From: Peter Dinda Date: Mon, 23 Jun 2008 21:37:57 +0000 (+0000) Subject: Added pci code (this only does a bus scan at this point) X-Git-Tag: boot386puppy-26-to-ide~15 X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=77cb02d9352065f780345e876eb104dd44237f66 Added pci code (this only does a bus scan at this point) --- diff --git a/palacios/include/geekos/pci.h b/palacios/include/geekos/pci.h new file mode 100644 index 0000000..1dd5e5e --- /dev/null +++ b/palacios/include/geekos/pci.h @@ -0,0 +1,8 @@ +#ifndef GEEKOS_PCI_H +#define GEEKOS_PCI_H + +#include + +int Init_PCI(); + +#endif /* GEEKOS_PCI_H */ diff --git a/palacios/src/geekos/pci.c b/palacios/src/geekos/pci.c new file mode 100644 index 0000000..3657bcf --- /dev/null +++ b/palacios/src/geekos/pci.c @@ -0,0 +1,266 @@ +#include +#include +#include +#include + +#define PCI_CONFIG_ADDRESS 0xcf8 // 32 bit, little endian +#define PCI_CONFIG_DATA 0xcfc // 32 bit, little endian + +#define PCI_MAX_NUM_BUSES 4 + + +struct pci_device_config { + ushort_t device_id; + ushort_t vendor_id; + ushort_t status; + ushort_t command; + uchar_t class_code; + uchar_t subclass; + ushort_t revision; + uchar_t BIST; + uchar_t header_type; + uchar_t latency_time; + uchar_t cache_line_size; + uint_t BAR[6]; + uint_t cardbus_cis_pointer; + ushort_t subsystem_id; + ushort_t subsystem_vendor_id; + uint_t expansion_rom_address; + uint_t reserved[2]; + uchar_t max_latency; + uchar_t min_grant; + uchar_t intr_pin; + uchar_t intr_line; +} __attribute__((__packed__)) ; + +struct pci_bus { + uint_t number; + struct pci_bus *next; + + struct pci_device *device_list; // + +}; + +struct pci_device { + uint_t number; + struct pci_bus *bus; + struct pci_device *next; + + struct pci_device_config config; +}; + +struct pci { + uint_t num_buses; + struct pci_bus *bus_list; +}; + + +static uint_t ReadPCIDWord(uint_t bus, uint_t dev, uint_t func, uint_t offset) +{ + uint_t address; + uint_t data; + + address = ((bus << 16) | (dev << 11) | + (func << 8) | (offset & 0xfc) | ((uint_t)0x80000000)); + + Out_DWord(PCI_CONFIG_ADDRESS,address); + data=In_DWord(PCI_CONFIG_DATA); + + return data; +} + +#if 0 + +static ushort_t ReadPCIWord(uint_t bus, uint_t dev, uint_t func, uint_t offset) +{ + uint_t address; + uint_t data; + + address = ((bus << 16) | (dev << 11) | + (func << 8) | (offset & 0xfc) | ((uint_t)0x80000000)); + + Out_DWord(PCI_CONFIG_ADDRESS,address); + data=In_DWord(PCI_CONFIG_DATA); + + //PrintBoth("PCI: [0x%x] = 0x%x\n",address,data); + + + return (ushort_t) ((data>>((offset&0x2)*8)) & 0xffff); +} + +#endif + +static ushort_t ReadPCIWord(uint_t bus, uint_t dev, uint_t func, uint_t offset) +{ + return (ushort_t) (ReadPCIDWord(bus,dev,func,offset)>>((offset&0x2)*8)); +} + +#if 0 // not currently used +static uchar_t ReadPCIByte(uint_t bus, uint_t dev, uint_t func, uint_t offset) +{ + return (uchar_t) (ReadPCIDWord(bus,dev,func,offset)>>((offset&0x3)*8)); +} +#endif + +static struct pci *NewPCI() +{ + struct pci *p = (struct pci *)Malloc(sizeof(struct pci)); + p->bus_list=NULL; + p->num_buses=0; + return p; +} + +static void AddPCIBus(struct pci *p, struct pci_bus *bus) +{ + bus->next = p->bus_list; + p->bus_list=bus; +} + + +static struct pci_bus *NewPCIBus(struct pci *p) +{ + struct pci_bus *pb = (struct pci_bus *)Malloc(sizeof(struct pci_bus)); + pb->device_list=NULL; + pb->number = (p->num_buses); + p->num_buses++; + return pb; +} + +static void AddPCIDevice(struct pci_bus *b, struct pci_device *d) +{ + d->bus=b; + d->next=b->device_list; + b->device_list=d; +} + +static struct pci_device *NewPCIDevice(struct pci_bus *pb) +{ + struct pci_device *pd = (struct pci_device *)Malloc(sizeof(struct pci_device)); + pd->number=0; + pd->bus=NULL; + pd->next=NULL; + return pd; +} + +static void GetPCIDeviceConfig(uint_t bus, + uint_t dev, + struct pci_device *d) +{ + uint_t numdwords=sizeof(struct pci_device_config) / 4; + uint_t i; + + uint_t *p = (uint_t *) (&(d->config)); + + for (i=0;inumber=bus; + // Add the devices to the bus + for (dev=0;dev<32;dev++) { + vendor=ReadPCIWord(bus,dev,0,0); + if (vendor!=0xffff) { + struct pci_device *thedev=NewPCIDevice(thebus); + thedev->number=dev; + GetPCIDeviceConfig(bus,dev,thedev); + AddPCIDevice(thebus,thedev); + } + } + AddPCIBus(thepci,thebus); + } + return thepci; +} + +static void PrintPCIDevice(struct pci_device *thedev) +{ + PrintBoth(" PCI Device: \n"); + PrintBoth(" Slot: %u\n",thedev->number); + PrintBoth(" device_id: 0x%x\n", (uint_t) thedev->config.device_id); + PrintBoth(" vendor_id: 0x%x\n", (uint_t) thedev->config.vendor_id); + PrintBoth(" status: 0x%x\n", (uint_t) thedev->config.status); + PrintBoth(" command: 0x%x\n", (uint_t) thedev->config.command); + PrintBoth(" class_code: 0x%x\n", (uint_t) thedev->config.class_code); + PrintBoth(" subclass: 0x%x\n", (uint_t) thedev->config.subclass); + PrintBoth(" revision: 0x%x\n", (uint_t) thedev->config.revision); + PrintBoth(" BIST: 0x%x\n", (uint_t) thedev->config.BIST); + PrintBoth(" header_type: 0x%x\n", (uint_t) thedev->config.header_type); + PrintBoth(" latency_time: 0x%x\n", (uint_t) thedev->config.latency_time); + PrintBoth(" cache_line_size: 0x%x\n", (uint_t) thedev->config.cache_line_size); + PrintBoth(" BAR[0]: 0x%x\n", (uint_t) thedev->config.BAR[0]); + PrintBoth(" BAR[1]: 0x%x\n", (uint_t) thedev->config.BAR[1]); + PrintBoth(" BAR[2]: 0x%x\n", (uint_t) thedev->config.BAR[2]); + PrintBoth(" BAR[3]: 0x%x\n", (uint_t) thedev->config.BAR[3]); + PrintBoth(" BAR[4]: 0x%x\n", (uint_t) thedev->config.BAR[4]); + PrintBoth(" BAR[5]: 0x%x\n", (uint_t) thedev->config.BAR[5]); + PrintBoth(" cardbus_cis_ptr: 0x%x\n", (uint_t) thedev->config.cardbus_cis_pointer); + PrintBoth(" subsystem_id: 0x%x\n", (uint_t) thedev->config.subsystem_id); + PrintBoth(" subsystem_vendor: 0x%x\n", (uint_t) thedev->config.subsystem_vendor_id); + PrintBoth(" exp_rom_address: 0x%x\n", (uint_t) thedev->config.expansion_rom_address); + PrintBoth(" reserved[0]: 0x%x\n", (uint_t) thedev->config.reserved[0]); + PrintBoth(" reserved[1]: 0x%x\n", (uint_t) thedev->config.reserved[1]); + PrintBoth(" max_latency: 0x%x\n", (uint_t) thedev->config.max_latency); + PrintBoth(" min_grant: 0x%x\n", (uint_t) thedev->config.min_grant); + PrintBoth(" intr_pin: 0x%x\n", (uint_t) thedev->config.intr_pin); + PrintBoth(" intr_line: 0x%x\n", (uint_t) thedev->config.intr_line); +} + +static void PrintPCIBus(struct pci_bus *thebus) +{ + struct pci_device *thedev; + + PrintBoth(" PCI Bus:\n"); + PrintBoth(" Number: %u\n",thebus->number); + + thedev=thebus->device_list; + + while (thedev) { + PrintPCIDevice(thedev); + thedev=thedev->next; + } +} + +static void PrintPCI(struct pci *thepci) +{ + struct pci_bus *thebus; + + PrintBoth("PCI Configuration:\n"); + PrintBoth(" Number of Buses: %u\n",thepci->num_buses); + thebus=thepci->bus_list; + while (thebus) { + PrintPCIBus(thebus); + thebus=thebus->next; + } + +} + +int Init_PCI() +{ + PrintPCI(ScanPCI()); + + return 0; + +}