X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Facpi.c;h=107469f2d3ff1be104a190da0d5b0a3928da55f2;hb=refs%2Fheads%2Fcoreboot;hp=0ff1b63d71e8f286ac425183a33620b70487f7be;hpb=2e55b03e6314b6cf282dd2d911598973b37a9ca4;p=seabios.git diff --git a/src/acpi.c b/src/acpi.c index 0ff1b63..107469f 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -139,6 +139,14 @@ struct madt_intsrcovr { u16 flags; } PACKED; +struct madt_local_nmi { + ACPI_SUB_HEADER_DEF + u8 processor_id; /* ACPI processor id */ + u16 flags; /* MPS INTI flags */ + u8 lint; /* Local APIC LINT# */ +} PACKED; + + /* * ACPI 2.0 Generic Address Space definition. */ @@ -300,7 +308,9 @@ build_madt(void) int madt_size = (sizeof(struct multiple_apic_table) + sizeof(struct madt_processor_apic) * MaxCountCPUs + sizeof(struct madt_io_apic) - + sizeof(struct madt_intsrcovr) * 16); + + sizeof(struct madt_intsrcovr) * 16 + + sizeof(struct madt_local_nmi)); + struct multiple_apic_table *madt = malloc_high(madt_size); if (!madt) { warn_noalloc(); @@ -352,7 +362,15 @@ build_madt(void) intsrcovr++; } - build_header((void*)madt, APIC_SIGNATURE, (void*)intsrcovr - (void*)madt, 1); + struct madt_local_nmi *local_nmi = (void*)intsrcovr; + local_nmi->type = APIC_LOCAL_NMI; + local_nmi->length = sizeof(*local_nmi); + local_nmi->processor_id = 0xff; /* all processors */ + local_nmi->flags = 0; + local_nmi->lint = 1; /* LINT1 */ + local_nmi++; + + build_header((void*)madt, APIC_SIGNATURE, (void*)local_nmi - (void*)madt, 1); return madt; } @@ -388,6 +406,7 @@ encodeLen(u8 *ssdt_ptr, int length, int bytes) #define SD_PROC (ssdp_proc_aml + *ssdt_proc_start) #define SSDT_SIGNATURE 0x54445353 // SSDT + static void* build_ssdt(void) { @@ -465,6 +484,44 @@ build_ssdt(void) return ssdt; } +#include "ssdt-pcihp.hex" + +#define PCI_RMV_BASE 0xae0c + +extern void link_time_assertion(void); + +static void* build_pcihp(void) +{ + u32 rmvc_pcrm; + int i; + + u8 *ssdt = malloc_high(sizeof ssdp_pcihp_aml); + memcpy(ssdt, ssdp_pcihp_aml, sizeof ssdp_pcihp_aml); + + /* Runtime patching of EJ0: to disable hotplug for a slot, + * replace the method name: _EJ0 by EJ0_. */ + if (ARRAY_SIZE(aml_ej0_name) != ARRAY_SIZE(aml_adr_dword)) { + link_time_assertion(); + } + + rmvc_pcrm = inl(PCI_RMV_BASE); + for (i = 0; i < ARRAY_SIZE(aml_ej0_name); ++i) { + /* Slot is in byte 2 in _ADR */ + u8 slot = ssdp_pcihp_aml[aml_adr_dword[i] + 2] & 0x1F; + /* Sanity check */ + if (memcmp(ssdp_pcihp_aml + aml_ej0_name[i], "_EJ0", 4)) { + warn_internalerror(); + free(ssdt); + return NULL; + } + if (!(rmvc_pcrm & (0x1 << slot))) { + memcpy(ssdt + aml_ej0_name[i], "EJ0_", 4); + } + } + + return ssdt; +} + #define HPET_SIGNATURE 0x54455048 // HPET static void* build_hpet(void) @@ -646,6 +703,7 @@ acpi_bios_init(void) ACPI_INIT_TABLE(build_madt()); ACPI_INIT_TABLE(build_hpet()); ACPI_INIT_TABLE(build_srat()); + ACPI_INIT_TABLE(build_pcihp()); u16 i, external_tables = qemu_cfg_acpi_additional_tables();