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.


Fixes to PCI scanning and configuration storage
Peter Dinda [Wed, 9 Jul 2008 00:44:38 +0000 (00:44 +0000)]
Plus it now knows about bridges

palacios/src/geekos/kthread.c
palacios/src/geekos/pci.c

index 1a67775..0cba546 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Kernel threads
  * Copyright (c) 2001,2003 David H. Hovemeyer <daveho@cs.umd.edu>
- * $Revision: 1.3 $
+ * $Revision: 1.4 $
  * 
  * This is free software.  You are permitted to use,
  * redistribute, and modify it as specified in the file "COPYING".
@@ -561,7 +561,7 @@ void Schedule(void)
      * it was called from.
      */
 
-    SerialPrint("Switch_To_Thread() in Schedule()\n");
+    //SerialPrint("Switch_To_Thread() in Schedule()\n");
     Switch_To_Thread(runnable);
 }
 
index 3657bcf..c276552 100644 (file)
 
 
 struct pci_device_config {
-  ushort_t   device_id;
   ushort_t   vendor_id;
-  ushort_t   status;
+  ushort_t   device_id;
   ushort_t   command;
-  uchar_t    class_code;
-  uchar_t    subclass;
-  ushort_t   revision;
-  uchar_t    BIST;
-  uchar_t    header_type;
-  uchar_t    latency_time;
+  ushort_t   status;
+  uchar_t    revision;
+  uchar_t    class_code[3];  // in order: programming interface, subclass, class code
+
+#define PROG_INTERFACE(x) ((x)[0])
+#define SUBCLASS(x) ((x)[1])
+#define CLASSCODE(x) ((x)[2])
+  
+  
   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__)) ;
+  uchar_t    latency_time;
+  uchar_t    header_type; // bits 6-0: 00: other, 01: pci-pci bridge, 02: pci-cardbus; bit 7: 1=multifunction
+  
+#define HEADER_TYPE(x) ((x)&0x7f)
+  
+#define PCI_DEVICE 0x0
+#define PCI_PCI_BRIDGE 0x1
+#define PCI_CARDBUS_BRIDGE 0x2
+
+#define MULTIFUNCTION(x) ((x)&0x80)
+
+#define IS_DEVICE(x) (HEADER_TYPE(x)==0x0)
+#define IS_PCI_PCI_BRIDGE(x) (HEADER_TYPE(x)==0x1)
+#define IS_PCI_CARDBUS_BRIDGE(x) (HEADER_TYPE(x)==0x2)
+
+  uchar_t    BIST;
+  
+  union {  
+    
+    // header = 00 (Device)
+    struct {
+      uint_t     BAR[6];
+      
+#define IS_IO_ADDR(x)   ((x)&0x1)
+#define IS_MEM_ADDR(x)  (!((x)&0x1))
+#define GET_IO_ADDR(x)  (((uint_t)(x))&0xfffffffc) 
+#define GET_MEM_ADDR(x) (((uint_t)(x))&0xfffffff0)
+#define GET_MEM_TYPE(x) (((x)&0x6)>>2)
+#define GET_MEM_PREFETCHABLE(x) ((x)&0x8)
+
+      uint_t     cardbus_cis_pointer;
+      ushort_t   subsystem_vendor_id;
+      ushort_t   subsystem_id;
+      uint_t     expansion_rom_address;
+      uchar_t    cap_ptr;  // capabilities list offset in config space
+      uchar_t    reserved[7];
+      uchar_t    intr_line; // 00=none, 01=IRQ1, etc.
+      uchar_t    intr_pin;  // 00=none, otherwise INTA# to INTD#
+      uchar_t    min_grant; // min busmaster time - units of 250ns
+      uchar_t    max_latency; // units of 250ns - busmasters
+      uint_t     device_data[48];
+    }  __attribute__((__packed__))  pci_device_config;
+    
+    // header = 01 (pci-pci bridge)
+    struct {
+      uint_t     BAR[2];
+      uchar_t    primary_bus;  // the one closer to the processor
+      uchar_t    secondary_bus; // the one further away
+      uchar_t    subordinate_bus;
+      uchar_t    secondary_lat_timer;
+      uchar_t    io_base;
+      uchar_t    io_limit;
+      ushort_t   secondary_status;
+      ushort_t   memory_base;
+      ushort_t   memory_limit;
+      ushort_t   prefetchable_memory_base;
+      ushort_t   prefetchable_memory_limit;
+      uint_t     prefetchable_memory_base_upper;  // for 64 bit?
+      uint_t     prefetchable_memory_limit_upper;
+      ushort_t   io_base_upper;  // upper 16
+      ushort_t   io_limit_upper; 
+      uint_t     reserved;
+      uint_t     expansion_rom_address;
+      uchar_t    intr_line;
+      uchar_t    intr_pin;
+      ushort_t   bridge_ctl;
+      uint_t     device_data[48];
+    }  __attribute__((__packed__))  pci_pci_bridge_config;
+
+
+    // header = 02 (pci-cardbus bridge)
+    struct {
+      uint_t     cardbus_base_addr;
+      uchar_t    cap_ptr;
+      uchar_t    reserved;
+      ushort_t   secondary_status;
+      uchar_t    pci_bus;
+      uchar_t    cardbus_bus;
+      uchar_t    subordinate_bus;
+      uchar_t    cardbus_lat_timer;
+      uint_t     memory_base0;
+      uint_t     memory_limit0;
+      uint_t     memory_base1;
+      uint_t     memory_limit1;
+      ushort_t   io_base0;
+      ushort_t   io_base0_upper;
+      ushort_t   io_limit0;
+      ushort_t   io_limit0_upper;
+      ushort_t   io_base1;
+      ushort_t   io_base1_upper;
+      ushort_t   io_limit1;
+      ushort_t   io_limit1_upper;
+      uchar_t    intr_line;
+      uchar_t    intr_pin;
+      ushort_t   bridge_ctl;
+      ushort_t   subsystem_vendor_id;
+      ushort_t   subsystem_device_id;
+      uint_t     legacy_16bit_base_addr;
+      uint_t     reserved2[14];
+      uint_t     device_data[32];
+    }  __attribute__((__packed__)) pci_cardbus_bridge_config;
+
+  }  __attribute__((__packed__)) u;
+  
+};
 
 struct pci_bus {
   uint_t number;
@@ -195,39 +291,179 @@ static struct pci *ScanPCI()
   return thepci;
 }
 
