Subversion Repositories HelenOS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. #include <unistd.h>
  2. #include <ddi.h>
  3. #include <libarch/ddi.h>
  4. #include <stdio.h>
  5.  
  6. #include "internal.h"
  7. #include "header.h"
  8.  
  9. /* physical addresses and offsets */
  10. #define U2P_BASE        0x1FE00000000
  11. #define PCI_CONF_OFFSET   0x001000000
  12. #define PCI_CONF_SIZE     0x001000000
  13. #define PCI_CONF_BASE  (U2P_BASE + PCI_CONF_OFFSET)
  14.  
  15. /* virtual address of PCI configuration space */
  16. static void *conf_addr = 0;  
  17.  
  18. /*
  19.  * virtual address of specified PCI configuration register:
  20.  * bus ... bus number (0 for top level PCI bus B, 1 for top level PCI bus A)
  21.  * dev ... device number (0 - 15)
  22.  * fn  ... function number (0 - 7)
  23.  * reg ... register number (register's position within PCI configuration header)
  24.  **/
  25. #define CONF_ADDR(bus, dev, fn, reg)   (conf_addr + ((bus << 16) | (dev << 11) | (fn << 8) | (reg << 2)))
  26.  
  27.  
  28. static void us2i_init(struct pci_access *a)
  29. {  
  30. }
  31.  
  32. static void us2i_cleanup(struct pci_access *a UNUSED)
  33. {
  34. }
  35.  
  36. static int us2i_detect(struct pci_access *a)
  37. {
  38.     unsigned int tmp;
  39.    
  40.     /*
  41.      * Gain control over PCI configuration ports.
  42.      */
  43.     if (pio_enable((void *)PCI_CONF_BASE, PCI_CONF_SIZE, &conf_addr)) {
  44.         return 0;
  45.     }
  46.    
  47.     printf("PCI: conf_addr = %lx", conf_addr);
  48.     printf("PCI: vendor id address = %lx", CONF_ADDR(0, 0, 0, PCI_VENDOR_ID));
  49.    
  50.     asm volatile ("sethi 0x42224, %g0");
  51.     int vendor_id = pio_read_16(CONF_ADDR(0, 0, 0, PCI_VENDOR_ID));
  52.     vendor_id = vendor_id | pio_read_8(CONF_ADDR(0, 0, 0, PCI_VENDOR_ID + 1)) << 8;
  53.     int device_id = pio_read_8(CONF_ADDR(0, 0, 0, PCI_DEVICE_ID));
  54.     device_id = device_id | pio_read_8(CONF_ADDR(0, 0, 0, PCI_DEVICE_ID + 1)) << 8;
  55.    
  56.     printf("PCI: vendor id = %x", vendor_id);
  57.     printf("PCI: device id = %x", device_id);
  58.  
  59.     return vendor_id == 0x108E && device_id == 0x8000; // should be Psycho from Sun Microsystems
  60. }
  61.  
  62. static int us2i_read(struct pci_dev *d, int pos, byte * buf, int len)
  63. {
  64.     if (pos >= 256)
  65.         return 0;      
  66.  
  67.     switch (len) {
  68.     case 1:
  69.         buf[0] = pio_read_8(CONF_ADDR(d->bus, d->dev, d->func, pos));
  70.         break;
  71.     case 2:
  72.         us2i_read(d, pos + 1, buf, 1);   // unlike PCI, sparc uses big endian
  73.         us2i_read(d, pos, buf + 1, 1);
  74.         break;
  75.     case 4:
  76.         us2i_read(d, pos + 3, buf, 1);  // endians in an ugly way ... FIX ME
  77.         us2i_read(d, pos + 2, buf + 1, 1);
  78.         us2i_read(d, pos + 1, buf + 2, 1);
  79.         us2i_read(d, pos, buf + 3, 1);     
  80.         break;
  81.     default:
  82.         return pci_generic_block_read(d, pos, buf, len);
  83.     }
  84.     return 1;
  85. }
  86.  
  87. static int us2i_write(struct pci_dev *d, int pos, byte * buf, int len)
  88. {
  89.     if (pos >= 256)
  90.         return 0;
  91.  
  92.     switch (len) {
  93.     case 1:
  94.         pio_write_8(CONF_ADDR(d->bus, d->dev, d->func, pos), buf[0]);
  95.         break;
  96.     case 2:
  97.         us2i_write(d, pos + 1, buf, 1);   // unlike PCI, sparc uses big endian
  98.         us2i_write(d, pos, buf + 1, 1);
  99.         break;
  100.     case 4:
  101.         us2i_write(d, pos + 3, buf, 1);  // endians in an ugly way ... FIX ME
  102.         us2i_write(d, pos + 2, buf + 1, 1);
  103.         us2i_write(d, pos + 1, buf + 2, 1);
  104.         us2i_write(d, pos, buf + 3, 1);
  105.         break;
  106.     default:
  107.         return pci_generic_block_write(d, pos, buf, len);
  108.     }
  109.     return 1;
  110. }
  111.  
  112.  
  113. struct pci_methods pm_us2i = {
  114.     "Ultra Sparc IIi",
  115.     NULL,           /* config */
  116.     us2i_detect,
  117.     us2i_init,
  118.     us2i_cleanup,
  119.     pci_generic_scan,
  120.     pci_generic_fill_info,
  121.     us2i_read,
  122.     us2i_write,
  123.     NULL,           /* init_dev */
  124.     NULL            /* cleanup_dev */
  125. };