📄 plugin_pci.c
字号:
/* tag: openbios pci plugin * * Copyright (C) 2003 Stefan Reinauer * * See the file "COPYING" for further information about * the copyright and warranty status of this work. */#include <stdio.h>#include <stdlib.h>#include "unix/plugins.h"#include "unix/plugin_pci.h"#define DEBUGu32 pci_conf_addr = 0;pci_dev_t *pci_devices = NULL;static pci_dev_t *find_device(u32 conf_addr){ pci_dev_t *devs = pci_devices; unsigned bus = (conf_addr >> 16) & 0xff; unsigned dev = (conf_addr >> 11) & 0x1f; unsigned fn = (conf_addr >> 8) & 0x7; // printf("Looking for device %x\n",conf_addr); while (devs) { if (devs->bus == bus && devs->dev == dev && devs->fn == fn) return devs; devs = devs->next; } return NULL;}/* * IO functions. These manage all the magic of providing a PCI * compatible interface to OpenBIOS' unix version of the kernel. */static u8 pci_inb(u32 reg){ u32 basereg = (reg & 0xfffc); u32 basepos = (reg & 0x03); pci_dev_t *dev; if (basereg == 0xcf8) { return (pci_conf_addr >> (basepos << 3)); } /* still here? so we're 0xCFC */ dev = find_device(pci_conf_addr); if (!dev || !dev->config) return 0xff; return dev->config[(pci_conf_addr + basepos) & 0xff];}static u16 pci_inw(u32 reg){ u32 basereg = (reg & 0xfffc); u32 basepos = (reg & 0x02); pci_dev_t *dev; if (basereg == 0xcf8) { return (pci_conf_addr >> (basepos << 3)); } /* still here? so we're 0xCFC */ dev = find_device(pci_conf_addr); if (!dev || !dev->config) return 0xffff; return *(u16 *) (dev->config + ((pci_conf_addr + basepos) & 0xff));}static u32 pci_inl(u32 reg){ u32 basereg = (reg & 0xfffc); pci_dev_t *dev; if (basereg == 0xcf8) { return pci_conf_addr; } /* still here? so we're 0xCFC */ dev = find_device(pci_conf_addr); if (!dev || !dev->config) return 0xffffffff; return *(u32 *) (dev->config + (pci_conf_addr & 0xff));}static void pci_outb(u32 reg, u8 val){ u32 basereg = (reg & 0xfffc); u32 basepos = (reg & 0x03); pci_dev_t *dev; if (basereg == 0xcf8) { pci_conf_addr &= (~(0xff << (basepos << 3))); pci_conf_addr |= (val << (basepos << 3)); return; } /* still here? so we're 0xCFC */ dev = find_device(pci_conf_addr); if (!dev || !dev->config) return; dev->config[pci_conf_addr & 0xff] = val;}static void pci_outw(u32 reg, u16 val){ u32 basereg = (reg & 0xfffc); u32 basepos = (reg & 0x02); pci_dev_t *dev; if (basereg == 0xcf8) { pci_conf_addr &= (~(0xffff << (basepos << 3))); pci_conf_addr |= (val << (basepos << 3)); return; } /* still here? so we're 0xCFC */ dev = find_device(pci_conf_addr); if (!dev || !dev->config) return; *(u16 *) (dev->config + (pci_conf_addr & 0xff)) = val;}static void pci_outl(u32 reg, u32 val){ u32 basereg = (reg & 0xfffc); pci_dev_t *dev; if (basereg == 0xcf8) { pci_conf_addr = val; return; } /* still here? so we're 0xCFC */ dev = find_device(pci_conf_addr); if (!dev || !dev->config) return; *(u32 *) (dev->config + (pci_conf_addr & 0xff)) = val;}static io_ops_t pci_io_ops = { inb:pci_inb, inw:pci_inw, inl:pci_inl, outb:pci_outb, outw:pci_outw, outl:pci_outl};/* * Functions visible to modules depending on this module. */int pci_register_device(unsigned bus, unsigned dev, unsigned fn, u8 * config){ pci_dev_t *newdev; u32 caddr = (1 << 31) | (bus << 16) | (dev << 11) | (fn << 8); if (find_device(caddr)) { printf("Error: pci device %02x:%02x.%01x already exists\n", bus, dev, fn); return -1; } newdev = malloc(sizeof(pci_dev_t)); if (!newdev) { printf("Out of memory\n"); return -1; } newdev->bus = bus; newdev->dev = dev; newdev->fn = fn; newdev->config = config; newdev->next = pci_devices; pci_devices = newdev; return 0;}/* * Initialization is really simple. We just grab the * PCI conf1 io range for our emulation functions. */extern int plugin_pci_init( void );int plugin_pci_init(void){#ifdef DEBUG printf("Plugin \"pci\" initializing... ");#endif register_iorange("pci", &pci_io_ops, 0xcf8, 0xcff);#ifdef DEBUG printf("done.\n");#endif return 0;}/* plugin meta information available for the plugin loader */PLUGIN_AUTHOR ("Stefan Reinauer <stepan@openbios.org>")PLUGIN_DESCRIPTION ("Generic PCI Device Emulation")PLUGIN_LICENSE ("GPL v2")/* This plugin has no dependencies. Otherwise the following * macro would be uncommented: * PLUGIN_DEPENDENCIES ("this", "that") */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -