Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. SymTabRec RHDChipsets[] = {
  3.     /* R500 */
  4.     { RHD_RV505, "RV505" },
  5.     { RHD_RV515, "RV515" },
  6.     { RHD_RV516, "RV516" },
  7.     { RHD_R520,  "R520" },
  8.     { RHD_RV530, "RV530" },
  9.     { RHD_RV535, "RV535" },
  10.     { RHD_RV550, "RV550" },
  11.     { RHD_RV560, "RV560" },
  12.     { RHD_RV570, "RV570" },
  13.     { RHD_R580,  "R580" },
  14.     /* R500 Mobility */
  15.     { RHD_M52,   "M52" },
  16.     { RHD_M54,   "M54" },
  17.     { RHD_M56,   "M56" },
  18.     { RHD_M58,   "M58" },
  19.     { RHD_M62,   "M62" },
  20.     { RHD_M64,   "M64" },
  21.     { RHD_M66,   "M66" },
  22.     { RHD_M68,   "M68" },
  23.     { RHD_M71,   "M71" },
  24.     /* R500 integrated */
  25.     { RHD_RS600, "RS600" },
  26.     { RHD_RS690, "RS690" },
  27.     { RHD_RS740, "RS740" },
  28.     /* R600 */
  29.     { RHD_R600,  "R600" },
  30.     { RHD_RV610, "RV610" },
  31.     { RHD_RV630, "RV630" },
  32.     /* R600 Mobility */
  33.     { RHD_M72,   "M72" },
  34.     { RHD_M74,   "M74" },
  35.     { RHD_M76,   "M76" },
  36.     /* RV670 came into existence after RV6x0 and M7x */
  37.     { RHD_RV670, "RV670" },
  38.     { RHD_R680,  "R680"  },
  39.     { RHD_RV620, "RV620" },
  40.     { RHD_RV635, "RV635" },
  41.     { -1,      NULL }
  42. };
  43.  
  44. # define RHD_DEVICE_MATCH(d, i) { (d),(i) }
  45. # define PCI_ID_LIST PciChipset_t RHDPCIchipsets[]
  46. # define LIST_END { 0,  0}
  47.  
  48. const PCI_ID_LIST = {
  49.     RHD_DEVICE_MATCH(  0x7100, RHD_R520  ), /* Radeon X1800 */
  50.     RHD_DEVICE_MATCH(  0x7101, RHD_M58   ), /* Mobility Radeon X1800 XT */
  51.     RHD_DEVICE_MATCH(  0x7102, RHD_M58   ), /* Mobility Radeon X1800 */
  52.     RHD_DEVICE_MATCH(  0x7103, RHD_M58   ), /* Mobility FireGL V7200 */
  53.     RHD_DEVICE_MATCH(  0x7104, RHD_R520  ), /* FireGL V7200 */
  54.     RHD_DEVICE_MATCH(  0x7105, RHD_R520  ), /* FireGL V5300 */
  55.     RHD_DEVICE_MATCH(  0x7106, RHD_M58   ), /* Mobility FireGL V7100 */
  56.     RHD_DEVICE_MATCH(  0x7108, RHD_R520  ), /* Radeon X1800 */
  57.     RHD_DEVICE_MATCH(  0x7109, RHD_R520  ), /* Radeon X1800 */
  58.     RHD_DEVICE_MATCH(  0x710A, RHD_R520  ), /* Radeon X1800 */
  59.     RHD_DEVICE_MATCH(  0x710B, RHD_R520  ), /* Radeon X1800 */
  60.     RHD_DEVICE_MATCH(  0x710C, RHD_R520  ), /* Radeon X1800 */
  61.     RHD_DEVICE_MATCH(  0x710E, RHD_R520  ), /* FireGL V7300 */
  62.     RHD_DEVICE_MATCH(  0x710F, RHD_R520  ), /* FireGL V7350 */
  63.     RHD_DEVICE_MATCH(  0x7140, RHD_RV515 ), /* Radeon X1600/X1550 */
  64.     RHD_DEVICE_MATCH(  0x7141, RHD_RV505 ), /* RV505 */
  65.     RHD_DEVICE_MATCH(  0x7142, RHD_RV515 ), /* Radeon X1300/X1550 */
  66.     RHD_DEVICE_MATCH(  0x7143, RHD_RV505 ), /* Radeon X1550 */
  67.     RHD_DEVICE_MATCH(  0x7144, RHD_M54   ), /* M54-GL */
  68.     RHD_DEVICE_MATCH(  0x7145, RHD_M54   ), /* Mobility Radeon X1400 */
  69.     RHD_DEVICE_MATCH(  0x7146, RHD_RV515 ), /* Radeon X1300/X1550 */
  70.     RHD_DEVICE_MATCH(  0x7147, RHD_RV505 ), /* Radeon X1550 64-bit */
  71.     RHD_DEVICE_MATCH(  0x7149, RHD_M52   ), /* Mobility Radeon X1300 */
  72.     RHD_DEVICE_MATCH(  0x714A, RHD_M52   ), /* Mobility Radeon X1300 */
  73.     RHD_DEVICE_MATCH(  0x714B, RHD_M52   ), /* Mobility Radeon X1300 */
  74.     RHD_DEVICE_MATCH(  0x714C, RHD_M52   ), /* Mobility Radeon X1300 */
  75.     RHD_DEVICE_MATCH(  0x714D, RHD_RV515 ), /* Radeon X1300 */
  76.     RHD_DEVICE_MATCH(  0x714E, RHD_RV515 ), /* Radeon X1300 */
  77.     RHD_DEVICE_MATCH(  0x714F, RHD_RV505 ), /* RV505 */
  78.     RHD_DEVICE_MATCH(  0x7151, RHD_RV505 ), /* RV505 */
  79.     RHD_DEVICE_MATCH(  0x7152, RHD_RV515 ), /* FireGL V3300 */
  80.     RHD_DEVICE_MATCH(  0x7153, RHD_RV515 ), /* FireGL V3350 */
  81.     RHD_DEVICE_MATCH(  0x715E, RHD_RV515 ), /* Radeon X1300 */
  82.     RHD_DEVICE_MATCH(  0x715F, RHD_RV505 ), /* Radeon X1550 64-bit */
  83.     RHD_DEVICE_MATCH(  0x7180, RHD_RV516 ), /* Radeon X1300/X1550 */
  84.     RHD_DEVICE_MATCH(  0x7181, RHD_RV516 ), /* Radeon X1600 */
  85.     RHD_DEVICE_MATCH(  0x7183, RHD_RV516 ), /* Radeon X1300/X1550 */
  86.     RHD_DEVICE_MATCH(  0x7186, RHD_M64   ), /* Mobility Radeon X1450 */
  87.     RHD_DEVICE_MATCH(  0x7187, RHD_RV516 ), /* Radeon X1300/X1550 */
  88.     RHD_DEVICE_MATCH(  0x7188, RHD_M64   ), /* Mobility Radeon X2300 */
  89.     RHD_DEVICE_MATCH(  0x718A, RHD_M64   ), /* Mobility Radeon X2300 */
  90.     RHD_DEVICE_MATCH(  0x718B, RHD_M62   ), /* Mobility Radeon X1350 */
  91.     RHD_DEVICE_MATCH(  0x718C, RHD_M62   ), /* Mobility Radeon X1350 */
  92.     RHD_DEVICE_MATCH(  0x718D, RHD_M64   ), /* Mobility Radeon X1450 */
  93.     RHD_DEVICE_MATCH(  0x718F, RHD_RV516 ), /* Radeon X1300 */
  94.     RHD_DEVICE_MATCH(  0x7193, RHD_RV516 ), /* Radeon X1550 */
  95.     RHD_DEVICE_MATCH(  0x7196, RHD_M62   ), /* Mobility Radeon X1350 */
  96.     RHD_DEVICE_MATCH(  0x719B, RHD_RV516 ), /* FireMV 2250 */
  97.     RHD_DEVICE_MATCH(  0x719F, RHD_RV516 ), /* Radeon X1550 64-bit */
  98.     RHD_DEVICE_MATCH(  0x71C0, RHD_RV530 ), /* Radeon X1600 */
  99.     RHD_DEVICE_MATCH(  0x71C1, RHD_RV535 ), /* Radeon X1650 */
  100.     RHD_DEVICE_MATCH(  0x71C2, RHD_RV530 ), /* Radeon X1600 */
  101.     RHD_DEVICE_MATCH(  0x71C3, RHD_RV535 ), /* Radeon X1600 */
  102.     RHD_DEVICE_MATCH(  0x71C4, RHD_M56   ), /* Mobility FireGL V5200 */
  103.     RHD_DEVICE_MATCH(  0x71C5, RHD_M56   ), /* Mobility Radeon X1600 */
  104.     RHD_DEVICE_MATCH(  0x71C6, RHD_RV530 ), /* Radeon X1650 */
  105.     RHD_DEVICE_MATCH(  0x71C7, RHD_RV535 ), /* Radeon X1650 */
  106.     RHD_DEVICE_MATCH(  0x71CD, RHD_RV530 ), /* Radeon X1600 */
  107.     RHD_DEVICE_MATCH(  0x71CE, RHD_RV530 ), /* Radeon X1300 XT/X1600 Pro */
  108.     RHD_DEVICE_MATCH(  0x71D2, RHD_RV530 ), /* FireGL V3400 */
  109.     RHD_DEVICE_MATCH(  0x71D4, RHD_M66   ), /* Mobility FireGL V5250 */
  110.     RHD_DEVICE_MATCH(  0x71D5, RHD_M66   ), /* Mobility Radeon X1700 */
  111.     RHD_DEVICE_MATCH(  0x71D6, RHD_M66   ), /* Mobility Radeon X1700 XT */
  112.     RHD_DEVICE_MATCH(  0x71DA, RHD_RV530 ), /* FireGL V5200 */
  113.     RHD_DEVICE_MATCH(  0x71DE, RHD_M66   ), /* Mobility Radeon X1700 */
  114.     RHD_DEVICE_MATCH(  0x7200, RHD_RV550 ), /*  Radeon X2300HD  */
  115.     RHD_DEVICE_MATCH(  0x7210, RHD_M71   ), /* Mobility Radeon HD 2300 */
  116.     RHD_DEVICE_MATCH(  0x7211, RHD_M71   ), /* Mobility Radeon HD 2300 */
  117.     RHD_DEVICE_MATCH(  0x7240, RHD_R580  ), /* Radeon X1950 */
  118.     RHD_DEVICE_MATCH(  0x7243, RHD_R580  ), /* Radeon X1900 */
  119.     RHD_DEVICE_MATCH(  0x7244, RHD_R580  ), /* Radeon X1950 */
  120.     RHD_DEVICE_MATCH(  0x7245, RHD_R580  ), /* Radeon X1900 */
  121.     RHD_DEVICE_MATCH(  0x7246, RHD_R580  ), /* Radeon X1900 */
  122.     RHD_DEVICE_MATCH(  0x7247, RHD_R580  ), /* Radeon X1900 */
  123.     RHD_DEVICE_MATCH(  0x7248, RHD_R580  ), /* Radeon X1900 */
  124.     RHD_DEVICE_MATCH(  0x7249, RHD_R580  ), /* Radeon X1900 */
  125.     RHD_DEVICE_MATCH(  0x724A, RHD_R580  ), /* Radeon X1900 */
  126.     RHD_DEVICE_MATCH(  0x724B, RHD_R580  ), /* Radeon X1900 */
  127.     RHD_DEVICE_MATCH(  0x724C, RHD_R580  ), /* Radeon X1900 */
  128.     RHD_DEVICE_MATCH(  0x724D, RHD_R580  ), /* Radeon X1900 */
  129.     RHD_DEVICE_MATCH(  0x724E, RHD_R580  ), /* AMD Stream Processor */
  130.     RHD_DEVICE_MATCH(  0x724F, RHD_R580  ), /* Radeon X1900 */
  131.     RHD_DEVICE_MATCH(  0x7280, RHD_RV570 ), /* Radeon X1950 */
  132.     RHD_DEVICE_MATCH(  0x7281, RHD_RV560 ), /* RV560 */
  133.     RHD_DEVICE_MATCH(  0x7283, RHD_RV560 ), /* RV560 */
  134.     RHD_DEVICE_MATCH(  0x7284, RHD_M68   ), /* Mobility Radeon X1900 */
  135.     RHD_DEVICE_MATCH(  0x7287, RHD_RV560 ), /* RV560 */
  136.     RHD_DEVICE_MATCH(  0x7288, RHD_RV570 ), /* Radeon X1950 GT */
  137.     RHD_DEVICE_MATCH(  0x7289, RHD_RV570 ), /* RV570 */
  138.     RHD_DEVICE_MATCH(  0x728B, RHD_RV570 ), /* RV570 */
  139.     RHD_DEVICE_MATCH(  0x728C, RHD_RV570 ), /* ATI FireGL V7400  */
  140.     RHD_DEVICE_MATCH(  0x7290, RHD_RV560 ), /* RV560 */
  141.     RHD_DEVICE_MATCH(  0x7291, RHD_RV560 ), /* Radeon X1650 */
  142.     RHD_DEVICE_MATCH(  0x7293, RHD_RV560 ), /* Radeon X1650 */
  143.     RHD_DEVICE_MATCH(  0x7297, RHD_RV560 ), /* RV560 */
  144.     RHD_DEVICE_MATCH(  0x791E, RHD_RS690 ), /* Radeon X1200 */
  145.     RHD_DEVICE_MATCH(  0x791F, RHD_RS690 ), /* Radeon X1200 */
  146.     RHD_DEVICE_MATCH(  0x793F, RHD_RS600 ), /* Radeon Xpress 1200 */
  147.     RHD_DEVICE_MATCH(  0x7941, RHD_RS600 ), /* Radeon Xpress 1200 */
  148.     RHD_DEVICE_MATCH(  0x7942, RHD_RS600 ), /* Radeon Xpress 1200 (M) */
  149.     RHD_DEVICE_MATCH(  0x796C, RHD_RS740 ), /* RS740 */
  150.     RHD_DEVICE_MATCH(  0x796D, RHD_RS740 ), /* RS740M */
  151.     RHD_DEVICE_MATCH(  0x796E, RHD_RS740 ), /* ATI Radeon 2100 RS740 */
  152.     RHD_DEVICE_MATCH(  0x796F, RHD_RS740 ), /* RS740M */
  153.     RHD_DEVICE_MATCH(  0x9400, RHD_R600  ), /* Radeon HD 2900 XT */
  154.     RHD_DEVICE_MATCH(  0x9401, RHD_R600  ), /* Radeon HD 2900 XT */
  155.     RHD_DEVICE_MATCH(  0x9402, RHD_R600  ), /* Radeon HD 2900 XT */
  156.     RHD_DEVICE_MATCH(  0x9403, RHD_R600  ), /* Radeon HD 2900 Pro */
  157.     RHD_DEVICE_MATCH(  0x9405, RHD_R600  ), /* Radeon HD 2900 GT */
  158.     RHD_DEVICE_MATCH(  0x940A, RHD_R600  ), /* FireGL V8650 */
  159.     RHD_DEVICE_MATCH(  0x940B, RHD_R600  ), /* FireGL V8600 */
  160.     RHD_DEVICE_MATCH(  0x940F, RHD_R600  ), /* FireGL V7600 */
  161.     RHD_DEVICE_MATCH(  0x94C0, RHD_RV610 ), /* RV610 */
  162.     RHD_DEVICE_MATCH(  0x94C1, RHD_RV610 ), /* Radeon HD 2400 XT */
  163.     RHD_DEVICE_MATCH(  0x94C3, RHD_RV610 ), /* Radeon HD 2400 Pro */
  164.     RHD_DEVICE_MATCH(  0x94C4, RHD_RV610 ), /* ATI Radeon HD 2400 PRO AGP */
  165.     RHD_DEVICE_MATCH(  0x94C5, RHD_RV610 ), /* FireGL V4000 */
  166.     RHD_DEVICE_MATCH(  0x94C6, RHD_RV610 ), /* RV610 */
  167.     RHD_DEVICE_MATCH(  0x94C7, RHD_RV610 ), /* ATI Radeon HD 2350 */
  168.     RHD_DEVICE_MATCH(  0x94C8, RHD_M74   ), /* Mobility Radeon HD 2400 XT */
  169.     RHD_DEVICE_MATCH(  0x94C9, RHD_M72   ), /* Mobility Radeon HD 2400 */
  170.     RHD_DEVICE_MATCH(  0x94CB, RHD_M72   ), /* ATI RADEON E2400 */
  171.     RHD_DEVICE_MATCH(  0x94CC, RHD_RV610 ), /* ATI Radeon HD 2400 */
  172.     RHD_DEVICE_MATCH(  0x9500, RHD_RV670 ), /* RV670 */
  173.     RHD_DEVICE_MATCH(  0x9501, RHD_RV670 ), /* ATI Radeon HD3870 */
  174.     RHD_DEVICE_MATCH(  0x9505, RHD_RV670 ), /* ATI Radeon HD3850 */
  175.     RHD_DEVICE_MATCH(  0x9507, RHD_RV670 ), /* RV670 */
  176.     RHD_DEVICE_MATCH(  0x950F, RHD_R680  ), /* ATI Radeon HD3870 X2 */
  177.     RHD_DEVICE_MATCH(  0x9511, RHD_RV670 ), /* ATI FireGL V7700 */
  178.     RHD_DEVICE_MATCH(  0x9515, RHD_RV670 ), /* ATI Radeon HD 3850 AGP */
  179.     RHD_DEVICE_MATCH(  0x9580, RHD_RV630 ), /* RV630 */
  180.     RHD_DEVICE_MATCH(  0x9581, RHD_M76   ), /* Mobility Radeon HD 2600 */
  181.     RHD_DEVICE_MATCH(  0x9583, RHD_M76   ), /* Mobility Radeon HD 2600 XT */
  182.     RHD_DEVICE_MATCH(  0x9586, RHD_RV630 ), /* ATI Radeon HD 2600 XT AGP */
  183.     RHD_DEVICE_MATCH(  0x9587, RHD_RV630 ), /* ATI Radeon HD 2600 Pro AGP */
  184.     RHD_DEVICE_MATCH(  0x9588, RHD_RV630 ), /* Radeon HD 2600 XT */
  185.     RHD_DEVICE_MATCH(  0x9589, RHD_RV630 ), /* Radeon HD 2600 Pro */
  186.     RHD_DEVICE_MATCH(  0x958A, RHD_RV630 ), /* Gemini RV630 */
  187.     RHD_DEVICE_MATCH(  0x958B, RHD_M76   ), /* Gemini ATI Mobility Radeon HD 2600 XT */
  188.     RHD_DEVICE_MATCH(  0x958C, RHD_RV630 ), /* FireGL V5600 */
  189.     RHD_DEVICE_MATCH(  0x958D, RHD_RV630 ), /* FireGL V3600 */
  190.     RHD_DEVICE_MATCH(  0x958E, RHD_RV630 ), /* ATI Radeon HD 2600 LE */
  191.     RHD_DEVICE_MATCH(  0x9590, RHD_RV635 ), /* ATI Radeon HD 3600 Series */
  192.     RHD_DEVICE_MATCH(  0x9591, RHD_RV635 ), /* ATI Mobility Radeon HD 3650 */
  193.     RHD_DEVICE_MATCH(  0x9596, RHD_RV635 ), /* ATI Radeon HD 3650 AGP */
  194.     RHD_DEVICE_MATCH(  0x9597, RHD_RV635 ), /* ATI Radeon HD 3600 Series */
  195.     RHD_DEVICE_MATCH(  0x9598, RHD_RV635 ), /* ATI Radeon HD 3670 */
  196.     RHD_DEVICE_MATCH(  0x9599, RHD_RV635 ), /* ATI Radeon HD 3600 Series */
  197.     RHD_DEVICE_MATCH(  0x95C0, RHD_RV620 ), /* ATI Radeon HD 3470 */
  198.     RHD_DEVICE_MATCH(  0x95C2, RHD_M82   ), /* ATI Mobility Radeon HD 3430 (M82) */
  199.     RHD_DEVICE_MATCH(  0x95C4, RHD_M82 ), /* ATI Mobility Radeon HD 3400 Series (M82)  */
  200.     RHD_DEVICE_MATCH(  0x95C5, RHD_RV620 ), /* ATI Radeon HD 3450 */
  201.     RHD_DEVICE_MATCH(  0x95C7, RHD_RV620 ), /* ATI Radeon HD 3430 */
  202.     RHD_DEVICE_MATCH(  0x95CD, RHD_RV620 ), /* ATI FireMV 2450  */
  203.     RHD_DEVICE_MATCH(  0x95CE, RHD_RV620 ), /* ATI FireMV 2260  */
  204.     RHD_DEVICE_MATCH(  0x95CF, RHD_RV620 ), /* ATI FireMV 2260  */
  205.     LIST_END
  206. };
  207.  
  208. const char *
  209. xf86TokenToString(SymTabPtr table, int token)
  210. {
  211.     int i;
  212.  
  213.     for (i = 0; table[i].token >= 0 && table[i].token != token; i++){};
  214.  
  215.     if (table[i].token < 0)
  216.       return NULL;
  217.     else
  218.       return(table[i].name);
  219. }
  220.  
  221. RHDPtr FindPciDevice()
  222. {
  223.   const PciChipset_t *dev;
  224.   u32 bus, last_bus;
  225.  
  226.   if( (last_bus = PciApi(1))==-1)
  227.     return 0;
  228.  
  229.   for(bus=0;bus<=last_bus;bus++)
  230.   {
  231.     u32 devfn;
  232.  
  233.     for(devfn=0;devfn<256;devfn++)
  234.     {
  235.       u32 id;
  236.       id = PciRead32(bus,devfn, 0);
  237.  
  238.       if( (CARD16)id != VENDOR_ATI)
  239.         continue;
  240.  
  241.       if( (dev=PciDevMatch(id>>16,RHDPCIchipsets))!=NULL)
  242.       {
  243.         CARD32 reg2C;
  244.         int i;
  245.  
  246.         rhd.PciDeviceID = (id>>16);
  247.  
  248.         rhd.bus = bus;
  249.         rhd.devfn = devfn;
  250.         rhd.PciTag = pciTag(bus,(devfn>>3)&0x1F,devfn&0x7);
  251.  
  252.         rhd.ChipSet = dev->ChipSet;
  253.  
  254.         reg2C = PciRead32(bus,devfn, 0x2C);
  255.  
  256.         rhd.subvendor_id = reg2C & 0xFFFF;;
  257.         rhd.subdevice_id = reg2C >> 16;
  258.  
  259.         for (i = 0; i < 6; i++)
  260.         {
  261.           CARD32 base;
  262.           Bool validSize;
  263.  
  264.           base = PciRead32(bus,devfn, PCI_MAP_REG_START + (i << 2));
  265.           if(base)
  266.           {
  267.             if (base & PCI_MAP_IO)
  268.             {
  269.               rhd.ioBase[i] = (CARD32)PCIGETIO(base);
  270.               rhd.memtype[i]   = base & PCI_MAP_IO_ATTR_MASK;
  271.             }
  272.             else
  273.             {
  274.               rhd.memBase[i] = (CARD32)PCIGETMEMORY(base);
  275.               rhd.memtype[i] = base & PCI_MAP_MEMORY_ATTR_MASK;
  276.             }
  277.           }
  278.           rhd.memsize[i] = pciGetBaseSize(bus,devfn, i, TRUE, &validSize);
  279.         }
  280.         rhd.ChipName = (char*)xf86TokenToString(RHDChipsets, rhd.PciDeviceID);
  281.  
  282.         return &rhd;
  283.       }
  284.     };
  285.   };
  286.   return NULL;
  287. }
  288.  
  289. const PciChipset_t *PciDevMatch(CARD16 dev,const PciChipset_t *list)
  290. {
  291.   while(list->device)
  292.   {
  293.     if(dev==list->device)
  294.       return list;
  295.     list++;
  296.   }
  297.   return 0;
  298. }
  299.  
  300.  
  301. CARD32 pciGetBaseSize(int bus, int devfn, int index, Bool destructive, Bool *min)
  302. {
  303.   int offset;
  304.   CARD32 addr1;
  305.   CARD32 addr2;
  306.   CARD32 mask1;
  307.   CARD32 mask2;
  308.   int bits = 0;
  309.  
  310.   /*
  311.    * silently ignore bogus index values.  Valid values are 0-6.  0-5 are
  312.    * the 6 base address registers, and 6 is the ROM base address register.
  313.    */
  314.   if (index < 0 || index > 6)
  315.     return 0;
  316.  
  317.   if (min)
  318.     *min = destructive;
  319.  
  320.   /* Get the PCI offset */
  321.   if (index == 6)
  322.     offset = PCI_MAP_ROM_REG;
  323.   else
  324.     offset = PCI_MAP_REG_START + (index << 2);
  325.  
  326.   addr1 = PciRead32(bus, devfn, offset);
  327.   /*
  328.    * Check if this is the second part of a 64 bit address.
  329.    * XXX need to check how endianness affects 64 bit addresses.
  330.    */
  331.   if (index > 0 && index < 6) {
  332.     addr2 = PciRead32(bus, devfn, offset - 4);
  333.     if (PCI_MAP_IS_MEM(addr2) && PCI_MAP_IS64BITMEM(addr2))
  334.       return 0;
  335.   }
  336.  
  337.   if (destructive) {
  338.      PciWrite32(bus, devfn, offset, 0xffffffff);
  339.      mask1 = PciRead32(bus, devfn, offset);
  340.      PciWrite32(bus, devfn, offset, addr1);
  341.   } else {
  342.     mask1 = addr1;
  343.   }
  344.  
  345.   /* Check if this is the first part of a 64 bit address. */
  346.   if (index < 5 && PCI_MAP_IS_MEM(mask1) && PCI_MAP_IS64BITMEM(mask1))
  347.   {
  348.     if (PCIGETMEMORY(mask1) == 0)
  349.     {
  350.       addr2 = PciRead32(bus, devfn, offset + 4);
  351.       if (destructive)
  352.       {
  353.         PciWrite32(bus, devfn, offset + 4, 0xffffffff);
  354.         mask2 = PciRead32(bus, devfn, offset + 4);
  355.         PciWrite32(bus, devfn, offset + 4, addr2);
  356.       }
  357.       else
  358.      {
  359.        mask2 = addr2;
  360.      }
  361.      if (mask2 == 0)
  362.        return 0;
  363.      bits = 32;
  364.      while ((mask2 & 1) == 0)
  365.      {
  366.        bits++;
  367.        mask2 >>= 1;
  368.      }
  369.      if (bits > 32)
  370.           return bits;
  371.     }
  372.   }
  373.   if (index < 6)
  374.     if (PCI_MAP_IS_MEM(mask1))
  375.       mask1 = PCIGETMEMORY(mask1);
  376.     else
  377.       mask1 = PCIGETIO(mask1);
  378.   else
  379.     mask1 = PCIGETROM(mask1);
  380.   if (mask1 == 0)
  381.     return 0;
  382.   bits = 0;
  383.   while ((mask1 & 1) == 0) {
  384.     bits++;
  385.     mask1 >>= 1;
  386.   }
  387.   /* I/O maps can be no larger than 8 bits */
  388.  
  389.   if ((index < 6) && PCI_MAP_IS_IO(addr1) && bits > 8)
  390.     bits = 8;
  391.   /* ROM maps can be no larger than 24 bits */
  392.   if (index == 6 && bits > 24)
  393.     bits = 24;
  394.   return bits;
  395. }
  396.  
  397.  
  398.