Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. #define PCI_MAP_REG_START   0x10
  3. #define PCI_MAP_ROM_REG     0x30
  4.  
  5. #define PCI_MAP_MEMORY          0x00000000
  6. #define PCI_MAP_IO          0x00000001
  7.  
  8. #define PCI_MAP_MEMORY_TYPE     0x00000007
  9. #define PCI_MAP_IO_TYPE         0x00000003
  10.  
  11. #define PCI_MAP_MEMORY_TYPE_32BIT   0x00000000
  12. #define PCI_MAP_MEMORY_TYPE_32BIT_1M    0x00000002
  13. #define PCI_MAP_MEMORY_TYPE_64BIT   0x00000004
  14. #define PCI_MAP_MEMORY_TYPE_MASK    0x00000006
  15. #define PCI_MAP_MEMORY_CACHABLE     0x00000008
  16. #define PCI_MAP_MEMORY_ATTR_MASK    0x0000000e
  17. #define PCI_MAP_MEMORY_ADDRESS_MASK 0xfffffff0
  18.  
  19. #define PCI_MAP_IO_ATTR_MASK        0x00000003
  20.  
  21. u32_t pciGetBaseSize(int bus, int devfn, int index,
  22.                      bool destructive, bool *min)
  23. {
  24.   int offset;
  25.   u32_t addr1;
  26.   u32_t addr2;
  27.   u32_t mask1;
  28.   u32_t mask2;
  29.   int bits = 0;
  30.  
  31.   /*
  32.    * silently ignore bogus index values.  Valid values are 0-6.  0-5 are
  33.    * the 6 base address registers, and 6 is the ROM base address register.
  34.    */
  35.   if (index < 0 || index > 6)
  36.     return 0;
  37.  
  38.   if (min)
  39.     *min = destructive;
  40.  
  41.   /* Get the PCI offset */
  42.   if (index == 6)
  43.     offset = PCI_MAP_ROM_REG;
  44.   else
  45.     offset = PCI_MAP_REG_START + (index << 2);
  46.  
  47.   addr1 = PciRead32(bus, devfn, offset);
  48.   /*
  49.    * Check if this is the second part of a 64 bit address.
  50.    * XXX need to check how endianness affects 64 bit addresses.
  51.    */
  52.   if (index > 0 && index < 6) {
  53.     addr2 = PciRead32(bus, devfn, offset - 4);
  54.     if (PCI_MAP_IS_MEM(addr2) && PCI_MAP_IS64BITMEM(addr2))
  55.       return 0;
  56.   }
  57.  
  58.   if (destructive) {
  59.      PciWrite32(bus, devfn, offset, 0xffffffff);
  60.      mask1 = PciRead32(bus, devfn, offset);
  61.      PciWrite32(bus, devfn, offset, addr1);
  62.   } else {
  63.     mask1 = addr1;
  64.   }
  65.  
  66.   /* Check if this is the first part of a 64 bit address. */
  67.   if (index < 5 && PCI_MAP_IS_MEM(mask1) && PCI_MAP_IS64BITMEM(mask1))
  68.   {
  69.     if (PCIGETMEMORY(mask1) == 0)
  70.     {
  71.       addr2 = PciRead32(bus, devfn, offset + 4);
  72.       if (destructive)
  73.       {
  74.         PciWrite32(bus, devfn, offset + 4, 0xffffffff);
  75.         mask2 = PciRead32(bus, devfn, offset + 4);
  76.         PciWrite32(bus, devfn, offset + 4, addr2);
  77.       }
  78.       else
  79.      {
  80.        mask2 = addr2;
  81.      }
  82.      if (mask2 == 0)
  83.        return 0;
  84.      bits = 32;
  85.      while ((mask2 & 1) == 0)
  86.      {
  87.        bits++;
  88.        mask2 >>= 1;
  89.      }
  90.      if (bits > 32)
  91.           return bits;
  92.     }
  93.   }
  94.   if (index < 6)
  95.     if (PCI_MAP_IS_MEM(mask1))
  96.       mask1 = PCIGETMEMORY(mask1);
  97.     else
  98.       mask1 = PCIGETIO(mask1);
  99.   else
  100.     mask1 = PCIGETROM(mask1);
  101.   if (mask1 == 0)
  102.     return 0;
  103.   bits = 0;
  104.   while ((mask1 & 1) == 0) {
  105.     bits++;
  106.     mask1 >>= 1;
  107.   }
  108.   /* I/O maps can be no larger than 8 bits */
  109.  
  110.   if ((index < 6) && PCI_MAP_IS_IO(addr1) && bits > 8)
  111.     bits = 8;
  112.   /* ROM maps can be no larger than 24 bits */
  113.   if (index == 6 && bits > 24)
  114.     bits = 24;
  115.   return bits;
  116. }
  117.