ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

hwpci.c
Go to the documentation of this file.
00001 /*
00002  *  FreeLoader
00003  *
00004  *  Copyright (C) 2004  Eric Kohl
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License along
00017  *  with this program; if not, write to the Free Software Foundation, Inc.,
00018  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00019  */
00020 
00021 #include <freeldr.h>
00022 
00023 #define NDEBUG
00024 #include <debug.h>
00025 
00026 DBG_DEFAULT_CHANNEL(HWDETECT);
00027 
00028 static PPCI_IRQ_ROUTING_TABLE
00029 GetPciIrqRoutingTable(VOID)
00030 {
00031   PPCI_IRQ_ROUTING_TABLE Table;
00032   PUCHAR Ptr;
00033   ULONG Sum;
00034   ULONG i;
00035 
00036   Table = (PPCI_IRQ_ROUTING_TABLE)0xF0000;
00037   while ((ULONG_PTR)Table < 0x100000)
00038     {
00039       if (Table->Signature == 'RIP$')
00040     {
00041       TRACE("Found signature\n");
00042 
00043       Ptr = (PUCHAR)Table;
00044       Sum = 0;
00045       for (i = 0; i < Table->TableSize; i++)
00046         {
00047           Sum += Ptr[i];
00048         }
00049 
00050       if ((Sum & 0xFF) != 0)
00051         {
00052           ERR("Invalid routing table\n");
00053           return NULL;
00054         }
00055 
00056       TRACE("Valid checksum\n");
00057 
00058       return Table;
00059     }
00060 
00061       Table = (PPCI_IRQ_ROUTING_TABLE)((ULONG_PTR)Table + 0x10);
00062     }
00063 
00064   return NULL;
00065 }
00066 
00067 
00068 static BOOLEAN
00069 FindPciBios(PPCI_REGISTRY_INFO BusData)
00070 {
00071   REGS  RegsIn;
00072   REGS  RegsOut;
00073 
00074   RegsIn.b.ah = 0xB1; /* Subfunction B1h */
00075   RegsIn.b.al = 0x01; /* PCI BIOS present */
00076 
00077   Int386(0x1A, &RegsIn, &RegsOut);
00078 
00079   if (INT386_SUCCESS(RegsOut) && RegsOut.d.edx == 0x20494350 && RegsOut.b.ah == 0)
00080     {
00081       TRACE("Found PCI bios\n");
00082 
00083       TRACE("AL: %x\n", RegsOut.b.al);
00084       TRACE("BH: %x\n", RegsOut.b.bh);
00085       TRACE("BL: %x\n", RegsOut.b.bl);
00086       TRACE("CL: %x\n", RegsOut.b.cl);
00087 
00088       BusData->NoBuses = RegsOut.b.cl + 1;
00089       BusData->MajorRevision = RegsOut.b.bh;
00090       BusData->MinorRevision = RegsOut.b.bl;
00091       BusData->HardwareMechanism = RegsOut.b.al;
00092 
00093       return TRUE;
00094     }
00095 
00096 
00097   TRACE("No PCI bios found\n");
00098 
00099   return FALSE;
00100 }
00101 
00102 
00103 static VOID
00104 DetectPciIrqRoutingTable(PCONFIGURATION_COMPONENT_DATA BusKey)
00105 {
00106   PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
00107   PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
00108   PPCI_IRQ_ROUTING_TABLE Table;
00109   PCONFIGURATION_COMPONENT_DATA TableKey;
00110   ULONG Size;
00111 
00112   Table = GetPciIrqRoutingTable();
00113   if (Table != NULL)
00114     {
00115       TRACE("Table size: %u\n", Table->TableSize);
00116 
00117       /* Set 'Configuration Data' value */
00118       Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors) +
00119          2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) + Table->TableSize;
00120       PartialResourceList = MmHeapAlloc(Size);
00121       if (PartialResourceList == NULL)
00122       {
00123           ERR("Failed to allocate resource descriptor\n");
00124           return;
00125       }
00126 
00127       /* Initialize resource descriptor */
00128       memset(PartialResourceList, 0, Size);
00129       PartialResourceList->Version = 1;
00130       PartialResourceList->Revision = 1;
00131       PartialResourceList->Count = 2;
00132 
00133       PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
00134       PartialDescriptor->Type = CmResourceTypeBusNumber;
00135       PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
00136       PartialDescriptor->u.BusNumber.Start = 0;
00137       PartialDescriptor->u.BusNumber.Length = 1;
00138 
00139       PartialDescriptor = &PartialResourceList->PartialDescriptors[1];
00140       PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
00141       PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
00142       PartialDescriptor->u.DeviceSpecificData.DataSize = Table->TableSize;
00143 
00144       memcpy(&PartialResourceList->PartialDescriptors[2],
00145           Table, Table->TableSize);
00146 
00147       FldrCreateComponentKey(BusKey,
00148                              PeripheralClass,
00149                              RealModeIrqRoutingTable,
00150                              0x0,
00151                              0x0,
00152                              0xFFFFFFFF,
00153                              "PCI Real-mode IRQ Routing Table",
00154                              PartialResourceList,
00155                              Size,
00156                              &TableKey);
00157 
00158       MmHeapFree(PartialResourceList);
00159     }
00160 }
00161 
00162 
00163 VOID
00164 DetectPciBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
00165 {
00166   PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
00167   PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
00168   PCI_REGISTRY_INFO BusData;
00169   PCONFIGURATION_COMPONENT_DATA BiosKey;
00170   ULONG Size;
00171   PCONFIGURATION_COMPONENT_DATA BusKey;
00172   ULONG i;
00173 
00174   /* Report the PCI BIOS */
00175   if (FindPciBios(&BusData))
00176     {
00177       /* Set 'Configuration Data' value */
00178       Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST,
00179                           PartialDescriptors);
00180       PartialResourceList = MmHeapAlloc(Size);
00181       if (PartialResourceList == NULL)
00182       {
00183           ERR("Failed to allocate resource descriptor\n");
00184           return;
00185       }
00186 
00187       /* Initialize resource descriptor */
00188       memset(PartialResourceList, 0, Size);
00189 
00190       /* Create new bus key */
00191       FldrCreateComponentKey(SystemKey,
00192                              AdapterClass,
00193                              MultiFunctionAdapter,
00194                              0x0,
00195                              0x0,
00196                              0xFFFFFFFF,
00197                              "PCI BIOS",
00198                              PartialResourceList,
00199                              Size,
00200                              &BiosKey);
00201 
00202       /* Increment bus number */
00203       (*BusNumber)++;
00204 
00205       MmHeapFree(PartialResourceList);
00206 
00207       DetectPciIrqRoutingTable(BiosKey);
00208 
00209       /* Report PCI buses */
00210       for (i = 0; i < (ULONG)BusData.NoBuses; i++)
00211       {
00212           /* Check if this is the first bus */
00213           if (i == 0)
00214           {
00215               /* Set 'Configuration Data' value */
00216               Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST,
00217                                   PartialDescriptors) +
00218                      sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) +
00219                      sizeof(PCI_REGISTRY_INFO);
00220               PartialResourceList = MmHeapAlloc(Size);
00221               if (!PartialResourceList)
00222               {
00223                   ERR("Failed to allocate resource descriptor\n");
00224                   return;
00225               }
00226 
00227               /* Initialize resource descriptor */
00228               memset(PartialResourceList, 0, Size);
00229               PartialResourceList->Version = 1;
00230               PartialResourceList->Revision = 1;
00231               PartialResourceList->Count = 1;
00232               PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
00233               PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
00234               PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
00235               PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(PCI_REGISTRY_INFO);
00236               memcpy(&PartialResourceList->PartialDescriptors[1],
00237                      &BusData,
00238                      sizeof(PCI_REGISTRY_INFO));
00239           }
00240           else
00241           {
00242               /* Set 'Configuration Data' value */
00243               Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST,
00244                                   PartialDescriptors);
00245               PartialResourceList = MmHeapAlloc(Size);
00246               if (!PartialResourceList)
00247               {
00248                   ERR("Failed to allocate resource descriptor\n");
00249                   return;
00250               }
00251 
00252               /* Initialize resource descriptor */
00253               memset(PartialResourceList, 0, Size);
00254           }
00255 
00256           /* Create the bus key */
00257           FldrCreateComponentKey(SystemKey,
00258                                  AdapterClass,
00259                                  MultiFunctionAdapter,
00260                                  0x0,
00261                                  0x0,
00262                                  0xFFFFFFFF,
00263                                  "PCI",
00264                                  PartialResourceList,
00265                                  Size,
00266                                  &BusKey);
00267 
00268           MmHeapFree(PartialResourceList);
00269 
00270           /* Increment bus number */
00271           (*BusNumber)++;
00272       }
00273     }
00274 }
00275 
00276 /* EOF */

Generated on Sat May 26 2012 04:17:53 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.