Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenhwpci.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
1.7.6.1
|