-static void PrintPCIDevice(struct pci_device *thedev)
+static void PrintPCIShared(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("      device_id:        0x%x\n", (uint_t) thedev->config.device_id);
   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("      status:           0x%x\n", (uint_t) thedev->config.status);
   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("      class_code:       0x%x%x%x (prog_interface 0x%x, subclass 0x%x, classcode 0x%x)\n", 
+           (uint_t) thedev->config.class_code[0],
+           (uint_t) thedev->config.class_code[1],
+           (uint_t) thedev->config.class_code[2],
+           (uint_t) PROG_INTERFACE(thedev->config.class_code),
+           (uint_t) SUBCLASS(thedev->config.class_code),
+           (uint_t) CLASSCODE(thedev->config.class_code)
+           );
   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);
+  PrintBoth("      latency_time:     0x%x\n", (uint_t) thedev->config.latency_time);
+  PrintBoth("      header_type:      0x%x (%s%s)\n", (uint_t) thedev->config.header_type,
+           HEADER_TYPE(thedev->config.header_type)==PCI_DEVICE ? "PCI Device" :
+           HEADER_TYPE(thedev->config.header_type)==PCI_PCI_BRIDGE ? "PCI-PCI Bridge" :
+           HEADER_TYPE(thedev->config.header_type)==PCI_CARDBUS_BRIDGE ? "PCI-Cardbus Bridge" : "UNKNOWN",
+           MULTIFUNCTION(thedev->config.header_type) ? " Multifunction" : ""
+           );
+  PrintBoth("      BIST:             0x%x\n", (uint_t) thedev->config.BIST);
 }
 
