2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
15 /* Buffer for text formatting */
16 char buf
[BUFFER_SIZE
];
18 static inline void MakeString(void (*callback
)(const char *), const char *fmt
, ...)
23 vsnprintf(buf
, sizeof(buf
), fmt
, ap
);
26 D(printf("%s\n", buf
));
31 static const char *decode_enum(ULONG val
, const char **table
)
35 for (i
= 0; table
[i
]; i
++)
43 static void parse_enum(const char *desc
, ULONG val
, const char **table
, void (*cb
)(const char *))
45 const char *valname
= decode_enum(val
, table
);
48 MakeString(cb
, "%s: %s", desc
, valname
);
50 MakeString(cb
, "%s: %s (%u)", desc
, _(MSG_UNKNOWN
), val
);
53 #define FLAG_VAL(v) ((v) ? _(MSG_YES) : _(MSG_NO))
55 static void parse_flags(ULONG flags
, const char **table
, void (*cb
)(const char *))
59 for (i
= 0; table
[i
]; i
++)
61 MakeString(cb
, " %s: %s", table
[i
], FLAG_VAL(flags
& (1 << i
)));
65 const char *spaces
[] =
69 "PCI configuration space",
70 "Embedded controller",
83 #define ACPI_PCI_OFFSET(addr) (unsigned short)((addr) & 0x0FFFF)
84 #define ACPI_PCI_FUNC(addr) (unsigned short)(((addr) >> 16) & 0x0FFFF)
85 #define ACPI_PCI_DEV(addr) (unsigned short)(((addr) >> 32) & 0x0FFFF)
87 static void parse_addr(const char *desc
, const ACPI_GENERIC_ADDRESS
*addr
, void (*cb
)(const char *))
90 int len
= sizeof(buf
);
94 n
= snprintf(p
, len
, "%s: ", desc
);
98 for (i
= 0; i
< 4; i
++) {
99 if (addr
->BitWidth
== 8*(1 << i
)) {
100 n
= snprintf(p
, len
, "%s %s ", sizes
[i
], _(MSG_AT
));
105 n
= snprintf(p
, len
, "%s (%u) %s ", _(MSG_UNKNOWN_SIZE
), addr
->BitWidth
, _(MSG_AT
));
110 if (addr
->SpaceId
== ACPI_ADR_SPACE_PCI_CONFIG
)
111 n
= snprintf(p
, len
, "0:%u:%u:0x%04X", ACPI_PCI_DEV(addr
->Address
), ACPI_PCI_FUNC(addr
->Address
),
112 ACPI_PCI_OFFSET(addr
->Address
));
114 n
= snprintf(p
, len
, "0x%llX", (long long)addr
->Address
);
121 n
= snprintf(p
, len
, ", %s %u - %u", _(MSG_BITS
), addr
->BitOffset
,
122 addr
->BitOffset
+ addr
->BitWidth
- 1);
127 if (addr
->SpaceId
== ACPI_ADR_SPACE_FIXED_HARDWARE
)
128 space
= _(MSG_SPACE_FIXED
);
129 else if (addr
->SpaceId
>= 0x80)
130 space
= _(MSG_SPACE_OEM
);
133 space
= decode_enum(addr
->SpaceId
, spaces
);
137 snprintf(p
, len
, _(MSG_FMT_KNOWN_SPACE
), space
);
139 snprintf(p
, len
, _(MSG_FMT_UNKNOWN_SPACE
), addr
->SpaceId
);
144 static void header_parser(const ACPI_TABLE_HEADER
*table
, void (*cb
)(const char *))
146 MakeString(cb
, "%s: %.4s, %s %u, %s 0x%p",
147 _(MSG_TABLE_SIGNATURE
), table
->Signature
,
148 _(MSG_REVISION
), table
->Revision
, _(MSG_ADDRESS
), table
);
149 MakeString(cb
, "%s: %.6s", _(MSG_OEM_ID
), &table
->OemId
);
150 MakeString(cb
, "%s: %.8s %s 0x%08X",
151 _(MSG_OEM_TABLE_ID
), table
->OemTableId
,
152 _(MSG_REVISION
), table
->OemRevision
);
153 MakeString(cb
, "%s: %.4s %s 0x%08X",
154 _(MSG_CREATOR_ID
), table
->AslCompilerId
,
155 _(MSG_REVISION
), table
->AslCompilerRevision
);
158 static void dumpData(const unsigned char *data
, int length
, void (*cb
)(const char *))
167 int buflen
= sizeof(buf
);
169 len
= snprintf(p
, buflen
, "%p:", data
);
173 for (i
= 0; i
< 16 && i
< left
; i
++)
175 len
= snprintf(p
, buflen
, " %02x", data
[i
]);
193 for (i
= 0; i
< 16 && i
< left
; i
++)
195 *p
++ = isprint(data
[i
]) ? data
[i
] : '.';
205 void unknown_parser(const ACPI_TABLE_HEADER
*table
, void (*cb
)(const char *))
207 header_parser(table
, cb
);
210 dumpData((const unsigned char *)table
, table
->Length
, cb
);
213 static void rsdt_parser(const ACPI_TABLE_HEADER
*rsdt
, void (*cb
)(const char *))
215 MakeString(cb
, "%s: 0x%p", _(MSG_RSDP_ADDR
), rsdt
);
219 header_parser(rsdt
, cb
);
222 static const char *Profiles
[] =
234 static const char *pc_flags
[] =
236 "Have legacy devices",
237 "Have 8042 keyboard controller",
240 "PCIe ASPM controls",
244 static const char *facp_flags
[] =
246 "CPU has WBINVD instruction",
247 "WBINVD flushes all caches",
248 "C1 power state supported",
249 "C2 power state for multiple CPUs",
250 "No fixed power button",
251 "No fixed sleep button",
252 "RTC wake status in fixed registers",
253 "RTC wakeup from S4 supported",
256 "Reset register supported",
258 "CPU instruction execution needed for sleep",
259 "PCI Express wakeup supported",
260 "Use platform clock",
261 "RTC_STS valid after S4",
262 "Remote power on supported",
263 "Force APIC cluster model",
264 "Force APIC physical destination",
268 static void fadt_parser(const ACPI_TABLE_HEADER
*header
, void (*cb
)(const char *))
270 const ACPI_TABLE_FADT
*fadt
= (const ACPI_TABLE_FADT
*)header
;
271 header_parser(&fadt
->Header
, cb
);
274 parse_enum(_(MSG_PM_PROFILE
), fadt
->PreferredProfile
, Profiles
, cb
);
276 MakeString(cb
, "%s: %d", _(MSG_SCI_INT
), fadt
->SciInterrupt
);
277 MakeString(cb
, "%s: 0x%08X", _(MSG_SMI_CMD
), fadt
->SmiCommand
);
278 MakeString(cb
, "%s: 0x%02X", _(MSG_ACPI_ENABLE
), fadt
->AcpiEnable
);
279 MakeString(cb
, "%s: 0x%02X", _(MSG_ACPI_DISABLE
), fadt
->AcpiDisable
);
280 MakeString(cb
, "%s: 0x%02X", _(MSG_S4BIOS
), fadt
->S4BiosRequest
);
281 MakeString(cb
, "%s: 0x%02X", _(MSG_PSTATE
), fadt
->PstateControl
);
283 if (!(fadt
->Flags
& ACPI_FADT_WBINVD
))
285 MakeString(cb
, "%s: %u", _(MSG_FLUSH_SIZE
), fadt
->FlushSize
);
286 MakeString(cb
, "%s: %u", _(MSG_FLUSH_STRIDE
), fadt
->FlushStride
);
290 MakeString(cb
, "%s: 0x%02X", _(MSG_RTC_DAY_ALARM
), fadt
->DayAlarm
);
291 if (fadt
->MonthAlarm
)
292 MakeString(cb
, "%s: 0x%02X", _(MSG_RTC_MON_ALARM
), fadt
->MonthAlarm
);
294 MakeString(cb
, "%s: 0x%02X", _(MSG_RTC_CENTURY
), fadt
->Century
);
296 MakeString(cb
, "%s:", _(MSG_PC_FLAGS
));
297 parse_flags(fadt
->BootFlags
, pc_flags
, cb
);
299 MakeString(cb
, "%s:", _(MSG_FF_FLAGS
));
300 parse_flags(fadt
->Flags
, facp_flags
, cb
);
302 /* ACPIBase-> 1.0 FADT ends here */
303 if (fadt
->Header
.Length
< offsetof(ACPI_TABLE_FADT
, ResetRegister
))
306 parse_addr(_(MSG_RESET_REG
), &fadt
->ResetRegister
, cb
);
307 MakeString(cb
, "%s: 0x%02X", _(MSG_RESET_VAL
), fadt
->ResetValue
);
310 static const char *irq_polarity
[] =
319 static const char *irq_trigger
[] =
328 static inline void parse_int_flags(UINT16 flags
, void (*cb
)(const char *))
330 parse_enum(_(MSG_POLARITY
), flags
& 3, irq_polarity
, cb
);
331 parse_enum(_(MSG_TRIGGER
), (flags
>> 2) & 3, irq_trigger
, cb
);
334 static const char *srcovr_buses
[] =
340 static const char *int_types
[] =
345 "Corrected platform error",
349 AROS_UFH3(static void, madt_entry_parser
,
350 AROS_UFHA(struct Hook
*, table_hook
, A0
),
351 AROS_UFHA(ACPI_SUBTABLE_HEADER
*, entry
, A2
),
352 AROS_UFHA(out_func
, cb
, A1
))
356 ACPI_MADT_LOCAL_APIC
*lapic
;
357 ACPI_MADT_IO_APIC
*ioapic
;
358 ACPI_MADT_INTERRUPT_OVERRIDE
*srcovr
;
359 ACPI_MADT_NMI_SOURCE
*nmisrc
;
360 ACPI_MADT_LOCAL_APIC_NMI
*nmi
;
361 ACPI_MADT_IO_SAPIC
*iosapic
;
362 ACPI_MADT_LOCAL_SAPIC
*lsapic
;
363 ACPI_MADT_INTERRUPT_SOURCE
*intsrc
;
364 ACPI_MADT_LOCAL_X2APIC
*x2apic
;
365 ACPI_MADT_LOCAL_X2APIC_NMI
*x2nmi
;
367 cb(""); /* Insert empty line */
371 case ACPI_MADT_TYPE_LOCAL_APIC
:
372 lapic
= (ACPI_MADT_LOCAL_APIC
*)entry
;
374 MakeString(cb
, "%s:", _(MSG_LOCAL_APIC
));
375 MakeString(cb
, " %s: 0x%02X", _(MSG_CPU_ID
), lapic
->ProcessorId
);
376 MakeString(cb
, " %s: 0x%02X", _(MSG_LAPIC_ID
), lapic
->Id
);
377 MakeString(cb
, " %s: %s", _(MSG_ENABLED
), FLAG_VAL(lapic
->LapicFlags
& ACPI_MADT_ENABLED
));
380 case ACPI_MADT_TYPE_IO_APIC
:
381 ioapic
= (ACPI_MADT_IO_APIC
*)entry
;
383 MakeString(cb
, "%s:", _(MSG_IOAPIC
));
384 MakeString(cb
, " %s: 0x%02X", _(MSG_ID
), ioapic
->Id
);
385 MakeString(cb
, " %s: 0x%04X", _(MSG_ADDRESS
), ioapic
->Address
);
386 MakeString(cb
, " %s: %d", _(MSG_IRQ_BASE
), ioapic
->GlobalIrqBase
);
389 case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE
:
390 srcovr
= (ACPI_MADT_INTERRUPT_OVERRIDE
*)entry
;
392 MakeString(cb
, "%s:", _(MSG_INT_SRC_OVR
));
393 parse_enum(_(MSG_BUS
), srcovr
->Bus
, srcovr_buses
, cb
);
394 MakeString(cb
, " %s: %u", _(MSG_BUS_IRQ
), srcovr
->SourceIrq
);
395 MakeString(cb
, " %s: %u", _(MSG_GLOBAL_IRQ
), srcovr
->GlobalIrq
);
396 parse_int_flags(srcovr
->IntiFlags
, cb
);
399 case ACPI_MADT_TYPE_NMI_SOURCE
:
400 nmisrc
= (ACPI_MADT_NMI_SOURCE
*)entry
;
402 MakeString(cb
, "%s:", _(MSG_NMI_SRC
));
403 parse_int_flags(nmisrc
->IntiFlags
, cb
);
404 MakeString(cb
, " %s: %u", _(MSG_GLOBAL_IRQ
), nmisrc
->GlobalIrq
);
407 case ACPI_MADT_TYPE_LOCAL_APIC_NMI
:
408 nmi
= (ACPI_MADT_LOCAL_APIC_NMI
*)entry
;
410 MakeString(cb
, "%s:", _(MSG_LAPIC_NMI
));
411 if (nmi
->ProcessorId
== (UINT8
)~0)
412 MakeString(cb
, " %s: %s", _(MSG_CPU_ID
), _(MSG_ALL
));
414 MakeString(cb
, " %s: 0x%02X", _(MSG_CPU_ID
), nmi
->ProcessorId
);
415 parse_int_flags(nmi
->IntiFlags
, cb
);
416 MakeString(cb
, " %s: %u", _(MSG_LINT
), nmi
->Lint
);
419 case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE
:
420 MakeString(cb
, "%s: 0x%016llX", _(MSG_LAPIC_ADDR_OVR
),
421 ((ACPI_MADT_LOCAL_APIC_OVERRIDE
*)entry
)->Address
);
424 case ACPI_MADT_TYPE_IO_SAPIC
:
425 iosapic
= (ACPI_MADT_IO_SAPIC
*)entry
;
427 MakeString(cb
, "%s:", _(MSG_IOSAPIC
));
428 MakeString(cb
, " %s: 0x%02X", _(MSG_ID
), iosapic
->Id
);
429 MakeString(cb
, " %s: %u", _(MSG_IRQ_BASE
), iosapic
->GlobalIrqBase
);
430 MakeString(cb
, " %s: 0x%016llX", _(MSG_ADDRESS
), iosapic
->Address
);
433 case ACPI_MADT_TYPE_LOCAL_SAPIC
:
434 lsapic
= (ACPI_MADT_LOCAL_SAPIC
*)entry
;
436 MakeString(cb
, "%s:", _(MSG_LSAPIC
));
437 MakeString(cb
, " %s: 0x%02X", _(MSG_CPU_ID
), lsapic
->ProcessorId
);
438 MakeString(cb
, " %s: 0x%02X", _(MSG_LSAPIC_ID
), lsapic
->Id
);
439 MakeString(cb
, " %s: 0x%02X", _(MSG_LSAPIC_EID
), lsapic
->Eid
);
440 MakeString(cb
, " %s: %s", _(MSG_ENABLED
), FLAG_VAL(lsapic
->LapicFlags
& 1));
443 case ACPI_MADT_TYPE_INTERRUPT_SOURCE
:
444 intsrc
= (ACPI_MADT_INTERRUPT_SOURCE
*)entry
;
446 MakeString(cb
, "%s:", _(MSG_PLAT_INT_SRC
));
447 parse_int_flags(intsrc
->IntiFlags
, cb
);
448 parse_enum(_(MSG_PLAT_INT_TYPE
), intsrc
->Type
, int_types
, cb
);
449 MakeString(cb
, " %s: 0x%02X", _(MSG_DEST_LSAPIC_ID
), intsrc
->Id
);
450 MakeString(cb
, " %s: 0x%02X", _(MSG_DEST_EID
), intsrc
->Eid
);
451 MakeString(cb
, " %s: 0x%02X", _(MSG_IOSAPIC_VECTOR
), intsrc
->IoSapicVector
);
452 MakeString(cb
, " %s: %u", _(MSG_GLOBAL_IRQ
), intsrc
->GlobalIrq
);
453 MakeString(cb
, " %s: %s", _(MSG_CPEI_PROC_OVR
),
454 FLAG_VAL(intsrc
->Flags
& ACPI_MADT_CPEI_OVERRIDE
));
457 case ACPI_MADT_TYPE_LOCAL_X2APIC
:
458 x2apic
= (ACPI_MADT_LOCAL_X2APIC
*)entry
;
460 MakeString(cb
, "%s:", _(MSG_LOCAL_X2APIC
));
461 MakeString(cb
, " %s: 0x%08X", _(MSG_X2APIC_ID
), x2apic
->LocalApicId
);
462 MakeString(cb
, " %s: %s", _(MSG_ENABLED
),
463 FLAG_VAL(x2apic
->LapicFlags
& 1));
464 MakeString(cb
, " %s: 0x%08X", _(MSG_CPU_UID
), x2apic
->Uid
);
467 case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI
:
468 x2nmi
= (ACPI_MADT_LOCAL_X2APIC_NMI
*)entry
;
470 MakeString(cb
, "%s:",_(MSG_X2APIC_NMI
));
471 parse_int_flags(x2nmi
->IntiFlags
, cb
);
472 if (x2nmi
->Uid
== (UINT32
)~0)
473 MakeString(cb
, " %s: %s", _(MSG_CPU_UID
), _(MSG_ALL
));
475 MakeString(cb
, " %s: 0x%08X", _(MSG_CPU_UID
), x2nmi
->Uid
);
476 MakeString(cb
, " %s: %u", _(MSG_LINT
), x2nmi
->Lint
);
480 MakeString(cb
, _(MSG_UNKNOWN_ENTRY
), entry
->Type
, entry
->Length
);
487 static const struct Hook madtHook
=
489 .h_Entry
= (APTR
)madt_entry_parser
492 static int MADT_ScanEntries(const ACPI_TABLE_MADT
*madt
, const struct Hook
*hook
, APTR userdata
)
494 const UINT8
*madt_entry
= (const UINT8
*)&madt
[1];
495 const UINT8
*madt_end
= (const UINT8
*)madt
+ madt
->Header
.Length
;
498 for (count
= 0; madt_entry
< madt_end
; madt_entry
+= ((const ACPI_SUBTABLE_HEADER
*)madt_entry
)->Length
) {
499 const ACPI_SUBTABLE_HEADER
*sh
= (const ACPI_SUBTABLE_HEADER
*)madt_entry
;
504 res
= CALLHOOKPKT((struct Hook
*)hook
, (APTR
)sh
, userdata
);
512 static void madt_parser(const ACPI_TABLE_HEADER
*header
, void (*cb
)(const char *))
514 const ACPI_TABLE_MADT
*madt
= (const ACPI_TABLE_MADT
*)header
;
515 D(printf("MADT at 0x%p, length %u\n", madt
, len
));
517 header_parser(&madt
->Header
, cb
);
520 MakeString(cb
, "%s: 0x%08X", _(MSG_LAPIC_ADDR
), madt
->Address
);
521 MakeString(cb
, "%s: %s", _(MSG_PCAT_COMPAT
), FLAG_VAL(madt
->Flags
& ACPI_MADT_PCAT_COMPAT
));
523 MADT_ScanEntries(madt
, &madtHook
, cb
);
526 static const char *hpet_protect
[] =
535 #define HPET_HW_REV_MASK 0x000000FF
536 #define HPET_NUM_COMPARATORS_MASK 0x00001F00
537 #define HPET_NUM_COMPARATORS_SHIFT 8
538 #define HPET_COUNTER_SIZE 0x00002000
539 #define HPET_LEGACY_REPLACEMENT 0x00008000
540 #define HPET_PCI_VENDOR_MASK 0xFFFF0000
541 #define HPET_PCI_VENDOR_SHIFT 16
543 /* page_protect components */
544 #define HPET_PAGE_PROTECT_MASK 0x0F
545 #define HPET_OEM_ATTR_MASK 0xF0
546 #define HPET_OEM_ATTR_SHIFT 4
548 #define HPET_PAGE_NONE 0
549 #define HPET_PAGE_4K 1
550 #define HPET_PAGE_64K 2
554 static void hpet_parser(const ACPI_TABLE_HEADER
*header
, void (*cb
)(const char *))
556 const ACPI_TABLE_HPET
*hpet
= (const ACPI_TABLE_HPET
*)header
;
557 header_parser(&hpet
->Header
, cb
);
560 MakeString(cb
, "%s: %u", _(MSG_HW_REVISION
), hpet
->Id
& HPET_HW_REV_MASK
);
561 MakeString(cb
, "%s: %u", _(MSG_NUM_COMPARATORS
),
562 (hpet
->Id
& HPET_NUM_COMPARATORS_MASK
) >> HPET_NUM_COMPARATORS_SHIFT
);
563 MakeString(cb
, "%s: %s", _(MSG_64BIT_COUNTER
), FLAG_VAL(hpet
->Id
& HPET_COUNTER_SIZE
));
564 MakeString(cb
, "%s: %s", _(MSG_LEGACY_REPLACEMENT
), FLAG_VAL(hpet
->Id
& HPET_LEGACY_REPLACEMENT
));
565 MakeString(cb
, "%s: 0x%04X", _(MSG_PCI_VENDOR
),
566 (hpet
->Id
& HPET_PCI_VENDOR_MASK
) >> HPET_PCI_VENDOR_SHIFT
);
567 parse_addr(_(MSG_BASE_ADDRESS
), &hpet
->Address
, cb
);
568 MakeString(cb
, "%s: %u", _(MSG_NUMBER
), hpet
->Sequence
);
569 MakeString(cb
, "%s: %u", _(MSG_MIN_TICK
), hpet
->MinimumTick
);
570 parse_enum(_(MSG_PAGE_PROTECT
), hpet
->Flags
& HPET_PAGE_PROTECT_MASK
,
572 MakeString(cb
, "%s: 0x%02X", _(MSG_OEM_ATTRS
), hpet
->Flags
>> HPET_OEM_ATTR_SHIFT
);
575 static void sbst_parser(const ACPI_TABLE_HEADER
*header
, void (*cb
)(const char *))
577 const ACPI_TABLE_SBST
*sbst
= (const ACPI_TABLE_SBST
*)header
;
578 header_parser(&sbst
->Header
, cb
);
581 MakeString(cb
, "%s: %u %s", _(MSG_BATT_WARN
), sbst
->WarningLevel
, _(MSG_MWH
));
582 MakeString(cb
, "%s: %u %s", _(MSG_BATT_LOW
), sbst
->LowLevel
, _(MSG_MWH
));
583 MakeString(cb
, "%s: %u %s", _(MSG_BATT_CRITICAL
), sbst
->CriticalLevel
, _(MSG_MWH
));
586 static void ecdt_parser(const ACPI_TABLE_HEADER
*header
, void (*cb
)(const char *))
588 const ACPI_TABLE_ECDT
*ecdt
= (const ACPI_TABLE_ECDT
*)header
;
589 header_parser(&ecdt
->Header
, cb
);
592 parse_addr(_(MSG_CMD_REG
), &ecdt
->Control
, cb
);
593 parse_addr(_(MSG_DATA_REG
), &ecdt
->Data
, cb
);
594 MakeString(cb
, "%s: 0x%08X", _(MSG_UID
), ecdt
->Uid
);
595 MakeString(cb
, "%s: %u", _(MSG_SCI_GPE_BIT
), ecdt
->Gpe
);
596 MakeString(cb
, "%s: %s", _(MSG_NAMESPACE_ID
), ecdt
->Id
);
599 AROS_UFH3(static void, mcfg_entry_parser
,
600 AROS_UFHA(struct Hook
*, table_hook
, A0
),
601 AROS_UFHA(ACPI_MCFG_ALLOCATION
*, entry
, A2
),
602 AROS_UFHA(out_func
, cb
, A1
))
608 const ACPI_MCFG_ALLOCATION
*mcfg_alloc
= (ACPI_MCFG_ALLOCATION
*)entry
;
609 MakeString(cb
, "%s: 0x%08llX", _(MSG_MCFG_BASE_ADDRESS
), mcfg_alloc
->Address
);
610 MakeString(cb
, "%s: 0x%04X", _(MSG_MCFG_SEGMENT
), mcfg_alloc
->PciSegment
);
611 MakeString(cb
, "%s: 0x%02X", _(MSG_MCFG_START_BUS_NUMBER
), mcfg_alloc
->StartBusNumber
);
612 MakeString(cb
, "%s: 0x%02X", _(MSG_MCFG_END_BUS_NUMBER
), mcfg_alloc
->EndBusNumber
);
617 static const struct Hook mcfgHook
=
619 .h_Entry
= (APTR
)mcfg_entry_parser
622 static int MMCONFIG_ScanEntries(const ACPI_TABLE_MCFG
*mcfg_tbl
, const struct Hook
*hook
, APTR userdata
)
624 const UINT8
*mcfg_alloc_entry
= (const UINT8
*)mcfg_tbl
+ sizeof(ACPI_TABLE_MCFG
);
625 const UINT8
*mcfg_alloc_end
= (const UINT8
*)mcfg_tbl
+ mcfg_tbl
->Header
.Length
;
628 for (count
= 0; mcfg_alloc_entry
< mcfg_alloc_end
; mcfg_alloc_entry
+= sizeof(ACPI_MCFG_ALLOCATION
)) {
629 const ACPI_MCFG_ALLOCATION
*sh
= (const ACPI_MCFG_ALLOCATION
*)mcfg_alloc_entry
;
634 res
= CALLHOOKPKT((struct Hook
*)hook
, (APTR
)sh
, userdata
);
643 static void mcfg_parser(const ACPI_TABLE_HEADER
*header
, void (*cb
)(const char *))
645 const ACPI_TABLE_MCFG
*mcfg_tbl
= (const ACPI_TABLE_MCFG
*)header
;
647 header_parser(&mcfg_tbl
->Header
, cb
);
649 MMCONFIG_ScanEntries(mcfg_tbl
, &mcfgHook
, cb
);
652 const struct Parser ParserTable
[] =
654 {"RSDT", "System" , rsdt_parser
},
655 {"XSDT", "System" , rsdt_parser
},
656 {"FACP", "Hardware" , fadt_parser
},
657 {"APIC", "Interrupts", madt_parser
},
658 {"HPET", "Timer" , hpet_parser
},
659 {"SBST", "Battery" , sbst_parser
},
660 {"ECDT", "Controller", ecdt_parser
},
661 {"MCFG", "PCI" , mcfg_parser
},
665 const struct Parser
*FindParser(const char *signature
)
667 const struct Parser
*t
;
669 for (t
= ParserTable
; t
->name
; t
++)
671 if (memcmp(signature
,t
->signature
,4) == 0)