Subversion Repositories HelenOS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. #include <ddi.h>
  2. #include <libarch/ddi.h>
  3. #include <futex.h>
  4.  
  5. #include "pci.h"
  6. #include "pci_bus.h"
  7. #include "pci_conf.h"
  8.  
  9. #define CONF_ADDR_PORT 0xCF8
  10. #define CONF_DATA_PORT 0xCFC
  11. #define CONF_PORT_SIZE 4
  12.  
  13. static void *conf_addr_port = NULL;
  14. static void *conf_data_port = NULL;
  15.  
  16. static atomic_t pci_conf_futex = FUTEX_INITIALIZER;
  17.  
  18. static void method1_conf_read(pci_dev_t *d, int reg, uint8_t *buf, int len);
  19.  
  20. #define CONF_ADDR(bus, dev, fn, reg)   ((1 << 31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
  21.  
  22. uint8_t pci_conf_read_8(pci_dev_t *dev, int reg)
  23. {
  24.     uint8_t res;
  25.     method1_conf_read(dev, reg, &res, 1);
  26.     return res;
  27. }
  28.  
  29. uint16_t pci_conf_read_16(pci_dev_t *dev, int reg)
  30. {
  31.     uint16_t res;
  32.     method1_conf_read(dev, reg, (uint8_t *)&res, 2);
  33.     return res;
  34. }
  35.  
  36. uint32_t pci_conf_read_32(pci_dev_t *dev, int reg)
  37. {
  38.     uint32_t res;
  39.     method1_conf_read(dev, reg, (uint8_t *)&res, 4);
  40.     return res;
  41. }
  42.  
  43. static void method1_conf_read(pci_dev_t *dev, int reg, uint8_t *buf, int len)
  44. {
  45.     futex_down(&pci_conf_futex);
  46.     uint32_t conf_addr =  CONF_ADDR(dev->bus->num, dev->dev, dev->fn, reg);
  47.     void *addr = conf_data_port + (reg & 3);
  48.    
  49.     pio_write_32(conf_addr_port, conf_addr);
  50.    
  51.     switch (len) {
  52.         case 1:
  53.             buf[0] = pio_read_8(addr);
  54.             break;
  55.         case 2:
  56.             ((uint16_t *)buf)[0] = pio_read_16(addr);
  57.             break;
  58.         case 4:
  59.             ((uint32_t *)buf)[0] = pio_read_32(addr);
  60.             break;
  61.     }
  62.    
  63.     futex_up(&pci_conf_futex);
  64. }
  65.  
  66. int pci_bus_init()
  67. {  
  68.     int error;
  69.     if (error = pio_enable((void *)CONF_ADDR_PORT, CONF_PORT_SIZE, &conf_addr_port)) {
  70.         printf("PCI: failed to enable configuration address port (error %d)\n", error);
  71.         return 0;
  72.     }
  73.    
  74.     if (error = pio_enable((void *)CONF_DATA_PORT, CONF_PORT_SIZE, &conf_data_port)) {
  75.         printf("PCI: failed to enable configuration data port (error %d)\n", error);
  76.         return 0;
  77.     }
  78.    
  79.     pci_bus_t *bus = pci_alloc_bus();
  80.     bus->data = NULL;
  81.     bus->num = 0;
  82.     pci_bus_register(bus);
  83.     pci_bus_scan(bus);
  84.     return 1;
  85. }
  86.  
  87. void pci_bus_clean()
  88. {
  89. }
  90.  
  91. /* pci bus structure initialization */
  92. void pci_init_bus_data(pci_bus_t *bus, pci_bus_t *parent)
  93. {
  94.     bus->data = NULL;
  95. }
  96.