Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Added pci code (this only does a bus scan at this point)
Peter Dinda [Mon, 23 Jun 2008 21:37:57 +0000 (21:37 +0000)]
palacios/include/geekos/pci.h [new file with mode: 0644]
palacios/src/geekos/pci.c [new file with mode: 0644]

diff --git a/palacios/include/geekos/pci.h b/palacios/include/geekos/pci.h
new file mode 100644 (file)
index 0000000..1dd5e5e
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef GEEKOS_PCI_H
+#define GEEKOS_PCI_H
+
+#include <geekos/ktypes.h>
+
+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 (file)
index 0000000..3657bcf
--- /dev/null
@@ -0,0 +1,266 @@
+#include <geekos/malloc.h>
+#include <geekos/pci.h>
+#include <geekos/io.h>
+#include <geekos/debug.h>
+
+#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;i<numdwords;i++) {
+    p[i]=ReadPCIDWord(bus,dev,0,i*4);
+  }
+}
+
+
+
+static struct pci *ScanPCI()
+{
+  uint_t bus, dev;
+  ushort_t vendor;
+
+  struct pci *thepci = NewPCI();
+  struct pci_bus *thebus;
+  for (bus=0;bus<PCI_MAX_NUM_BUSES;bus++) {
+    // Are there any devices on the bus?
+    for (dev=0;dev<32;dev++) { 
+      vendor=ReadPCIWord(bus,dev,0,0);
+      if (vendor!=0xffff) { 
+       break;
+      }
+    }
+    if (dev==32) { 
+      continue;
+    }
+    // There are devices.  Create a bus.
+    thebus = NewPCIBus(thepci);
+    thebus->number=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;
+
+}