[HAL]: Bus support in the HAL actually creates a further wedge between the different...
[reactos.git] / reactos / hal / halx86 / generic / legacy / bussupp.c
1 /*
2 * PROJECT: ReactOS HAL
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: hal/halx86/generic/legacy/bussupp.c
5 * PURPOSE: HAL Legacy Bus Support Code
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include <hal.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 /* GLOBALS ********************************************************************/
16
17 /* PRIVATE FUNCTIONS **********************************************************/
18
19 PBUS_HANDLER
20 NTAPI
21 HalpAllocateBusHandler(IN INTERFACE_TYPE InterfaceType,
22 IN BUS_DATA_TYPE BusDataType,
23 IN ULONG BusNumber,
24 IN INTERFACE_TYPE ParentBusInterfaceType,
25 IN ULONG ParentBusNumber,
26 IN ULONG BusSpecificData)
27 {
28 PBUS_HANDLER Bus;
29
30 /* Register the bus handler */
31 HalRegisterBusHandler(InterfaceType,
32 BusDataType,
33 BusNumber,
34 ParentBusInterfaceType,
35 ParentBusNumber,
36 BusSpecificData,
37 NULL,
38 &Bus);
39 if (!Bus) return NULL;
40
41 /* Check for a valid interface */
42 if (InterfaceType != InterfaceTypeUndefined)
43 {
44 /* Allocate address ranges and zero them out */
45 Bus->BusAddresses = ExAllocatePoolWithTag(NonPagedPool,
46 sizeof(SUPPORTED_RANGES),
47 ' laH');
48 RtlZeroMemory(Bus->BusAddresses, sizeof(SUPPORTED_RANGES));
49
50 /* Build the data structure */
51 Bus->BusAddresses->Version = HAL_SUPPORTED_RANGE_VERSION;
52 Bus->BusAddresses->Dma.Limit = 7;
53 Bus->BusAddresses->Memory.Limit = 0xFFFFFFFF;
54 Bus->BusAddresses->IO.Limit = 0xFFFF;
55 Bus->BusAddresses->IO.SystemAddressSpace = 1;
56 Bus->BusAddresses->PrefetchMemory.Base = 1;
57 }
58
59 /* Return the bus address */
60 return Bus;
61 }
62
63 VOID
64 NTAPI
65 HalpRegisterInternalBusHandlers(VOID)
66 {
67 PBUS_HANDLER Bus;
68
69 /* Only do processor 1 */
70 if (KeGetCurrentPrcb()->Number) return;
71
72 /* Register root support */
73 HalpInitBusHandler();
74
75 /* Allocate the system bus */
76 Bus = HalpAllocateBusHandler(Internal,
77 ConfigurationSpaceUndefined,
78 0,
79 InterfaceTypeUndefined,
80 0,
81 0);
82 DPRINT1("Registering Internal Bus: %p\n", Bus);
83 if (Bus)
84 {
85 /* Set it up */
86 Bus->GetInterruptVector = HalpGetSystemInterruptVector;
87 Bus->TranslateBusAddress = HalpTranslateSystemBusAddress;
88 }
89
90 /* Allocate the CMOS bus */
91 Bus = HalpAllocateBusHandler(InterfaceTypeUndefined,
92 Cmos,
93 0,
94 InterfaceTypeUndefined,
95 0,
96 0);
97 DPRINT1("Registering CMOS Bus: %p\n", Bus);
98 if (Bus)
99 {
100 /* Set it up */
101 Bus->GetBusData = HalpcGetCmosData;
102 Bus->SetBusData = HalpcSetCmosData;
103 }
104
105 /* Allocate the CMOS bus */
106 Bus = HalpAllocateBusHandler(InterfaceTypeUndefined,
107 Cmos,
108 1,
109 InterfaceTypeUndefined,
110 0,
111 0);
112 DPRINT1("Registering CMOS Bus: %p\n", Bus);
113 if (Bus)
114 {
115 /* Set it up */
116 Bus->GetBusData = HalpcGetCmosData;
117 Bus->SetBusData = HalpcSetCmosData;
118 }
119
120 /* Allocate ISA bus */
121 Bus = HalpAllocateBusHandler(Isa,
122 ConfigurationSpaceUndefined,
123 0,
124 Internal,
125 0,
126 0);
127 DPRINT1("Registering ISA Bus: %p\n", Bus);
128 if (Bus)
129 {
130 /* Set it up */
131 Bus->GetBusData = HalpNoBusData;
132 Bus->BusAddresses->Memory.Limit = 0xFFFFFF;
133 Bus->TranslateBusAddress = HalpTranslateIsaBusAddress;
134 }
135
136 /* No support for EISA or MCA */
137 ASSERT(HalpBusType == MACHINE_TYPE_ISA);
138 }
139
140 VOID
141 NTAPI
142 HalpInitializePciBus(VOID)
143 {
144 /* FIXME: Should do legacy PCI bus detection */
145
146 /* FIXME: Should detect chipset hacks */
147
148 /* FIXME: Should detect broken PCI hardware and apply hacks */
149
150 /* FIXME: Should build resource ranges */
151 }
152
153 VOID
154 NTAPI
155 HalpInitBusHandlers(VOID)
156 {
157 /* Register the HAL Bus Handler support */
158 HalpRegisterInternalBusHandlers();
159 }
160
161 VOID
162 NTAPI
163 HalpRegisterKdSupportFunctions(VOID)
164 {
165 /* Register PCI Device Functions */
166 KdSetupPciDeviceForDebugging = HalpSetupPciDeviceForDebugging;
167 KdReleasePciDeviceforDebugging = HalpReleasePciDeviceForDebugging;
168
169 /* Register memory functions */
170 #ifndef _MINIHAL_
171 KdMapPhysicalMemory64 = HalpMapPhysicalMemory64;
172 KdUnmapVirtualAddress = HalpUnmapVirtualAddress;
173 #endif
174
175 /* Register ACPI stub */
176 KdCheckPowerButton = HalpCheckPowerButton;
177 }
178
179 NTSTATUS
180 NTAPI
181 HalpAssignSlotResources(IN PUNICODE_STRING RegistryPath,
182 IN PUNICODE_STRING DriverClassName,
183 IN PDRIVER_OBJECT DriverObject,
184 IN PDEVICE_OBJECT DeviceObject,
185 IN INTERFACE_TYPE BusType,
186 IN ULONG BusNumber,
187 IN ULONG SlotNumber,
188 IN OUT PCM_RESOURCE_LIST *AllocatedResources)
189 {
190 BUS_HANDLER BusHandler;
191 PAGED_CODE();
192
193 /* Only PCI is supported */
194 if (BusType != PCIBus) return STATUS_NOT_IMPLEMENTED;
195
196 /* Setup fake PCI Bus handler */
197 RtlCopyMemory(&BusHandler, &HalpFakePciBusHandler, sizeof(BUS_HANDLER));
198 BusHandler.BusNumber = BusNumber;
199
200 /* Call the PCI function */
201 return HalpAssignPCISlotResources(&BusHandler,
202 &BusHandler,
203 RegistryPath,
204 DriverClassName,
205 DriverObject,
206 DeviceObject,
207 SlotNumber,
208 AllocatedResources);
209 }
210
211 BOOLEAN
212 NTAPI
213 HalpTranslateBusAddress(IN INTERFACE_TYPE InterfaceType,
214 IN ULONG BusNumber,
215 IN PHYSICAL_ADDRESS BusAddress,
216 IN OUT PULONG AddressSpace,
217 OUT PPHYSICAL_ADDRESS TranslatedAddress)
218 {
219 /* Translation is easy */
220 TranslatedAddress->QuadPart = BusAddress.QuadPart;
221 return TRUE;
222 }
223
224 ULONG
225 NTAPI
226 HalpGetSystemInterruptVector_Acpi(IN ULONG BusNumber,
227 IN ULONG BusInterruptLevel,
228 IN ULONG BusInterruptVector,
229 OUT PKIRQL Irql,
230 OUT PKAFFINITY Affinity)
231 {
232 ULONG Vector = IRQ2VECTOR(BusInterruptLevel);
233 *Irql = (KIRQL)VECTOR2IRQL(Vector);
234 *Affinity = 0xFFFFFFFF;
235 return Vector;
236 }
237
238 BOOLEAN
239 NTAPI
240 HalpFindBusAddressTranslation(IN PHYSICAL_ADDRESS BusAddress,
241 IN OUT PULONG AddressSpace,
242 OUT PPHYSICAL_ADDRESS TranslatedAddress,
243 IN OUT PULONG_PTR Context,
244 IN BOOLEAN NextBus)
245 {
246 /* Make sure we have a context */
247 if (!Context) return FALSE;
248
249 /* If we have data in the context, then this shouldn't be a new lookup */
250 if ((*Context) && (NextBus == TRUE)) return FALSE;
251
252 /* Return bus data */
253 TranslatedAddress->QuadPart = BusAddress.QuadPart;
254
255 /* Set context value and return success */
256 *Context = 1;
257 return TRUE;
258 }
259
260 /* PUBLIC FUNCTIONS **********************************************************/
261
262 /*
263 * @implemented
264 */
265 NTSTATUS
266 NTAPI
267 HalAdjustResourceList(IN PCM_RESOURCE_LIST Resources)
268 {
269 /* Deprecated, return success */
270 return STATUS_SUCCESS;
271 }
272
273 /*
274 * @implemented
275 */
276 NTSTATUS
277 NTAPI
278 HalAssignSlotResources(IN PUNICODE_STRING RegistryPath,
279 IN PUNICODE_STRING DriverClassName,
280 IN PDRIVER_OBJECT DriverObject,
281 IN PDEVICE_OBJECT DeviceObject,
282 IN INTERFACE_TYPE BusType,
283 IN ULONG BusNumber,
284 IN ULONG SlotNumber,
285 IN OUT PCM_RESOURCE_LIST *AllocatedResources)
286 {
287 /* Check the bus type */
288 if (BusType != PCIBus)
289 {
290 /* Call our internal handler */
291 return HalpAssignSlotResources(RegistryPath,
292 DriverClassName,
293 DriverObject,
294 DeviceObject,
295 BusType,
296 BusNumber,
297 SlotNumber,
298 AllocatedResources);
299 }
300 else
301 {
302 /* Call the PCI registered function */
303 return HalPciAssignSlotResources(RegistryPath,
304 DriverClassName,
305 DriverObject,
306 DeviceObject,
307 PCIBus,
308 BusNumber,
309 SlotNumber,
310 AllocatedResources);
311 }
312 }
313
314 /*
315 * @implemented
316 */
317 ULONG
318 NTAPI
319 HalGetBusData(IN BUS_DATA_TYPE BusDataType,
320 IN ULONG BusNumber,
321 IN ULONG SlotNumber,
322 IN PVOID Buffer,
323 IN ULONG Length)
324 {
325 /* Call the extended function */
326 return HalGetBusDataByOffset(BusDataType,
327 BusNumber,
328 SlotNumber,
329 Buffer,
330 0,
331 Length);
332 }
333
334 /*
335 * @implemented
336 */
337 ULONG
338 NTAPI
339 HalGetBusDataByOffset(IN BUS_DATA_TYPE BusDataType,
340 IN ULONG BusNumber,
341 IN ULONG SlotNumber,
342 IN PVOID Buffer,
343 IN ULONG Offset,
344 IN ULONG Length)
345 {
346 BUS_HANDLER BusHandler;
347
348 /* Look as the bus type */
349 if (BusDataType == Cmos)
350 {
351 /* Call CMOS Function */
352 return HalpGetCmosData(0, SlotNumber, Buffer, Length);
353 }
354 else if (BusDataType == EisaConfiguration)
355 {
356 /* FIXME: TODO */
357 ASSERT(FALSE);
358 }
359 else if ((BusDataType == PCIConfiguration) &&
360 (HalpPCIConfigInitialized) &&
361 ((BusNumber >= HalpMinPciBus) && (BusNumber <= HalpMaxPciBus)))
362 {
363 /* Setup fake PCI Bus handler */
364 RtlCopyMemory(&BusHandler, &HalpFakePciBusHandler, sizeof(BUS_HANDLER));
365 BusHandler.BusNumber = BusNumber;
366
367 /* Call PCI function */
368 return HalpGetPCIData(&BusHandler,
369 &BusHandler,
370 *(PPCI_SLOT_NUMBER)&SlotNumber,
371 Buffer,
372 Offset,
373 Length);
374 }
375
376 /* Invalid bus */
377 return 0;
378 }
379
380 /*
381 * @implemented
382 */
383 ULONG
384 NTAPI
385 HalGetInterruptVector(IN INTERFACE_TYPE InterfaceType,
386 IN ULONG BusNumber,
387 IN ULONG BusInterruptLevel,
388 IN ULONG BusInterruptVector,
389 OUT PKIRQL Irql,
390 OUT PKAFFINITY Affinity)
391 {
392 /* Call the system bus translator */
393 return HalpGetSystemInterruptVector_Acpi(BusNumber,
394 BusInterruptLevel,
395 BusInterruptVector,
396 Irql,
397 Affinity);
398 }
399
400 /*
401 * @implemented
402 */
403 ULONG
404 NTAPI
405 HalSetBusData(IN BUS_DATA_TYPE BusDataType,
406 IN ULONG BusNumber,
407 IN ULONG SlotNumber,
408 IN PVOID Buffer,
409 IN ULONG Length)
410 {
411 /* Call the extended function */
412 return HalSetBusDataByOffset(BusDataType,
413 BusNumber,
414 SlotNumber,
415 Buffer,
416 0,
417 Length);
418 }
419
420 /*
421 * @implemented
422 */
423 ULONG
424 NTAPI
425 HalSetBusDataByOffset(IN BUS_DATA_TYPE BusDataType,
426 IN ULONG BusNumber,
427 IN ULONG SlotNumber,
428 IN PVOID Buffer,
429 IN ULONG Offset,
430 IN ULONG Length)
431 {
432 BUS_HANDLER BusHandler;
433
434 /* Look as the bus type */
435 if (BusDataType == Cmos)
436 {
437 /* Call CMOS Function */
438 return HalpSetCmosData(0, SlotNumber, Buffer, Length);
439 }
440 else if ((BusDataType == PCIConfiguration) && (HalpPCIConfigInitialized))
441 {
442 /* Setup fake PCI Bus handler */
443 RtlCopyMemory(&BusHandler, &HalpFakePciBusHandler, sizeof(BUS_HANDLER));
444 BusHandler.BusNumber = BusNumber;
445
446 /* Call PCI function */
447 return HalpSetPCIData(&BusHandler,
448 &BusHandler,
449 *(PPCI_SLOT_NUMBER)&SlotNumber,
450 Buffer,
451 Offset,
452 Length);
453 }
454
455 /* Invalid bus */
456 return 0;
457 }
458
459 /*
460 * @implemented
461 */
462 BOOLEAN
463 NTAPI
464 HalTranslateBusAddress(IN INTERFACE_TYPE InterfaceType,
465 IN ULONG BusNumber,
466 IN PHYSICAL_ADDRESS BusAddress,
467 IN OUT PULONG AddressSpace,
468 OUT PPHYSICAL_ADDRESS TranslatedAddress)
469 {
470 /* Look as the bus type */
471 if (InterfaceType == PCIBus)
472 {
473 /* Call the PCI registered function */
474 return HalPciTranslateBusAddress(PCIBus,
475 BusNumber,
476 BusAddress,
477 AddressSpace,
478 TranslatedAddress);
479 }
480 else
481 {
482 /* Translation is easy */
483 TranslatedAddress->QuadPart = BusAddress.QuadPart;
484 return TRUE;
485 }
486 }
487
488 /* EOF */