According to SDM, if CPUs have APIC ID more than 254 firmware should pass control to OS in x2APIC mode. This series adds x2APIC bootstrap initialization.
QEMU side of x2APIC support: https://lists.gnu.org/archive/html/qemu-devel/2016-05/msg01094.html
Igor Mammedov (2): paravirt: disable MPTable in case of more than 255 CPUs support booting with more than 255 CPUs
src/fw/mptable.c | 4 ++++ src/fw/smp.c | 48 +++++++++++++++++++++++++++++++++++++++--------- src/x86.h | 1 + 3 files changed, 44 insertions(+), 9 deletions(-)
MPTable doesn't support more than 254 CPUs and QEMU supplies an alternative MADT table which guest will use instead of it. So do not install MPTable if more than 254 CPUs are provided.
Signed-off-by: Igor Mammedov imammedo@redhat.com --- src/fw/mptable.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/src/fw/mptable.c b/src/fw/mptable.c index 47385cc..aec26f8 100644 --- a/src/fw/mptable.c +++ b/src/fw/mptable.c @@ -24,6 +24,10 @@ mptable_setup(void) if (! CONFIG_MPTABLE) return;
+ if (romfile_loadint("etc/max-cpus", 0) > 255) { + dprintf(1, "MPTable doesn't support more than 254 CPUs. Skip it.\n"); + return; + } dprintf(3, "init MPTable\n");
// Config structure in temp area.
On Mon, May 09, 2016 at 11:43:53AM +0200, Igor Mammedov wrote:
MPTable doesn't support more than 254 CPUs and QEMU supplies an alternative MADT table which guest will use instead of it. So do not install MPTable if more than 254 CPUs are provided.
Signed-off-by: Igor Mammedov imammedo@redhat.com
src/fw/mptable.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/src/fw/mptable.c b/src/fw/mptable.c index 47385cc..aec26f8 100644 --- a/src/fw/mptable.c +++ b/src/fw/mptable.c @@ -24,6 +24,10 @@ mptable_setup(void) if (! CONFIG_MPTABLE) return;
if (romfile_loadint("etc/max-cpus", 0) > 255) {
dprintf(1, "MPTable doesn't support more than 254 CPUs. Skip it.\n");
return;
} dprintf(3, "init MPTable\n");
// Config structure in temp area.
Thanks. I'd prefer to not make further modifications to fw/mptable.c though. I think it would be better to do something like (totally untested):
--- a/src/fw/paravirt.c +++ b/src/fw/paravirt.c @@ -154,8 +154,14 @@ qemu_platform_setup(void) smp_setup();
// Create bios tables - pirtable_setup(); - mptable_setup(); + if (romfile_find("etc/legacy-tables-loader")) { + // QEMU may specify the PIR and mptable (or leave empty for no tables) + romfile_loader_execute("etc/legacy-tables-loader"); + } else { + // Load the legacy internal tables + pirtable_setup(); + mptable_setup(); + } smbios_setup();
if (CONFIG_FW_ROMFILE_LOAD) {
And then QEMU can create an empty fw_cfg file to suppress both the mptable and the pir table. (Or, it can populate it to specify exactly what QEMU wants in those tables.)
-Kevin
On Mon, 9 May 2016 11:12:25 -0400 "Kevin O'Connor" kevin@koconnor.net wrote:
On Mon, May 09, 2016 at 11:43:53AM +0200, Igor Mammedov wrote:
MPTable doesn't support more than 254 CPUs and QEMU supplies an alternative MADT table which guest will use instead of it. So do not install MPTable if more than 254 CPUs are provided.
Signed-off-by: Igor Mammedov imammedo@redhat.com
src/fw/mptable.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/src/fw/mptable.c b/src/fw/mptable.c index 47385cc..aec26f8 100644 --- a/src/fw/mptable.c +++ b/src/fw/mptable.c @@ -24,6 +24,10 @@ mptable_setup(void) if (! CONFIG_MPTABLE) return;
if (romfile_loadint("etc/max-cpus", 0) > 255) {
dprintf(1, "MPTable doesn't support more than 254 CPUs. Skip it.\n");
return;
} dprintf(3, "init MPTable\n");
// Config structure in temp area.
Thanks. I'd prefer to not make further modifications to fw/mptable.c though. I think it would be better to do something like (totally untested):
--- a/src/fw/paravirt.c +++ b/src/fw/paravirt.c @@ -154,8 +154,14 @@ qemu_platform_setup(void) smp_setup();
// Create bios tables
- pirtable_setup();
- mptable_setup();
if (romfile_find("etc/legacy-tables-loader")) {
// QEMU may specify the PIR and mptable (or leave empty for no tables)
romfile_loader_execute("etc/legacy-tables-loader");
} else {
// Load the legacy internal tables
pirtable_setup();
mptable_setup();
} smbios_setup();
if (CONFIG_FW_ROMFILE_LOAD) {
And then QEMU can create an empty fw_cfg file to suppress both the mptable and the pir table. (Or, it can populate it to specify exactly what QEMU wants in those tables.)
I don't think QEMU would ever want to provide legacy tables as Seabios creates them just fine for supported by them amount of CPUs. It's just that mptable_setup() is broken when there is more than 255 CPUs which leads to out of bound read/write accesses when dealing with APIC ID > 255.
Considering QEMU not being interested in legacy tables, how about following:
--- a/src/fw/paravirt.c +++ b/src/fw/paravirt.c @@ -154,8 +154,10 @@ qemu_platform_setup(void) smp_setup();
// Create bios tables - pirtable_setup(); - mptable_setup(); + if (MaxCountCPUs <= 255) { + pirtable_setup(); + mptable_setup(); + } smbios_setup();
if (CONFIG_FW_ROMFILE_LOAD) {
-Kevin
On Tue, May 10, 2016 at 02:13:35PM +0200, Igor Mammedov wrote:
On Mon, 9 May 2016 11:12:25 -0400 "Kevin O'Connor" kevin@koconnor.net wrote:
On Mon, May 09, 2016 at 11:43:53AM +0200, Igor Mammedov wrote:
MPTable doesn't support more than 254 CPUs and QEMU supplies an alternative MADT table which guest will use instead of it. So do not install MPTable if more than 254 CPUs are provided.
Signed-off-by: Igor Mammedov imammedo@redhat.com
src/fw/mptable.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/src/fw/mptable.c b/src/fw/mptable.c index 47385cc..aec26f8 100644 --- a/src/fw/mptable.c +++ b/src/fw/mptable.c @@ -24,6 +24,10 @@ mptable_setup(void) if (! CONFIG_MPTABLE) return;
if (romfile_loadint("etc/max-cpus", 0) > 255) {
dprintf(1, "MPTable doesn't support more than 254 CPUs. Skip it.\n");
return;
} dprintf(3, "init MPTable\n");
// Config structure in temp area.
Thanks. I'd prefer to not make further modifications to fw/mptable.c though. I think it would be better to do something like (totally untested):
--- a/src/fw/paravirt.c +++ b/src/fw/paravirt.c @@ -154,8 +154,14 @@ qemu_platform_setup(void) smp_setup();
// Create bios tables
- pirtable_setup();
- mptable_setup();
if (romfile_find("etc/legacy-tables-loader")) {
// QEMU may specify the PIR and mptable (or leave empty for no tables)
romfile_loader_execute("etc/legacy-tables-loader");
} else {
// Load the legacy internal tables
pirtable_setup();
mptable_setup();
} smbios_setup();
if (CONFIG_FW_ROMFILE_LOAD) {
And then QEMU can create an empty fw_cfg file to suppress both the mptable and the pir table. (Or, it can populate it to specify exactly what QEMU wants in those tables.)
I don't think QEMU would ever want to provide legacy tables as Seabios creates them just fine for supported by them amount of CPUs. It's just that mptable_setup() is broken when there is more than 255 CPUs which leads to out of bound read/write accesses when dealing with APIC ID > 255.
Considering QEMU not being interested in legacy tables, how about following:
--- a/src/fw/paravirt.c +++ b/src/fw/paravirt.c @@ -154,8 +154,10 @@ qemu_platform_setup(void) smp_setup();
// Create bios tables
- pirtable_setup();
- mptable_setup();
if (MaxCountCPUs <= 255) {
pirtable_setup();
mptable_setup();
} smbios_setup();
if (CONFIG_FW_ROMFILE_LOAD) {
Okay. I think something like:
... if (romfile_loadint("etc/create-legacy-tables", 1)) { pirtable_setup(); mptable_setup(); } ...
would be better. But, I'm also okay with the above MaxCountCPUs solution.
Thanks. -Kevin
SDM[*1] says that if there are CPUs with APIC ID greater than 254, BIOS is to pass control to OS in x2APIC mode. Use the fact that QEMU passes in "etc/max-cpus" max possible "APIC ID + 1" to detect need for x2APIC mode. Also instead of CMOS_BIOS_SMP_COUNT which is limited to 256 CPUs use a new rom file "etc/boot-cpus" that QEMU supporting more than 256 CPUs will provide.
*1) SDM: Volume 3: EXTENDED XAPIC (X2APIC): Initialization by System Software
Signed-off-by: Igor Mammedov imammedo@redhat.com --- src/fw/smp.c | 48 +++++++++++++++++++++++++++++++++++++++--------- src/x86.h | 1 + 2 files changed, 40 insertions(+), 9 deletions(-)
diff --git a/src/fw/smp.c b/src/fw/smp.c index 579acdb..2bb5e1b 100644 --- a/src/fw/smp.c +++ b/src/fw/smp.c @@ -19,6 +19,9 @@ #define APIC_LINT1 ((u8*)BUILD_APIC_ADDR + 0x360)
#define APIC_ENABLED 0x0100 +#define MSR_IA32_APIC_BASE 0x01B +#define MSR_LOCAL_APIC_ID 0x802 +#define MSR_IA32_APICBASE_EXTD (1ULL << 10) /* Enable x2APIC mode */
static struct { u32 index; u64 val; } smp_mtrr[32]; static u32 smp_mtrr_count; @@ -46,6 +49,19 @@ int apic_id_is_present(u8 apic_id) return !!(FoundAPICIDs[apic_id/32] & (1ul << (apic_id % 32))); }
+static void handle_x2apic(u32 has_x2apic) +{ + if (MaxCountCPUs < 256) + return; + + if (!has_x2apic) + return; + + // switch to x2APIC mode + u64 apic_base = rdmsr(MSR_IA32_APIC_BASE); + wrmsr(MSR_IA32_APIC_BASE, apic_base | MSR_IA32_APICBASE_EXTD); +} + void VISIBLE32FLAT handle_smp(void) { @@ -55,17 +71,24 @@ handle_smp(void) // Detect apic_id u32 eax, ebx, ecx, cpuid_features; cpuid(1, &eax, &ebx, &ecx, &cpuid_features); - u8 apic_id = ebx>>24; - dprintf(DEBUG_HDL_smp, "handle_smp: apic_id=%d\n", apic_id); + + handle_x2apic(ecx & CPUID_X2APIC);
// MTRR setup int i; for (i=0; i<smp_mtrr_count; i++) wrmsr(smp_mtrr[i].index, smp_mtrr[i].val);
- // Set bit on FoundAPICIDs - FoundAPICIDs[apic_id/32] |= (1 << (apic_id % 32)); - + /* + * QEMU that supports APIC ID > 255 provides its own BIOS tables + * so skip filling present APIC map as it's not used. + * (it's used for internal BIOS tables for QEMU older than 1.8) + */ + if (MaxCountCPUs < 255) { + u32 apic_id = ebx>>24; + // Set bit on FoundAPICIDs + FoundAPICIDs[apic_id/32] |= (1 << (apic_id % 32)); + } CountCPUs++; }
@@ -91,6 +114,11 @@ smp_setup(void) return; }
+ /* set max possible APIC ID limit for AP bootstrap to decide + * if it neds to switch into x2APIC mode + */ + MaxCountCPUs = romfile_loadint("etc/max-cpus", 1); + // mark the BSP initial APIC ID as found, too: u8 apic_id = ebx>>24; FoundAPICIDs[apic_id/32] |= (1 << (apic_id % 32)); @@ -124,8 +152,9 @@ smp_setup(void) writel(APIC_ICR_LOW, 0x000C4600 | sipi_vector);
// Wait for other CPUs to process the SIPI. - u8 cmos_smp_count = rtc_read(CMOS_BIOS_SMP_COUNT) + 1; - while (cmos_smp_count != CountCPUs) + u16 boot_cpus_count = romfile_loadint("etc/boot-cpus", + rtc_read(CMOS_BIOS_SMP_COUNT) + 1); + while (boot_cpus_count != CountCPUs) asm volatile( // Release lock and allow other processors to use the stack. " movl %%esp, %1\n" @@ -141,8 +170,9 @@ smp_setup(void) // Restore memory. *(u64*)BUILD_AP_BOOT_ADDR = old;
- MaxCountCPUs = romfile_loadint("etc/max-cpus", 0); - if (!MaxCountCPUs || MaxCountCPUs < CountCPUs) + handle_x2apic(ecx & CPUID_X2APIC); + + if (MaxCountCPUs < CountCPUs) MaxCountCPUs = CountCPUs;
dprintf(1, "Found %d cpu(s) max supported %d cpu(s)\n", CountCPUs, diff --git a/src/x86.h b/src/x86.h index 53378e9..5ae1602 100644 --- a/src/x86.h +++ b/src/x86.h @@ -67,6 +67,7 @@ static inline void wbinvd(void) #define CPUID_TSC (1 << 4) #define CPUID_MSR (1 << 5) #define CPUID_APIC (1 << 9) +#define CPUID_X2APIC (1 << 21) #define CPUID_MTRR (1 << 12) static inline void __cpuid(u32 index, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) {
On Mon, May 09, 2016 at 11:43:54AM +0200, Igor Mammedov wrote:
SDM[*1] says that if there are CPUs with APIC ID greater than 254, BIOS is to pass control to OS in x2APIC mode. Use the fact that QEMU passes in "etc/max-cpus" max possible "APIC ID + 1" to detect need for x2APIC mode. Also instead of CMOS_BIOS_SMP_COUNT which is limited to 256 CPUs use a new rom file "etc/boot-cpus" that QEMU supporting more than 256 CPUs will provide.
*1) SDM: Volume 3: EXTENDED XAPIC (X2APIC): Initialization by System Software
Signed-off-by: Igor Mammedov imammedo@redhat.com
src/fw/smp.c | 48 +++++++++++++++++++++++++++++++++++++++--------- src/x86.h | 1 + 2 files changed, 40 insertions(+), 9 deletions(-)
diff --git a/src/fw/smp.c b/src/fw/smp.c index 579acdb..2bb5e1b 100644 --- a/src/fw/smp.c +++ b/src/fw/smp.c @@ -19,6 +19,9 @@ #define APIC_LINT1 ((u8*)BUILD_APIC_ADDR + 0x360)
#define APIC_ENABLED 0x0100 +#define MSR_IA32_APIC_BASE 0x01B +#define MSR_LOCAL_APIC_ID 0x802 +#define MSR_IA32_APICBASE_EXTD (1ULL << 10) /* Enable x2APIC mode */
static struct { u32 index; u64 val; } smp_mtrr[32]; static u32 smp_mtrr_count; @@ -46,6 +49,19 @@ int apic_id_is_present(u8 apic_id) return !!(FoundAPICIDs[apic_id/32] & (1ul << (apic_id % 32))); }
+static void handle_x2apic(u32 has_x2apic) +{
- if (MaxCountCPUs < 256)
return;
- if (!has_x2apic)
return;
- // switch to x2APIC mode
- u64 apic_base = rdmsr(MSR_IA32_APIC_BASE);
- wrmsr(MSR_IA32_APIC_BASE, apic_base | MSR_IA32_APICBASE_EXTD);
+}
void VISIBLE32FLAT handle_smp(void) { @@ -55,17 +71,24 @@ handle_smp(void) // Detect apic_id u32 eax, ebx, ecx, cpuid_features; cpuid(1, &eax, &ebx, &ecx, &cpuid_features);
- u8 apic_id = ebx>>24;
- dprintf(DEBUG_HDL_smp, "handle_smp: apic_id=%d\n", apic_id);
Is it no longer possible to report an identifier for the apic? Was the dprintf removed because the log was filled with cpu reports or because there is no equivalent id?
handle_x2apic(ecx & CPUID_X2APIC);
// MTRR setup int i; for (i=0; i<smp_mtrr_count; i++) wrmsr(smp_mtrr[i].index, smp_mtrr[i].val);
- // Set bit on FoundAPICIDs
- FoundAPICIDs[apic_id/32] |= (1 << (apic_id % 32));
- /*
* QEMU that supports APIC ID > 255 provides its own BIOS tables
* so skip filling present APIC map as it's not used.
* (it's used for internal BIOS tables for QEMU older than 1.8)
*/
- if (MaxCountCPUs < 255) {
u32 apic_id = ebx>>24;
// Set bit on FoundAPICIDs
FoundAPICIDs[apic_id/32] |= (1 << (apic_id % 32));
- } CountCPUs++;
}
@@ -91,6 +114,11 @@ smp_setup(void) return; }
- /* set max possible APIC ID limit for AP bootstrap to decide
* if it neds to switch into x2APIC mode
*/
- MaxCountCPUs = romfile_loadint("etc/max-cpus", 1);
- // mark the BSP initial APIC ID as found, too: u8 apic_id = ebx>>24; FoundAPICIDs[apic_id/32] |= (1 << (apic_id % 32));
This updates FoundAPICIDs even if MaxCountCPUs > 255 which is a little confusing.
I think this patch would be simpler if the updating of FoundAPICIDs was refactored first. Something like the below (totally untested).
-Kevin
--- a/src/fw/smp.c +++ b/src/fw/smp.c @@ -46,27 +46,34 @@ int apic_id_is_present(u8 apic_id) return !!(FoundAPICIDs[apic_id/32] & (1ul << (apic_id % 32))); }
+static int +count_cpu(void) +{ + CountCPUs++; + + // Track found apic id for use in legacy internal bios tables + u32 eax, ebx, ecx, cpuid_features; + cpuid(1, &eax, &ebx, &ecx, &cpuid_features); + u8 apic_id = ebx>>24; + FoundAPICIDs[apic_id/32] |= 1 << (apic_id % 32); + + return apic_id; +} + void VISIBLE32FLAT handle_smp(void) { if (!CONFIG_QEMU) return;
- // Detect apic_id - u32 eax, ebx, ecx, cpuid_features; - cpuid(1, &eax, &ebx, &ecx, &cpuid_features); - u8 apic_id = ebx>>24; + // Track this CPU and detect the apic_id + int apic_id = count_cpu(); dprintf(DEBUG_HDL_smp, "handle_smp: apic_id=%d\n", apic_id);
// MTRR setup int i; for (i=0; i<smp_mtrr_count; i++) wrmsr(smp_mtrr[i].index, smp_mtrr[i].val); - - // Set bit on FoundAPICIDs - FoundAPICIDs[apic_id/32] |= (1 << (apic_id % 32)); - - CountCPUs++; }
// Atomic lock for shared stack across processors. @@ -91,10 +98,8 @@ smp_setup(void) return; }
- // mark the BSP initial APIC ID as found, too: - u8 apic_id = ebx>>24; - FoundAPICIDs[apic_id/32] |= (1 << (apic_id % 32)); - CountCPUs = 1; + // Detect initial boot cpu + count_cpu();
// Setup jump trampoline to counter code. u64 old = *(u64*)BUILD_AP_BOOT_ADDR;
On Mon, 9 May 2016 11:49:36 -0400 "Kevin O'Connor" kevin@koconnor.net wrote:
On Mon, May 09, 2016 at 11:43:54AM +0200, Igor Mammedov wrote:
SDM[*1] says that if there are CPUs with APIC ID greater than 254, BIOS is to pass control to OS in x2APIC mode. Use the fact that QEMU passes in "etc/max-cpus" max possible "APIC ID + 1" to detect need for x2APIC mode. Also instead of CMOS_BIOS_SMP_COUNT which is limited to 256 CPUs use a new rom file "etc/boot-cpus" that QEMU supporting more than 256 CPUs will provide.
*1) SDM: Volume 3: EXTENDED XAPIC (X2APIC): Initialization by System Software
Signed-off-by: Igor Mammedov imammedo@redhat.com
src/fw/smp.c | 48 +++++++++++++++++++++++++++++++++++++++--------- src/x86.h | 1 + 2 files changed, 40 insertions(+), 9 deletions(-)
diff --git a/src/fw/smp.c b/src/fw/smp.c index 579acdb..2bb5e1b 100644 --- a/src/fw/smp.c +++ b/src/fw/smp.c @@ -19,6 +19,9 @@ #define APIC_LINT1 ((u8*)BUILD_APIC_ADDR + 0x360)
#define APIC_ENABLED 0x0100 +#define MSR_IA32_APIC_BASE 0x01B +#define MSR_LOCAL_APIC_ID 0x802 +#define MSR_IA32_APICBASE_EXTD (1ULL << 10) /* Enable x2APIC mode */
static struct { u32 index; u64 val; } smp_mtrr[32]; static u32 smp_mtrr_count; @@ -46,6 +49,19 @@ int apic_id_is_present(u8 apic_id) return !!(FoundAPICIDs[apic_id/32] & (1ul << (apic_id % 32))); }
+static void handle_x2apic(u32 has_x2apic) +{
- if (MaxCountCPUs < 256)
return;
- if (!has_x2apic)
return;
- // switch to x2APIC mode
- u64 apic_base = rdmsr(MSR_IA32_APIC_BASE);
- wrmsr(MSR_IA32_APIC_BASE, apic_base | MSR_IA32_APICBASE_EXTD);
+}
void VISIBLE32FLAT handle_smp(void) { @@ -55,17 +71,24 @@ handle_smp(void) // Detect apic_id u32 eax, ebx, ecx, cpuid_features; cpuid(1, &eax, &ebx, &ecx, &cpuid_features);
- u8 apic_id = ebx>>24;
- dprintf(DEBUG_HDL_smp, "handle_smp: apic_id=%d\n", apic_id);
Is it no longer possible to report an identifier for the apic? Was the dprintf removed because the log was filled with cpu reports or because there is no equivalent id?
I've deleted it by accident, it's possible to read x2APIC ID from from CPUID.0BH.EDX (but that isn't supported by current QEMU, so it returns bogus 0 value) or from MSR after switching into x2APIC mode. I'll add it back using value returned from MSR.
handle_x2apic(ecx & CPUID_X2APIC);
// MTRR setup int i; for (i=0; i<smp_mtrr_count; i++) wrmsr(smp_mtrr[i].index, smp_mtrr[i].val);
- // Set bit on FoundAPICIDs
- FoundAPICIDs[apic_id/32] |= (1 << (apic_id % 32));
- /*
* QEMU that supports APIC ID > 255 provides its own BIOS tables
* so skip filling present APIC map as it's not used.
* (it's used for internal BIOS tables for QEMU older than 1.8)
*/
- if (MaxCountCPUs < 255) {
u32 apic_id = ebx>>24;
// Set bit on FoundAPICIDs
FoundAPICIDs[apic_id/32] |= (1 << (apic_id % 32));
- } CountCPUs++;
}
@@ -91,6 +114,11 @@ smp_setup(void) return; }
- /* set max possible APIC ID limit for AP bootstrap to decide
* if it neds to switch into x2APIC mode
*/
- MaxCountCPUs = romfile_loadint("etc/max-cpus", 1);
- // mark the BSP initial APIC ID as found, too: u8 apic_id = ebx>>24; FoundAPICIDs[apic_id/32] |= (1 << (apic_id % 32));
This updates FoundAPICIDs even if MaxCountCPUs > 255 which is a little confusing.
I think this patch would be simpler if the updating of FoundAPICIDs was refactored first. Something like the below (totally untested).
-Kevin
--- a/src/fw/smp.c +++ b/src/fw/smp.c @@ -46,27 +46,34 @@ int apic_id_is_present(u8 apic_id) return !!(FoundAPICIDs[apic_id/32] & (1ul << (apic_id % 32))); }
+static int +count_cpu(void) +{
- CountCPUs++;
- // Track found apic id for use in legacy internal bios tables
- u32 eax, ebx, ecx, cpuid_features;
- cpuid(1, &eax, &ebx, &ecx, &cpuid_features);
- u8 apic_id = ebx>>24;
- FoundAPICIDs[apic_id/32] |= 1 << (apic_id % 32);
- return apic_id;
+}
void VISIBLE32FLAT handle_smp(void) { if (!CONFIG_QEMU) return;
- // Detect apic_id
- u32 eax, ebx, ecx, cpuid_features;
- cpuid(1, &eax, &ebx, &ecx, &cpuid_features);
- u8 apic_id = ebx>>24;
// Track this CPU and detect the apic_id
int apic_id = count_cpu(); dprintf(DEBUG_HDL_smp, "handle_smp: apic_id=%d\n", apic_id);
// MTRR setup int i; for (i=0; i<smp_mtrr_count; i++) wrmsr(smp_mtrr[i].index, smp_mtrr[i].val);
- // Set bit on FoundAPICIDs
- FoundAPICIDs[apic_id/32] |= (1 << (apic_id % 32));
- CountCPUs++;
}
// Atomic lock for shared stack across processors. @@ -91,10 +98,8 @@ smp_setup(void) return; }
- // mark the BSP initial APIC ID as found, too:
- u8 apic_id = ebx>>24;
- FoundAPICIDs[apic_id/32] |= (1 << (apic_id % 32));
- CountCPUs = 1;
// Detect initial boot cpu
count_cpu();
// Setup jump trampoline to counter code. u64 old = *(u64*)BUILD_AP_BOOT_ADDR;