+static void PrintPCIDevice(struct pci_device *thedev)
+{
+  int i;
+  
+  PrintBoth("     PCI Device:\n");
+  PrintPCIShared(thedev);
+  for (i=0;i<6;i++) { 
+    PrintBoth("      BAR[%d]:           0x%x (", i, (uint_t) thedev->config.u.pci_device_config.BAR[i]);
+    if (IS_IO_ADDR(thedev->config.u.pci_device_config.BAR[i])) { 
+      PrintBoth("IO Address 0x%x)\n", GET_IO_ADDR(thedev->config.u.pci_device_config.BAR[i]));
+    } else if (IS_MEM_ADDR(thedev->config.u.pci_device_config.BAR[i])) { 
+      PrintBoth("Memory Address 0x%x type=0x%x%s\n", 
+               GET_MEM_ADDR(thedev->config.u.pci_device_config.BAR[i]),
+               GET_MEM_TYPE(thedev->config.u.pci_device_config.BAR[i]),
+               GET_MEM_PREFETCHABLE(thedev->config.u.pci_device_config.BAR[i]) ? " prefetchable)" : ")");
+    } else {
+      PrintBoth("UNKNOWN)\n");
+    }
+  }
+  PrintBoth("      cardbus_cis_ptr:  0x%x\n", (uint_t) thedev->config.u.pci_device_config.cardbus_cis_pointer);
+  PrintBoth("      subsystem_vendor: 0x%x\n", (uint_t) thedev->config.u.pci_device_config.subsystem_vendor_id);
+  PrintBoth("      subsystem_id:     0x%x\n", (uint_t) thedev->config.u.pci_device_config.subsystem_id);
+  PrintBoth("      exp_rom_address:  0x%x\n", (uint_t) thedev->config.u.pci_device_config.expansion_rom_address);
+  PrintBoth("      cap ptr           0x%x\n", (uint_t) thedev->config.u.pci_device_config.cap_ptr);
+  for (i=0;i<7;i++) { 
+    PrintBoth("      reserved[%d]:      0x%x\n", i, (uint_t) thedev->config.u.pci_device_config.reserved[i]);
+  }
+  PrintBoth("      intr_line:        0x%x\n", (uint_t) thedev->config.u.pci_device_config.intr_line);
+  PrintBoth("      intr_pin:         0x%x\n", (uint_t) thedev->config.u.pci_device_config.intr_pin);
+  PrintBoth("      min_grant:        0x%x\n", (uint_t) thedev->config.u.pci_device_config.min_grant);
+  PrintBoth("      max_latency:      0x%x\n", (uint_t) thedev->config.u.pci_device_config.max_latency);
+  for (i=0;i<48;i++) { 
+    PrintBoth("      device_data[%d]:   0x%x\n", i, (uint_t) thedev->config.u.pci_device_config.device_data[i]);
+  }
+}
+
+static void PrintPCIPCIBridge(struct pci_device *thedev)
+{
+  int i;
+  
+  PrintBoth("     PCI-PCI Bridge:\n");
+  PrintPCIShared(thedev);
+  for (i=0;i<2;i++) { 
+    PrintBoth("      BAR[%d]:           0x%x (", i, (uint_t) thedev->config.u.pci_pci_bridge_config.BAR[i]);
+    if (IS_IO_ADDR(thedev->config.u.pci_pci_bridge_config.BAR[i])) { 
+      PrintBoth("IO Address 0x%x)\n", GET_IO_ADDR(thedev->config.u.pci_pci_bridge_config.BAR[i]));
+    } else if (IS_MEM_ADDR(thedev->config.u.pci_pci_bridge_config.BAR[i])) { 
+      PrintBoth("Memory Address 0x%x type=0x%x%s\n",
+               GET_MEM_ADDR(thedev->config.u.pci_pci_bridge_config.BAR[i]),
+       GET_MEM_TYPE(thedev->config.u.pci_pci_bridge_config.BAR[i]),
+               GET_MEM_PREFETCHABLE(thedev->config.u.pci_pci_bridge_config.BAR[i]) ? " prefetchable)" : ")");
+    } else {
+      PrintBoth("UNKNOWN)\n");
+    }
+  }
+  PrintBoth("      primary_bus:      0x%x\n", (uint_t) thedev->config.u.pci_pci_bridge_config.primary_bus);
+  PrintBoth("      secondary_bus:    0x%x\n", (uint_t) thedev->config.u.pci_pci_bridge_config.secondary_bus);
+  PrintBoth("      subordinate_bus:  0x%x\n", (uint_t) thedev->config.u.pci_pci_bridge_config.subordinate_bus);
+  PrintBoth("      second_lat_timer: 0x%x\n", (uint_t) thedev->config.u.pci_pci_bridge_config.secondary_lat_timer);
+  PrintBoth("      io_base:          0x%x\n", (uint_t) thedev->config.u.pci_pci_bridge_config.io_base);
+  PrintBoth("      io_limit:         0x%x\n", (uint_t) thedev->config.u.pci_pci_bridge_config.io_limit);
+  PrintBoth("      secondary_status: 0x%x\n", (uint_t) thedev->config.u.pci_pci_bridge_config.secondary_status);
+  PrintBoth("      memory_base:      0x%x\n", (uint_t) thedev->config.u.pci_pci_bridge_config.memory_base);
+  PrintBoth("      memory_limit:     0x%x\n", (uint_t) thedev->config.u.pci_pci_bridge_config.memory_limit);
+  PrintBoth("      prefetch_base:    0x%x\n", (uint_t) thedev->config.u.pci_pci_bridge_config.prefetchable_memory_base);
+  PrintBoth("      prefetch_limit:   0x%x\n", (uint_t) thedev->config.u.pci_pci_bridge_config.prefetchable_memory_limit);
+  PrintBoth("      prefetch_base_up: 0x%x\n", (uint_t) thedev->config.u.pci_pci_bridge_config.prefetchable_memory_base_upper);
+  PrintBoth("      prefetch_limit_u: 0x%x\n", (uint_t) thedev->config.u.pci_pci_bridge_config.prefetchable_memory_limit_upper);
+  PrintBoth("      memory_limit:     0x%x\n", (uint_t) thedev->config.u.pci_pci_bridge_config.memory_limit);
+  PrintBoth("      memory_limit:     0x%x\n", (uint_t) thedev->config.u.pci_pci_bridge_config.memory_limit);
+  PrintBoth("      io_base_up:       0x%x\n", (uint_t) thedev->config.u.pci_pci_bridge_config.io_base_upper);
+  PrintBoth("      io_limit_up:      0x%x\n", (uint_t) thedev->config.u.pci_pci_bridge_config.io_limit_upper);
+  PrintBoth("      reserved:         0x%x\n", (uint_t) thedev->config.u.pci_pci_bridge_config.reserved);
+  PrintBoth("      exp_rom_address:  0x%x\n", (uint_t) thedev->config.u.pci_pci_bridge_config.expansion_rom_address);
+  PrintBoth("      intr_line:        0x%x\n", (uint_t) thedev->config.u.pci_pci_bridge_config.intr_line);
+  PrintBoth("      intr_pin:         0x%x\n", (uint_t) thedev->config.u.pci_pci_bridge_config.intr_pin);
+  for (i=0;i<48;i++) { 
+    PrintBoth("      device_data[%d]:   0x%x\n", i, (uint_t) thedev->config.u.pci_pci_bridge_config.device_data[i]);
+  }
+}
+
+static void PrintPCICardbusBridge(struct pci_device *thedev)
+{
+  int i;
+  
+  PrintBoth("     PCI-Cardbus Bridge:\n");
+  PrintPCIShared(thedev);
+  PrintBoth("      cardbus_base_add: 0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.cardbus_base_addr);
+  PrintBoth("      cap_ptr:          0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.cap_ptr);
+  PrintBoth("      reserved:         0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.reserved);
+  PrintBoth("      secondary_status  0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.secondary_status);
+  PrintBoth("      pci_bus:          0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.pci_bus);
+  PrintBoth("      cardbus_bus:      0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.cardbus_bus);
+  PrintBoth("      subordinate_bus:  0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.subordinate_bus);
+  PrintBoth("      cardbus_lat_time: 0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.cardbus_lat_timer);
+  PrintBoth("      memory_base0      0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.memory_base0);
+  PrintBoth("      memory_limit0     0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.memory_limit0);
+  PrintBoth("      memory_base1      0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.memory_base1);
+  PrintBoth("      memory_limit1     0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.memory_limit1);
+  PrintBoth("      io_base0          0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.io_base0);
+  PrintBoth("      io_base0_up       0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.io_base0_upper);
+  PrintBoth("      io_limit0         0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.io_limit0);
+  PrintBoth("      io_limit0_up      0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.io_limit0_upper);
+  PrintBoth("      io_base1          0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.io_base1);
+  PrintBoth("      io_base1_up       0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.io_base1_upper);
+  PrintBoth("      io_limit1         0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.io_limit1);
+  PrintBoth("      io_limit1_up      0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.io_limit1_upper);
+  PrintBoth("      intr_line:        0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.intr_line);
+  PrintBoth("      intr_pin:         0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.intr_pin);
+  PrintBoth("      bridge_ctl:       0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.bridge_ctl);
+  PrintBoth("      subsys_vend_id:   0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.subsystem_vendor_id);
+  PrintBoth("      subsys_dev_id:    0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.subsystem_device_id);
+  PrintBoth("      legacy16_base:    0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.legacy_16bit_base_addr);
+  for (i=0;i<14;i++) {
+    PrintBoth("      reserved2[%d]:    0x%x\n", (uint_t) thedev->config.u.pci_cardbus_bridge_config.reserved2[i]);
+  }
+  for (i=0;i<48;i++) { 
+    PrintBoth("      device_data[%d]:   0x%x\n", i, (uint_t) thedev->config.u.pci_cardbus_bridge_config.device_data[i]);
+  }
+}
+
+static void PrintPCIUnknown(struct pci_device *thedev)
+{
+  PrintBoth("    PCI Unknown Element\n");
+  PrintPCIShared(thedev);
+}
+
+static void PrintPCIElement(struct pci_device *thedev) 
+{ 
+  switch (HEADER_TYPE(thedev->config.header_type)) { 
+  case PCI_DEVICE:
+    PrintPCIDevice(thedev);
+    break;
+  case PCI_PCI_BRIDGE:
+    PrintPCIPCIBridge(thedev);
+    break;
+  case PCI_CARDBUS_BRIDGE:
+    PrintPCICardbusBridge(thedev);
+    break;
+  default:
+    PrintPCIUnknown(thedev);
+    break;
+  }
+}
+    
+
 static void PrintPCIBus(struct pci_bus *thebus)
 {
   struct pci_device *thedev;
@@ -238,7 +474,7 @@ static void PrintPCIBus(struct pci_bus *thebus)
   thedev=thebus->device_list;
 
   while (thedev) { 
-    PrintPCIDevice(thedev);
+    PrintPCIElement(thedev);
     thedev=thedev->next;
   }
 }