Listtree.mcc: use internal inherited class of NListtree
[AROS.git] / arch / all-pc / acpitool / parsers.c
blob46d9394d9e63666fc3c398bfba94433ec2714bba
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <ctype.h>
7 #include <stdio.h>
8 #include <string.h>
10 #include "locale.h"
11 #include "parsers.h"
13 #define D(x)
15 /* Buffer for text formatting */
16 char buf[BUFFER_SIZE];
18 static inline void MakeString(void (*callback)(const char *), const char *fmt, ...)
20 va_list ap;
22 va_start(ap, fmt);
23 vsnprintf(buf, sizeof(buf), fmt, ap);
24 va_end(ap);
26 D(printf("%s\n", buf));
28 callback(buf);
31 static const char *decode_enum(ULONG val, const char **table)
33 unsigned int i;
35 for (i = 0; table[i]; i++)
37 if (val == i)
38 return table[i];
40 return NULL;
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);
47 if (valname)
48 MakeString(cb, "%s: %s", desc, valname);
49 else
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 *))
57 unsigned int i;
59 for (i = 0; table[i]; i++)
61 MakeString(cb, " %s: %s", table[i], FLAG_VAL(flags & (1 << i)));
65 const char *spaces[] =
67 "memory",
68 "I/O ports",
69 "PCI configuration space",
70 "Embedded controller",
71 "SMBus",
72 NULL
75 const char *sizes[] =
77 "byte",
78 "word",
79 "double word",
80 "quad word"
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 *))
89 char *p = buf;
90 int len = sizeof(buf);
91 const char *space;
92 int n, i;
94 n = snprintf(p, len, "%s: ", desc);
95 p += n;
96 len -= n;
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));
101 break;
104 if (i == 4)
105 n = snprintf(p, len, "%s (%u) %s ", _(MSG_UNKNOWN_SIZE), addr->BitWidth, _(MSG_AT));
107 p += n;
108 len -= n;
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));
113 else
114 n = snprintf(p, len, "0x%llX", (long long)addr->Address);
116 p += n;
117 len -= n;
119 if (addr->BitWidth)
121 n = snprintf(p, len, ", %s %u - %u", _(MSG_BITS), addr->BitOffset,
122 addr->BitOffset + addr->BitWidth - 1);
123 p += n;
124 len -= n;
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);
131 else
133 space = decode_enum(addr->SpaceId, spaces);
136 if (space)
137 snprintf(p, len, _(MSG_FMT_KNOWN_SPACE), space);
138 else
139 snprintf(p, len, _(MSG_FMT_UNKNOWN_SPACE), addr->SpaceId);
141 cb(buf);
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 *))
160 int len;
161 int i;
162 int left = length;
164 while (left > 0)
166 char *p = buf;
167 int buflen = sizeof(buf);
169 len = snprintf(p, buflen, "%p:", data);
170 p += len;
171 buflen -= len;
173 for (i = 0; i < 16 && i < left; i++)
175 len = snprintf(p, buflen, " %02x", data[i]);
176 p += len;
177 buflen -= len;
180 if (i != 15)
182 for (; i < 16; i++)
184 *p++ = ' ';
185 *p++ = ' ';
186 *p++ = ' ';
190 *p++ = ' ';
191 *p++ = ' ';
193 for (i = 0; i < 16 && i < left; i++)
195 *p++ = isprint(data[i]) ? data[i] : '.';
198 cb(buf);
200 data += 16;
201 left -= 16;
205 void unknown_parser(const ACPI_TABLE_HEADER *table, void (*cb)(const char *))
207 header_parser(table, cb);
208 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);
217 cb("");
219 header_parser(rsdt, cb);
222 static const char *Profiles[] =
224 "Unspecified",
225 "Desktop",
226 "Mobile",
227 "Workstation",
228 "Enterprize server",
229 "SOHO server",
230 "Appliance",
231 "Performance server"
234 static const char *pc_flags[] =
236 "Have legacy devices",
237 "Have 8042 keyboard controller",
238 "VGA not present",
239 "MSI not supported",
240 "PCIe ASPM controls",
241 NULL
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",
254 "TMR_VAL is 32-bit",
255 "Docking supported",
256 "Reset register supported",
257 "Sealed case",
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",
265 NULL
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);
272 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);
289 if (fadt->DayAlarm)
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);
293 if (fadt->Century)
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))
304 return;
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[] =
312 "Bus default",
313 "Active high",
314 "Invalid (2)",
315 "Active low",
316 NULL
319 static const char *irq_trigger[] =
321 "Bus default",
322 "Edge",
323 "Invalid (2)",
324 "Level",
325 NULL
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[] =
336 "ISA",
337 NULL
340 static const char *int_types[] =
342 "Unknown (0)",
343 "PMI",
344 "INIT",
345 "Corrected platform error",
346 NULL
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))
354 AROS_USERFUNC_INIT
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 */
369 switch (entry->Type)
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));
378 break;
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);
387 break;
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);
397 break;
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);
405 break;
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));
413 else
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);
417 break;
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);
422 break;
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);
431 break;
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));
441 break;
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));
455 break;
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);
465 break;
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));
474 else
475 MakeString(cb, " %s: 0x%08X", _(MSG_CPU_UID), x2nmi->Uid);
476 MakeString(cb, " %s: %u", _(MSG_LINT), x2nmi->Lint);
477 break;
479 default:
480 MakeString(cb, _(MSG_UNKNOWN_ENTRY), entry->Type, entry->Length);
481 break;
484 AROS_USERFUNC_EXIT
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;
496 int count;
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;
500 BOOL res;
501 if (hook == NULL)
502 res = TRUE;
503 else
504 res = CALLHOOKPKT((struct Hook *)hook, (APTR)sh, userdata);
505 if (res)
506 count++;
509 return count;
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);
518 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[] =
528 "None",
529 "4KB",
530 "64KB",
531 NULL
534 /* ID components */
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);
558 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,
571 hpet_protect, cb);
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);
579 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);
590 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))
604 AROS_USERFUNC_INIT
606 cb("");
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);
614 AROS_USERFUNC_EXIT
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;
626 int count;
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;
630 BOOL res;
631 if (hook == NULL)
632 res = TRUE;
633 else
634 res = CALLHOOKPKT((struct Hook *)hook, (APTR)sh, userdata);
635 if (res)
636 count++;
639 return count;
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},
662 {NULL, NULL, NULL}
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)
672 return t;
674 return NULL;