Warning, cross-references for /kernel/smp/acpi.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include "arch/i386.h"
0019 #include "kernel.h"
0020 #include "mem/mem.h"
0021 #include "smp/smp.h"
0022 #include "smp/apic.h"
0023 #include "smp/spinlock.h"
0024 #include "drivers/pci/pci.h"
0025 #include "drivers/acpi/acpi.h"
0026 #include "drivers/acpi/acmacros.h"
0027 #include "drivers/acpi/acexcep.h"
0028 #include "util/printf.h"
0029 #include "util/cpuid.h"
0030
0031 static int process_acpi_tables (void);
0032 static int acpi_add_processor (ACPI_MADT_LOCAL_APIC *);
0033 static void acpi_parse_srat (ACPI_TABLE_SRAT *);
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 #define ACPI_MAX_INIT_TABLES 24
0049 static ACPI_TABLE_DESC TableArray[ACPI_MAX_INIT_TABLES];
0050
0051 uint32
0052 acpi_early_init(void)
0053 {
0054 return process_acpi_tables ();
0055 }
0056
0057 void
0058 acpi_enable_IOAPIC (void)
0059 {
0060 ACPI_STATUS Status;
0061 ACPI_OBJECT arg = { ACPI_TYPE_INTEGER };
0062 ACPI_OBJECT_LIST arg_list = { 1, &arg };
0063 arg.Integer.Value = 1;
0064 Status = AcpiEvaluateObject (NULL, "\\_PIC", &arg_list, NULL);
0065 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) {
0066 com1_printf ("unable to evaluate _PIC(1): %d\n", Status);
0067 } else
0068 com1_printf ("ACPI: IOAPIC mode enabled.\n");
0069 }
0070
0071 static u8 acpi_sci_irq = 9, acpi_sci_flags = 0;
0072 static u32
0073 acpi_irq_handler (u8 vec)
0074 {
0075 extern ACPI_OSD_HANDLER acpi_service_routine;
0076 extern void *acpi_service_routine_context;
0077
0078
0079 if (acpi_service_routine) {
0080 acpi_service_routine (acpi_service_routine_context);
0081 }
0082 return 0;
0083 }
0084
0085 void
0086 acpi_reboot (void)
0087 {
0088 ACPI_STATUS AcpiHwWrite (UINT32 Value, ACPI_GENERIC_ADDRESS *Reg);
0089 AcpiHwWrite (AcpiGbl_FADT.ResetValue, &AcpiGbl_FADT.ResetRegister);
0090 }
0091
0092 static UINT32
0093 acpi_power_button (void *ctxt)
0094 {
0095 logger_printf ("ACPI: acpi_power_button\n");
0096 printf ("REBOOTING...\n");
0097 com1_printf ("REBOOTING...\n");
0098 tsc_delay_usec (100000);
0099 acpi_reboot ();
0100 asm volatile ("hlt");
0101 return 0;
0102 }
0103
0104 static void
0105 acpi_notify_handler (ACPI_HANDLE Device,
0106 UINT32 Value,
0107 void *Context)
0108 {
0109 ACPI_BUFFER Path;
0110 ACPI_STATUS Status;
0111 logger_printf ("ACPI: acpi_notify_handler (0x%p, 0x%X)\n", Device, Value);
0112 Status = AcpiGetName (Device, ACPI_FULL_PATHNAME, &Path);
0113 if (ACPI_SUCCESS (Status)) {
0114 logger_printf (" DeviceName=%s\n", Path.Pointer);
0115 }
0116 }
0117
0118 void
0119 acpi_secondary_init(void)
0120 {
0121 ACPI_STATUS Status;
0122
0123 ACPI_STATUS DisplayOneDevice (ACPI_HANDLE, UINT32, void *, void **);
0124
0125
0126 Status = AcpiInitializeSubsystem ();
0127 if (ACPI_FAILURE (Status)) {
0128 com1_printf ("Failed to initialize ACPI.\n");
0129 }
0130 Status = AcpiReallocateRootTable ();
0131 if (ACPI_FAILURE (Status)) {
0132 com1_printf ("Failed: AcpiReallocateRootTable %d.\n", Status);
0133 }
0134 Status = AcpiLoadTables ();
0135 if (ACPI_FAILURE (Status)) {
0136 com1_printf ("Failed: AcpiLoadTables.\n");
0137 }
0138 Status = AcpiEnableSubsystem (ACPI_FULL_INITIALIZATION);
0139 if (ACPI_FAILURE (Status)) {
0140 com1_printf ("Failed: AcpiEnableSubsystem.\n");
0141 }
0142 Status = AcpiInitializeObjects (ACPI_FULL_INITIALIZATION);
0143 if (ACPI_FAILURE (Status)) {
0144 com1_printf ("Failed: AcpiInitializeObjects.\n");
0145 }
0146
0147
0148 acpi_enable_IOAPIC ();
0149
0150
0151 u8 vector = find_unused_vector (MINIMUM_VECTOR_PRIORITY);
0152 if (vector) {
0153 u64 flags = IOAPIC_DELIVERY_FIXED | IOAPIC_DESTINATION_LOGICAL;
0154 u8 gsi = acpi_sci_irq;
0155
0156 if ((acpi_sci_flags & ACPI_MADT_POLARITY_MASK) == ACPI_MADT_POLARITY_ACTIVE_HIGH)
0157 flags |= IOAPIC_POLARITY_HIGH;
0158 else
0159 flags |= IOAPIC_POLARITY_LOW;
0160 if ((acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) == ACPI_MADT_TRIGGER_EDGE)
0161 flags |= IOAPIC_TRIGGER_EDGE;
0162 else
0163 flags |= IOAPIC_TRIGGER_LEVEL;
0164 if (IOAPIC_map_GSI (gsi, vector, 0x0100000000000000ULL | flags) != -1) {
0165 set_vector_handler (vector, acpi_irq_handler);
0166 logger_printf ("ACPI: mapped GSI 0x%X to vector 0x%X (%s, %s)\n",
0167 gsi, vector,
0168 flags & IOAPIC_TRIGGER_LEVEL ? "level" : "edge",
0169 flags & IOAPIC_POLARITY_LOW ? "low" : "high");
0170 } else
0171 logger_printf ("ACPI: failed to map GSI\n");
0172 } else
0173 logger_printf ("ACPI: failed to find unused vector\n");
0174
0175 logger_printf ("AcpiEnableEvent returned %d\n",
0176 AcpiEnableEvent (ACPI_EVENT_POWER_BUTTON, 0));
0177 logger_printf ("AcpiInstallFixedEventHandler returned %d\n",
0178 AcpiInstallFixedEventHandler (ACPI_EVENT_POWER_BUTTON, acpi_power_button, NULL));
0179 logger_printf ("AcpiInstallNotifyHandler returned %d\n",
0180 AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, acpi_notify_handler, NULL));
0181 logger_printf ("AcpiInstallNotifyHandler returned %d\n",
0182 AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_DEVICE_NOTIFY, acpi_notify_handler, NULL));
0183
0184 extern u8 AcpiGbl_OsiData;
0185 AcpiGbl_OsiData=0;
0186
0187
0188
0189
0190 #if 0
0191 AcpiGetHandle (ACPI_ROOT_OBJECT, ACPI_NS_SYSTEM_BUS, &SysBusHandle);
0192 AcpiWalkNamespace (ACPI_TYPE_ANY, SysBusHandle, INT_MAX,
0193 DisplayOneDevice, NULL, NULL);
0194 #else
0195 AcpiGetDevices (NULL, DisplayOneDevice, NULL, NULL);
0196 #endif
0197 }
0198
0199 #define printf com1_printf
0200 static int
0201 process_acpi_tables (void)
0202 {
0203 extern uint32 mp_LAPIC_addr;
0204 extern uint32 mp_num_IOAPICs;
0205 extern uint32 mp_IOAPIC_addr;
0206 extern mp_IOAPIC_info mp_IOAPICs[];
0207 extern uint32 mp_num_overrides;
0208 extern mp_int_override mp_overrides[];
0209
0210 ACPI_STATUS status;
0211
0212 status = AcpiInitializeTables (TableArray, ACPI_MAX_INIT_TABLES, FALSE);
0213
0214 if (status == AE_OK) {
0215 ACPI_TABLE_MADT *madt;
0216 ACPI_TABLE_FADT *fadt;
0217 ACPI_TABLE_BOOT *boot;
0218 ACPI_TABLE_ASF *asf;
0219 ACPI_TABLE_MCFG *mcfg;
0220 ACPI_TABLE_HPET *hpet;
0221 ACPI_TABLE_TCPA *tcpa;
0222 ACPI_TABLE_SRAT *srat;
0223 ACPI_TABLE_DMAR *dmar;
0224
0225 if (AcpiGetTable (ACPI_SIG_FADT, 0, (ACPI_TABLE_HEADER **) & fadt) ==
0226 AE_OK) {
0227
0228 printf ("Bootflags: %s %s %s\n",
0229 (fadt->BootFlags & ACPI_FADT_LEGACY_DEVICES) ?
0230 "HAS_LEGACY_DEVICES" : "NO_LEGACY_DEVICES",
0231 (fadt->BootFlags & ACPI_FADT_8042) ?
0232 "HAS_KBD_8042" : "NO_KBD_8042",
0233 (fadt->BootFlags & ACPI_FADT_NO_VGA) ?
0234 "NO_VGA_PROBING" : "VGA_PROBING_OK");
0235 printf ("Flags=0x%X SCI_IRQ=0x%X Pm1aEvt=0x%p Pm1aCtl=0x%p\n",
0236 fadt->Flags,
0237 fadt->SciInterrupt,
0238 fadt->Pm1aEventBlock,
0239 fadt->Pm1aControlBlock);
0240 printf ("ResetReg=0x%llX ResetSpace=%d ResetVal=0x%X\n",
0241 fadt->ResetRegister.Address, fadt->ResetRegister.SpaceId, fadt->ResetValue);
0242 acpi_sci_irq = fadt->SciInterrupt;
0243 } else {
0244 printf ("AcpiGetTable FADT: FAILED\n");
0245 }
0246
0247 mp_ISA_bus_id = 0;
0248 if (AcpiGetTable (ACPI_SIG_MADT, 0, (ACPI_TABLE_HEADER **) & madt) ==
0249 AE_OK) {
0250
0251 uint8 *ptr, *lim = (uint8 *) madt + madt->Header.Length;
0252 printf ("ACPI OEM: %.6s Compiler: %.4s LAPIC: %p Flags:%s\n",
0253 madt->Header.OemId,
0254 madt->Header.AslCompilerId,
0255 madt->Address,
0256 (madt->Flags & ACPI_MADT_PCAT_COMPAT) ? " PCAT_COMPAT" : "");
0257 mp_LAPIC_addr = madt->Address;
0258 ptr = (uint8 *) madt + sizeof (ACPI_TABLE_MADT);
0259 while (ptr < lim) {
0260 switch (((ACPI_SUBTABLE_HEADER *) ptr)->Type) {
0261 case ACPI_MADT_TYPE_LOCAL_APIC:{
0262
0263 ACPI_MADT_LOCAL_APIC *sub = (ACPI_MADT_LOCAL_APIC *) ptr;
0264 printf ("Processor: 0x%X APIC-ID: 0x%X %s",
0265 sub->ProcessorId,
0266 sub->Id,
0267 sub->LapicFlags & 1 ? "(enabled)" : "(disabled)");
0268 if (acpi_add_processor (sub)) {
0269 printf (" (booted)");
0270 }
0271 printf ("\n");
0272 break;
0273 }
0274 case ACPI_MADT_TYPE_IO_APIC:{
0275
0276 ACPI_MADT_IO_APIC *sub = (ACPI_MADT_IO_APIC *) ptr;
0277 printf ("IO-APIC ID: %X Address: %X IRQBase: %X\n",
0278 sub->Id, sub->Address, sub->GlobalIrqBase);
0279 if (mp_num_IOAPICs == MAX_IOAPICS)
0280 panic ("Too many IO-APICs.");
0281 mp_IOAPIC_addr = sub->Address;
0282 mp_IOAPICs[mp_num_IOAPICs].id = sub->Id;
0283 mp_IOAPICs[mp_num_IOAPICs].address = sub->Address;
0284 mp_IOAPICs[mp_num_IOAPICs].startGSI = sub->GlobalIrqBase;
0285 mp_IOAPICs[mp_num_IOAPICs].numGSIs = IOAPIC_num_entries();
0286 mp_num_IOAPICs++;
0287 break;
0288 }
0289 case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:{
0290
0291 ACPI_MADT_INTERRUPT_OVERRIDE *sub =
0292 (ACPI_MADT_INTERRUPT_OVERRIDE *) ptr;
0293 printf ("Int. Override: Bus: %X SourceIRQ: %X GlobalIRQ: %X Flags: %X\n",
0294 sub->Bus, sub->SourceIrq, sub->GlobalIrq, sub->IntiFlags);
0295 if (mp_num_overrides == MAX_INT_OVERRIDES)
0296 panic ("Too many interrupt overrides.");
0297 mp_overrides[mp_num_overrides].src_bus = sub->Bus;
0298 mp_overrides[mp_num_overrides].src_IRQ = sub->SourceIrq;
0299 mp_overrides[mp_num_overrides].dest_GSI = sub->GlobalIrq;
0300 mp_num_overrides++;
0301
0302
0303 if (sub->SourceIrq == acpi_sci_irq) {
0304 acpi_sci_irq = sub->GlobalIrq;
0305 acpi_sci_flags = sub->IntiFlags;
0306 }
0307 break;
0308 }
0309 default:
0310 printf ("MADT sub-entry: %X\n",
0311 ((ACPI_SUBTABLE_HEADER *) ptr)->Type);
0312 break;
0313 }
0314 ptr += ((ACPI_SUBTABLE_HEADER *) ptr)->Length;
0315 }
0316 } else {
0317 printf ("AcpiGetTable MADT: FAILED\n");
0318 return 0;
0319 }
0320 if (AcpiGetTable (ACPI_SIG_BOOT, 0, (ACPI_TABLE_HEADER **) & boot) ==
0321 AE_OK) {
0322
0323 printf ("BOOT: CmosIndex=0x%X\n", boot->CmosIndex);
0324 }
0325 if (AcpiGetTable (ACPI_SIG_TCPA, 0, (ACPI_TABLE_HEADER **) & tcpa) ==
0326 AE_OK) {
0327
0328 printf ("TCPA: MaxLog=0x%X Addr: 0x%llX\n",
0329 tcpa->MaxLogLength,
0330 tcpa->LogAddress);
0331 }
0332 if (AcpiGetTable (ACPI_SIG_HPET, 0, (ACPI_TABLE_HEADER **) & hpet) ==
0333 AE_OK) {
0334
0335 printf ("HPET: ID: 0x%X Addr: 0x%p Seq#: 0x%X MinTick: 0x%X Flags: 0x%X\n",
0336 hpet->Id,
0337 hpet->Address,
0338 (uint32) hpet->Sequence,
0339 (uint32) hpet->MinimumTick, (uint32) hpet->Flags);
0340 }
0341 if (AcpiGetTable (ACPI_SIG_MCFG, 0, (ACPI_TABLE_HEADER **) & mcfg) ==
0342 AE_OK) {
0343
0344 printf ("MCFG: Length: %d Reserved: 0x%llX\n",
0345 mcfg->Header.Length,
0346 mcfg->Reserved);
0347 }
0348 if (AcpiGetTable (ACPI_SIG_ASF, 0, (ACPI_TABLE_HEADER **) & asf) == AE_OK) {
0349
0350 printf ("ASF: Length: %d\n", mcfg->Header.Length);
0351 }
0352 if (AcpiGetTable (ACPI_SIG_SRAT, 0, (ACPI_TABLE_HEADER **) & srat) == AE_OK) {
0353
0354 printf ("SRAT: Length: %d\n", srat->Header.Length);
0355 acpi_parse_srat (srat);
0356 }
0357 if (AcpiGetTable (ACPI_SIG_DMAR, 0, (ACPI_TABLE_HEADER **) & dmar) == AE_OK) {
0358
0359 printf ("DMAR: Length: %d Flags: 0x%X Width: %d\n",
0360 dmar->Header.Length,
0361 dmar->Flags,
0362 dmar->Width);
0363 }
0364 } else
0365 return 0;
0366
0367 return mp_num_cpus;
0368 }
0369
0370 #undef printf
0371
0372
0373
0374 static int
0375 acpi_add_processor (ACPI_MADT_LOCAL_APIC * ptr)
0376 {
0377 #ifndef NO_SMP
0378 u32 ebx;
0379 cpuid (1, 0, NULL, &ebx, NULL, NULL);
0380 uint8 this_apic_id = ebx >> 24;
0381 uint8 apic_id = ptr->Id;
0382
0383 if (!(ptr->LapicFlags & 1))
0384 return 0;
0385 if (this_apic_id == apic_id)
0386 return 0;
0387
0388 if (smp_boot_cpu (apic_id, APIC_VER_NEW)) {
0389 CPU_to_APIC[mp_num_cpus] = apic_id;
0390 APIC_to_CPU[apic_id] = mp_num_cpus;
0391 mp_num_cpus++;
0392 return 1;
0393 } else
0394 return 0;
0395 #else
0396 return 0;
0397 #endif
0398 }
0399
0400
0401
0402 extern char const *AcpiGbl_ExceptionNames_Env[];
0403
0404 ACPI_STATUS
0405 GetLnkIrq (ACPI_RESOURCE *Resource, void *Context)
0406 {
0407 pci_irq_t *irq = (pci_irq_t *)Context;
0408 if (Resource->Type == ACPI_RESOURCE_TYPE_IRQ) {
0409 irq->gsi = Resource->Data.Irq.Interrupts[0];
0410 irq->trigger = Resource->Data.Irq.Triggering;
0411 irq->polarity = Resource->Data.Irq.Polarity;
0412 return AE_CTRL_TERMINATE;
0413 }
0414 return AE_OK;
0415 }
0416
0417 void
0418 GetLnkInfo (char *lnkname, pci_irq_t *irq)
0419 {
0420 ACPI_HANDLE Handle;
0421 ACPI_STATUS Status;
0422
0423 Status = AcpiGetHandle (NULL, lnkname, &Handle);
0424 if (ACPI_SUCCESS (Status)) {
0425 AcpiWalkResources (Handle, "_CRS", GetLnkIrq, (void *) irq);
0426 }
0427 }
0428
0429 #define READ(bus, slot, func, reg, type) \
0430 pci_read_##type (pci_addr (bus, slot, func, reg))
0431
0432 ACPI_STATUS
0433 DisplayOneDevice (ACPI_HANDLE ObjHandle, UINT32 Level, void *Context,
0434 void **RetVal)
0435 {
0436 ACPI_STATUS Status;
0437 ACPI_DEVICE_INFO *Info;
0438 ACPI_BUFFER Path;
0439 ACPI_BUFFER Result;
0440 ACPI_OBJECT Obj;
0441 char Buffer[256];
0442 uint8 prt_buf[1024];
0443 ACPI_BUFFER Prt = { .Length = sizeof (prt_buf), .Pointer = prt_buf };
0444 ACPI_PCI_ROUTING_TABLE *prtd;
0445 uint32 addr=0;
0446 uint32 fun = 0;
0447 bool pcibus=FALSE;
0448 u8 busnum;
0449
0450 Path.Length = sizeof (Buffer);
0451 Path.Pointer = Buffer;
0452
0453 Status = AcpiGetName (ObjHandle, ACPI_FULL_PATHNAME, &Path);
0454 if (ACPI_SUCCESS (Status)) {
0455 com1_printf ("%s: \n", Path.Pointer);
0456 }
0457 Status = AcpiGetObjectInfo (ObjHandle, &Info);
0458 if (ACPI_SUCCESS (Status)) {
0459 com1_printf (" ");
0460 if (Info->Flags & ACPI_PCI_ROOT_BRIDGE) {
0461 com1_printf (" PCI_ROOT");
0462 busnum = 0;
0463 pcibus = TRUE;
0464 }
0465 if (Info->Valid & ACPI_VALID_STA)
0466 com1_printf (" STA %.8X", Info->CurrentStatus);
0467 if (Info->Valid & ACPI_VALID_ADR) {
0468 com1_printf (" ADR %.8X", Info->Address);
0469 addr = Info->Address >> 16;
0470 fun = Info->Address & 0x7;
0471 }
0472 if (Info->Valid & ACPI_VALID_HID)
0473 com1_printf (" HID %s", Info->HardwareId.String);
0474 if (Info->Valid & ACPI_VALID_UID)
0475 com1_printf (" UID %s", Info->UniqueId.String);
0476 if (Info->Valid & ACPI_VALID_CID)
0477 com1_printf (" CID");
0478
0479 ACPI_FREE (Info);
0480 }
0481
0482 Result.Length = sizeof (Obj);
0483 Result.Pointer = &Obj;
0484 Status =
0485 AcpiEvaluateObjectTyped (ObjHandle, "_DDN", NULL, &Result,
0486 ACPI_TYPE_STRING);
0487 if (ACPI_SUCCESS (Status)) {
0488 com1_printf (" DDN=%s", Obj.String.Pointer);
0489 }
0490
0491 Result.Length = sizeof (Obj);
0492 Result.Pointer = &Obj;
0493 Status =
0494 AcpiEvaluateObjectTyped (ObjHandle, "_STR", NULL, &Result,
0495 ACPI_TYPE_STRING);
0496 if (ACPI_SUCCESS (Status)) {
0497 com1_printf (" STR=%s", Obj.String.Pointer);
0498 }
0499
0500 Result.Length = sizeof (Obj);
0501 Result.Pointer = &Obj;
0502 Status =
0503 AcpiEvaluateObjectTyped (ObjHandle, "_MLS", NULL, &Result,
0504 ACPI_TYPE_STRING);
0505 if (ACPI_SUCCESS (Status)) {
0506 com1_printf (" MLS=%s", Obj.String.Pointer);
0507 }
0508
0509 Status =
0510 AcpiEvaluateObjectTyped (ObjHandle, "_BBN", NULL, &Result,
0511 ACPI_TYPE_INTEGER);
0512 if (ACPI_SUCCESS (Status)) {
0513 com1_printf (" BBN=%d", Obj.Integer.Value);
0514 } else if (Status != AE_NOT_FOUND)
0515 com1_printf (" bbnERR=%d", Status);
0516
0517 Status =
0518 AcpiEvaluateObjectTyped (ObjHandle, "_PXM", NULL, &Result,
0519 ACPI_TYPE_INTEGER);
0520 if (ACPI_SUCCESS (Status)) {
0521 com1_printf (" PXM=%d", Obj.Integer.Value);
0522 } else if (Status != AE_NOT_FOUND)
0523 com1_printf (" pxmERR=%d", Status);
0524
0525
0526 com1_printf ("\n");
0527
0528 for (;;) {
0529 Status = AcpiGetIrqRoutingTable (ObjHandle, &Prt);
0530 if (ACPI_FAILURE (Status)) {
0531 if (Status == AE_BUFFER_OVERFLOW) {
0532 com1_printf ("AcpiGetIrqRoutingTable failed: BUFFER OVERFLOW\n");
0533 }
0534 break;
0535 } else break;
0536 }
0537 if (ACPI_SUCCESS (Status)) {
0538 int i;
0539
0540
0541 if (READ (0, addr, 0, 0, dword) != 0xFFFFFFFF) {
0542 u8 hdrtype = READ (0, addr, 0, 0x0E, byte);
0543 if ((hdrtype & 0x7F) == 1) {
0544
0545 busnum = READ (0, addr, fun, 0x19, byte);
0546 com1_printf (" bus=0x%.02X\n", busnum);
0547 pcibus = TRUE;
0548 }
0549 }
0550
0551 for (i=0;i<sizeof(prt_buf);) {
0552 pci_irq_t irq;
0553 prtd = (ACPI_PCI_ROUTING_TABLE *)(&prt_buf[i]);
0554 if (prtd->Length == 0) break;
0555
0556 if (pcibus) {
0557 irq.bus = busnum;
0558 irq.dev = (uint32) ((prtd->Address >> 16) & 0xFF);
0559 irq.pin = prtd->Pin + 1;
0560 irq.gsi = 0;
0561 }
0562
0563 if (prtd->Source[0]) {
0564 com1_printf (" PRT entry: len=%d pin=%d addr=%p srcidx=0x%x src=%s\n",
0565 prtd->Length,
0566 prtd->Pin,
0567 (uint32)prtd->Address,
0568 prtd->SourceIndex,
0569 &prtd->Source[0]);
0570 GetLnkInfo (&prtd->Source[0], &irq);
0571 } else {
0572 com1_printf (" PRT entry: len=%d pin=%d addr=%p fixed IRQ=0x%x\n",
0573 prtd->Length,
0574 prtd->Pin,
0575 (uint32)prtd->Address,
0576 prtd->SourceIndex);
0577 irq.gsi = prtd->SourceIndex;
0578 irq.polarity = POLARITY_DEFAULT;
0579 irq.trigger = TRIGGER_DEFAULT;
0580 }
0581
0582 if (pcibus && irq.gsi != 0)
0583 pci_irq_register (&irq);
0584
0585 i+=prtd->Length;
0586 }
0587 }
0588
0589 #if 0
0590 ACPI_STATUS DisplayResource (ACPI_RESOURCE *Resource, void *Context);
0591 com1_printf (" _PRS:\n");
0592 AcpiWalkResources (ObjHandle, "_PRS", DisplayResource, NULL);
0593 com1_printf (" _CRS:\n");
0594 AcpiWalkResources (ObjHandle, "_CRS", DisplayResource, NULL);
0595 #endif
0596 return AE_OK;
0597 }
0598
0599 ACPI_STATUS
0600 DisplayResource (ACPI_RESOURCE *Resource, void *Context)
0601 {
0602 int i;
0603 com1_printf ("Resource: type=%d ", Resource->Type);
0604 switch (Resource->Type) {
0605 case ACPI_RESOURCE_TYPE_IRQ:
0606 com1_printf ("IRQ dlen=%d trig=%d pol=%d shar=%d cnt=%d\n int=",
0607 Resource->Data.Irq.DescriptorLength,
0608 Resource->Data.Irq.Triggering,
0609 Resource->Data.Irq.Polarity,
0610 Resource->Data.Irq.Sharable,
0611 Resource->Data.Irq.InterruptCount);
0612 for (i=0;i<Resource->Data.Irq.InterruptCount;i++)
0613 com1_printf ("%.02X ", Resource->Data.Irq.Interrupts[i]);
0614 com1_printf ("\n");
0615 break;
0616 case ACPI_RESOURCE_TYPE_IO:
0617 com1_printf ("IO decode=0x%x align=0x%x addrlen=%d min=0x%.04X max=0x%.04X\n",
0618 Resource->Data.Io.IoDecode,
0619 Resource->Data.Io.Alignment,
0620 Resource->Data.Io.AddressLength,
0621 Resource->Data.Io.Minimum,
0622 Resource->Data.Io.Maximum);
0623 break;
0624 case ACPI_RESOURCE_TYPE_END_TAG:
0625 com1_printf ("end_tag\n");
0626 break;
0627 case ACPI_RESOURCE_TYPE_ADDRESS16:
0628 com1_printf ("ADDR16 type=%d min=0x%.04X max=0x%.04X gran=0x%.04X trans=0x%.04X\n",
0629 Resource->Data.Address16.ResourceType,
0630 Resource->Data.Address16.Minimum,
0631 Resource->Data.Address16.Maximum,
0632 Resource->Data.Address16.Granularity,
0633 Resource->Data.Address16.TranslationOffset);
0634 break;
0635 case ACPI_RESOURCE_TYPE_ADDRESS32:
0636 com1_printf ("ADDR32 type=%d min=0x%.04X max=0x%.04X\n",
0637 Resource->Data.Address32.ResourceType,
0638 Resource->Data.Address32.Minimum,
0639 Resource->Data.Address32.Maximum);
0640 break;
0641 default:
0642 com1_printf ("unhandled\n");
0643 break;
0644 }
0645 return AE_OK;
0646 }
0647
0648
0649
0650 static void
0651 acpi_parse_srat (ACPI_TABLE_SRAT *srat)
0652 {
0653 ACPI_SRAT_CPU_AFFINITY *cpu;
0654 ACPI_SRAT_MEM_AFFINITY *mem;
0655 ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic;
0656 u32 prox;
0657 ACPI_SUBTABLE_HEADER *sub = (ACPI_SUBTABLE_HEADER *) &srat[1];
0658 int len = srat->Header.Length;
0659
0660 len -= sizeof (ACPI_TABLE_SRAT);
0661 while (len > 0) {
0662
0663
0664 switch (sub->Type) {
0665 case ACPI_SRAT_TYPE_CPU_AFFINITY:
0666 cpu = (ACPI_SRAT_CPU_AFFINITY *) sub;
0667 prox = cpu->ProximityDomainLo |
0668 (cpu->ProximityDomainHi[0] << 0x08 |
0669 cpu->ProximityDomainHi[1] << 0x10 |
0670 cpu->ProximityDomainHi[2] << 0x18);
0671 logger_printf ("SRAT: CPU: prox=0x%X apicID=0x%X flags=0x%X%s sapicEID=0x%X\n",
0672 prox, cpu->ApicId, cpu->Flags,
0673 cpu->Flags & ACPI_SRAT_CPU_ENABLED ? " enabled" : "",
0674 cpu->LocalSapicEid);
0675 break;
0676 case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
0677 mem = (ACPI_SRAT_MEM_AFFINITY *) sub;
0678 logger_printf ("SRAT: MEM: prox=0x%X base=0x%llX len=0x%llX flags=0x%X%s%s%s\n",
0679 mem->ProximityDomain, mem->BaseAddress, mem->Length, mem->Flags,
0680 mem->Flags & ACPI_SRAT_MEM_ENABLED ? " enabled" : "",
0681 mem->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE ? " hotplug" : "",
0682 mem->Flags & ACPI_SRAT_MEM_NON_VOLATILE ? " nonvolatile" : "");
0683 break;
0684 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
0685 x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *) sub;
0686 logger_printf ("SRAT: X2APIC: prox=0x%X apicID=0x%X flags=0x%X%s clockDom=0x%X\n",
0687 x2apic->ProximityDomain, x2apic->ApicId, x2apic->Flags,
0688 x2apic->Flags & ACPI_SRAT_CPU_ENABLED ? " enabled" : "",
0689 x2apic->ClockDomain);
0690 break;
0691 default:
0692 logger_printf ("SRAT: unknown subtype type=%d\n", sub->Type);
0693 break;
0694 }
0695 len -= sub->Length;
0696 sub = (ACPI_SUBTABLE_HEADER *) &((u8 *) sub)[sub->Length];
0697 }
0698 }
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712