Subversion Repositories Kolibri OS

Rev

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

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