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.
*/
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();
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;
}
#define SD_PROC (ssdp_proc_aml + *ssdt_proc_start)
#define SSDT_SIGNATURE 0x54445353 // SSDT
+
static void*
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)
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();