mirror of
https://github.com/memtest86plus/memtest86plus.git
synced 2025-02-25 18:55:23 -06:00
Add support for 64-bit local APIC addresses found in the MADT.
This is untested, as I don't have any hardware that uses this option.
This commit is contained in:
parent
631cd553aa
commit
b3d350f454
37
system/smp.c
37
system/smp.c
@ -96,6 +96,11 @@
|
|||||||
#define CPU_ENABLED 1
|
#define CPU_ENABLED 1
|
||||||
#define CPU_BOOTPROCESSOR 2
|
#define CPU_BOOTPROCESSOR 2
|
||||||
|
|
||||||
|
// MADT entry types
|
||||||
|
|
||||||
|
#define MADT_PROCESSOR 0
|
||||||
|
#define MADT_LAPIC_ADDR 5
|
||||||
|
|
||||||
// MADT processor flag values
|
// MADT processor flag values
|
||||||
|
|
||||||
#define MADT_PF_ENABLED 0x1
|
#define MADT_PF_ENABLED 0x1
|
||||||
@ -204,6 +209,11 @@ typedef struct {
|
|||||||
char creator_revision[4];
|
char creator_revision[4];
|
||||||
} rsdt_header_t;
|
} rsdt_header_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t length;
|
||||||
|
} madt_entry_header_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
uint8_t length;
|
uint8_t length;
|
||||||
@ -212,6 +222,13 @@ typedef struct {
|
|||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
} madt_processor_entry_t;
|
} madt_processor_entry_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t length;
|
||||||
|
uint16_t reserved;
|
||||||
|
uint64_t lapic_addr;
|
||||||
|
} madt_lapic_addr_entry_t;
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Private Variables
|
// Private Variables
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -420,16 +437,16 @@ static bool parse_madt(uintptr_t addr)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
apic = (volatile apic_register_t *)map_region(mpc->lapic_addr, APIC_REGS_SIZE, false);
|
uintptr_t apic_addr = mpc->lapic_addr;
|
||||||
if (apic == NULL) return false;
|
|
||||||
|
|
||||||
int found_cpus = 0;
|
int found_cpus = 0;
|
||||||
|
|
||||||
uint8_t *tab_entry_ptr = (uint8_t *)mpc + sizeof(mp_config_table_header_t);
|
uint8_t *tab_entry_ptr = (uint8_t *)mpc + sizeof(mp_config_table_header_t);
|
||||||
uint8_t *mpc_table_end = (uint8_t *)mpc + mpc->length;
|
uint8_t *mpc_table_end = (uint8_t *)mpc + mpc->length;
|
||||||
while (tab_entry_ptr < mpc_table_end) {
|
while (tab_entry_ptr < mpc_table_end) {
|
||||||
madt_processor_entry_t *entry = (madt_processor_entry_t *)tab_entry_ptr;
|
madt_entry_header_t *entry_header = (madt_entry_header_t *)tab_entry_ptr;
|
||||||
if (entry->type == MP_PROCESSOR) {
|
if (entry_header->type == MADT_PROCESSOR) {
|
||||||
|
madt_processor_entry_t *entry = (madt_processor_entry_t *)tab_entry_ptr;
|
||||||
if (entry->flags & (MADT_PF_ENABLED|MADT_PF_ONLINE_CAPABLE)) {
|
if (entry->flags & (MADT_PF_ENABLED|MADT_PF_ONLINE_CAPABLE)) {
|
||||||
if (num_available_cpus < MAX_CPUS) {
|
if (num_available_cpus < MAX_CPUS) {
|
||||||
cpu_num_to_apic_id[found_cpus] = entry->apic_id;
|
cpu_num_to_apic_id[found_cpus] = entry->apic_id;
|
||||||
@ -441,7 +458,17 @@ static bool parse_madt(uintptr_t addr)
|
|||||||
found_cpus++;
|
found_cpus++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tab_entry_ptr += entry->length;
|
if (entry_header->type == MADT_LAPIC_ADDR) {
|
||||||
|
madt_lapic_addr_entry_t *entry = (madt_lapic_addr_entry_t *)tab_entry_ptr;
|
||||||
|
apic_addr = (uintptr_t)entry->lapic_addr;
|
||||||
|
}
|
||||||
|
tab_entry_ptr += entry_header->length;
|
||||||
|
}
|
||||||
|
|
||||||
|
apic = (volatile apic_register_t *)map_region(apic_addr, APIC_REGS_SIZE, false);
|
||||||
|
if (apic == NULL) {
|
||||||
|
num_available_cpus = 1;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user