diff --git a/headers/private/kernel/arch/x86/smp_apic.h b/headers/private/kernel/arch/x86/smp_apic.h index 0dcc38e107..a66d41a744 100644 --- a/headers/private/kernel/arch/x86/smp_apic.h +++ b/headers/private/kernel/arch/x86/smp_apic.h @@ -108,39 +108,33 @@ #define MP_EXT_IO_INT 3 #define MP_EXT_LOCAL_INT 4 -#define MP_EXT_PE_LEN 20 -#define MP_EXT_BUS_LEN 8 -#define MP_EXT_IO_APIC_LEN 8 -#define MP_EXT_IO_INT_LEN 8 -#define MP_EXT_LOCAL_INT_LEN 8 - struct mp_config_table { uint32 signature; /* "PCMP" */ - uint16 table_len; /* length of this structure */ - uint8 mp_rev; /* spec supported, 1 for 1.1 or 4 for 1.4 */ + uint16 base_table_length; /* length of the base table entries and this structure */ + uint8 spec_revision; /* spec supported, 1 for 1.1 or 4 for 1.4 */ uint8 checksum; /* checksum, all bytes add up to zero */ char oem[8]; /* oem identification, not null-terminated */ char product[12]; /* product name, not null-terminated */ - void *oem_table_ptr; /* addr of oem-defined table, zero if none */ - uint16 oem_len; /* length of oem table */ - uint16 num_entries; /* number of entries in base table */ + void *oem_table; /* addr of oem-defined table, zero if none */ + uint16 oem_length; /* length of oem table */ + uint16 num_base_entries; /* number of entries in base table */ uint32 apic; /* address of apic */ - uint16 ext_len; /* length of extended section */ + uint16 ext_length; /* length of extended section */ uint8 ext_checksum; /* checksum of extended table entries */ }; -struct mp_flt_struct { +struct mp_floating_struct { uint32 signature; /* "_MP_" */ - struct mp_config_table *mpc; /* address of mp configuration table */ - uint8 mpc_len; /* length of this structure in 16-byte units */ - uint8 mp_rev; /* spec supported, 1 for 1.1 or 4 for 1.4 */ + struct mp_config_table *config_table; /* address of mp configuration table */ + uint8 config_length; /* length of the table in 16-byte units */ + uint8 spec_revision; /* spec supported, 1 for 1.1 or 4 for 1.4 */ uint8 checksum; /* checksum, all bytes add up to zero */ uint8 mp_feature_1; /* mp system configuration type if no mpc */ uint8 mp_feature_2; /* imcrp */ uint8 mp_feature_3, mp_feature_4, mp_feature_5; /* reserved */ }; -struct mp_ext_pe { +struct mp_base_processor { uint8 type; uint8 apic_id; uint8 apic_version; @@ -150,7 +144,7 @@ struct mp_ext_pe { uint32 res1, res2; }; -struct mp_ext_ioapic { +struct mp_base_ioapic { uint8 type; uint8 ioapic_id; uint8 ioapic_version; @@ -158,13 +152,13 @@ struct mp_ext_ioapic { uint32 *addr; }; -struct mp_ext_bus { +struct mp_base_bus { uint8 type; uint8 bus_id; char name[6]; }; -struct mp_ext_interrupt { +struct mp_base_interrupt { uint8 type; uint8 interrupt_type; uint16 polarity : 2; @@ -176,4 +170,11 @@ struct mp_ext_interrupt { uint8 dest_apic_int; }; +enum { + MP_INT_TYPE_INT = 0, + MP_INT_TYPE_NMI, + MP_INT_TYPE_SMI, + MP_INT_TYPE_ExtINT, +}; + #endif /* _KERNEL_ARCH_x86_SMP_APIC_H */ diff --git a/src/system/boot/platform/bios_ia32/smp_boot.c b/src/system/boot/platform/bios_ia32/smp_boot.c index 20b9460446..a0219ce04e 100644 --- a/src/system/boot/platform/bios_ia32/smp_boot.c +++ b/src/system/boot/platform/bios_ia32/smp_boot.c @@ -33,6 +33,18 @@ struct gdt_idt_descr { uint32 *b; } _PACKED; +struct smp_scan_spots_struct { + uint32 start; + uint32 stop; + uint32 length; +}; + +static struct smp_scan_spots_struct smp_scan_spots[] = { + { 0x9fc00, 0xa0000, 0xa0000 - 0x9fc00 }, + { 0xf0000, 0x100000, 0x100000 - 0xf0000 }, + { 0, 0, 0 } +}; + extern void execute_n_instructions(int count); @@ -40,9 +52,7 @@ extern void smp_trampoline(void); extern void smp_trampoline_end(void); -static uint32 mp_mem_phys = 0; -static uint32 mp_mem_virt = 0; -static struct mp_flt_struct *mp_flt_ptr = NULL; +static struct mp_floating_struct *sFloatingStruct = NULL; static int smp_get_current_cpu(void); @@ -61,20 +71,6 @@ apic_write(uint32 offset, uint32 data) *addr = data; } -/* -static void * -mp_virt_to_phys(void *ptr) -{ - return ((void *)(((unsigned int)ptr - mp_mem_virt) + mp_mem_phys)); -} -*/ - -static void * -mp_phys_to_virt(void *ptr) -{ - return ((void *)(((uint32)ptr - mp_mem_phys) + mp_mem_virt)); -} - static int smp_get_current_cpu(void) @@ -106,9 +102,9 @@ smp_probe(uint32 base, uint32 limit) static void smp_do_config(void) { + struct mp_config_table *config; char *ptr; int i; - struct mp_config_table *mpc; #ifdef TRACE_SMP const char *cpu_family[] = { "", "", "", "", "Intel 486", "Intel Pentium", "Intel Pentium Pro", "Intel Pentium II" }; @@ -121,86 +117,83 @@ smp_do_config(void) */ gKernelArgs.num_cpus = 0; - mpc = mp_phys_to_virt(mp_flt_ptr->mpc); + config = sFloatingStruct->config_table; /* print out our new found configuration. */ - ptr = (char *) &(mpc->oem[0]); + ptr = (char *)&(config->oem[0]); TRACE(("smp: oem id: %c%c%c%c%c%c%c%c product id: " "%c%c%c%c%c%c%c%c%c%c%c%c\n", ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15], ptr[16], ptr[17], ptr[18], ptr[19])); TRACE(("smp: base table has %d entries, extended section %d bytes\n", - mpc->num_entries, mpc->ext_len)); + config->num_base_entries, config->ext_length)); - gKernelArgs.arch_args.apic_phys = (uint32)mpc->apic; + gKernelArgs.arch_args.apic_phys = (uint32)config->apic; - ptr = (char *)((uint32)mpc + sizeof(struct mp_config_table)); - for (i = 0; i < mpc->num_entries; i++) { + ptr = (char *)((uint32)config + sizeof(struct mp_config_table)); + for (i = 0; i < config->num_base_entries; i++) { switch (*ptr) { case MP_EXT_PE: { - struct mp_ext_pe *pe = (struct mp_ext_pe *)ptr; + struct mp_base_processor *processor = (struct mp_base_processor *)ptr; - gKernelArgs.arch_args.cpu_apic_id[gKernelArgs.num_cpus] = pe->apic_id; - gKernelArgs.arch_args.cpu_os_id[pe->apic_id] = gKernelArgs.num_cpus; - gKernelArgs.arch_args.cpu_apic_version[gKernelArgs.num_cpus] = pe->apic_version; + gKernelArgs.arch_args.cpu_apic_id[gKernelArgs.num_cpus] = processor->apic_id; + gKernelArgs.arch_args.cpu_os_id[processor->apic_id] = gKernelArgs.num_cpus; + gKernelArgs.arch_args.cpu_apic_version[gKernelArgs.num_cpus] = processor->apic_version; TRACE(("smp: cpu#%ld: %s, apic id %d, version %d%s\n", - gKernelArgs.num_cpus, cpu_family[(pe->signature & 0xf00) >> 8], - pe->apic_id, pe->apic_version, (pe->cpu_flags & 0x2) ? + gKernelArgs.num_cpus, cpu_family[(processor->signature & 0xf00) >> 8], + processor->apic_id, processor->apic_version, (processor->cpu_flags & 0x2) ? ", BSP" : "")); gKernelArgs.num_cpus++; - ptr += sizeof(struct mp_ext_pe); + ptr += sizeof(struct mp_base_processor); break; } case MP_EXT_BUS: { - struct mp_ext_bus *bus = (struct mp_ext_bus *)ptr; + struct mp_base_bus *bus = (struct mp_base_bus *)ptr; TRACE(("smp: bus %d: %c%c%c%c%c%c\n", bus->bus_id, bus->name[0], bus->name[1], bus->name[2], bus->name[3], bus->name[4], bus->name[5])); - ptr += sizeof(struct mp_ext_bus); + ptr += sizeof(struct mp_base_bus); break; } case MP_EXT_IO_APIC: { - struct mp_ext_ioapic *io = (struct mp_ext_ioapic *) ptr; + struct mp_base_ioapic *io = (struct mp_base_ioapic *) ptr; gKernelArgs.arch_args.ioapic_phys = (uint32)io->addr; TRACE(("smp: found io apic with apic id %d, version %d\n", io->ioapic_id, io->ioapic_version)); - ptr += sizeof(struct mp_ext_ioapic); + ptr += sizeof(struct mp_base_ioapic); break; } case MP_EXT_IO_INT: - { - struct mp_ext_interrupt *interrupt = (struct mp_ext_interrupt *)ptr; - dprintf("smp: I/O int: source bus %d, irq %d, dest apic %d, int %d, polarity %d, trigger mode %d\n", - interrupt->source_bus_id, interrupt->source_bus_irq, - interrupt->dest_apic_id, interrupt->dest_apic_int, - interrupt->polarity, interrupt->trigger_mode); - ptr += sizeof(struct mp_ext_interrupt); - break; - } case MP_EXT_LOCAL_INT: { - struct mp_ext_interrupt *interrupt = (struct mp_ext_interrupt *)ptr; - dprintf("smp: local int: source bus %d, irq %d, dest apic %d, int %d, polarity %d, trigger mode %d\n", - interrupt->source_bus_id, interrupt->source_bus_irq, - interrupt->dest_apic_id, interrupt->dest_apic_int, - interrupt->polarity, interrupt->trigger_mode); - ptr += sizeof(struct mp_ext_interrupt); + struct mp_base_interrupt *interrupt = (struct mp_base_interrupt *)ptr; + + dprintf("smp: %s int: type %d, source bus %d, irq %d, dest apic %d, int %d, polarity %d, trigger mode %d\n", + interrupt->type == MP_EXT_IO_INT ? "I/O" : "local", + interrupt->interrupt_type, interrupt->source_bus_id, + interrupt->source_bus_irq, interrupt->dest_apic_id, + interrupt->dest_apic_int, interrupt->polarity, + interrupt->trigger_mode); + ptr += sizeof(struct mp_base_interrupt); break; } } } + dprintf("smp: apic @ %p, i/o apic @ %p, total %ld processors detected\n", - (void *)gKernelArgs.arch_args.apic_phys, (void *)gKernelArgs.arch_args.ioapic_phys, gKernelArgs.num_cpus); + (void *)gKernelArgs.arch_args.apic_phys, + (void *)gKernelArgs.arch_args.ioapic_phys, + gKernelArgs.num_cpus); // this BIOS looks broken, because it didn't report any cpus (VMWare) if (gKernelArgs.num_cpus == 0) @@ -208,19 +201,6 @@ smp_do_config(void) } -struct smp_scan_spots_struct { - uint32 start; - uint32 stop; - uint32 len; -}; - -static struct smp_scan_spots_struct smp_scan_spots[] = { - { 0x9fc00, 0xa0000, 0xa0000 - 0x9fc00 }, - { 0xf0000, 0x100000, 0x100000 - 0xf0000 }, - { 0, 0, 0 } -}; - - static int smp_find_mp_config(void) { @@ -232,30 +212,29 @@ smp_find_mp_config(void) #endif // XXX for now, assume the memory is identity mapped by the 1st stage - for (i = 0; smp_scan_spots[i].len > 0; i++) { - mp_flt_ptr = (struct mp_flt_struct *)smp_probe(smp_scan_spots[i].start, + for (i = 0; smp_scan_spots[i].length > 0; i++) { + sFloatingStruct = (struct mp_floating_struct *)smp_probe(smp_scan_spots[i].start, smp_scan_spots[i].stop); - if (mp_flt_ptr != NULL) + if (sFloatingStruct != NULL) break; } - if (mp_flt_ptr != NULL) { - mp_mem_phys = smp_scan_spots[i].start; - mp_mem_virt = smp_scan_spots[i].start; + if (sFloatingStruct != NULL) { + TRACE(("smp_boot: intel mp version %s, %s", + (sFloatingStruct->spec_revision == 1) ? "1.1" : "1.4", + (sFloatingStruct->mp_feature_2 & 0x80) + ? "imcr and pic compatibility mode.\n" + : "virtual wire compatibility mode.\n")); - TRACE(("smp_boot: intel mp version %s, %s", (mp_flt_ptr->mp_rev == 1) ? "1.1" : - "1.4", (mp_flt_ptr->mp_feature_2 & 0x80) ? - "imcr and pic compatibility mode.\n" : "virtual wire compatibility mode.\n")); - - if (mp_flt_ptr->mpc == 0) { + if (sFloatingStruct->config_table == NULL) { // XXX need to implement #if 1 gKernelArgs.num_cpus = 1; return 1; #else /* this system conforms to one of the default configurations */ -// mp_num_def_config = mp_flt_ptr->mp_feature_1; - TRACE(("smp: standard configuration %d\n", mp_flt_ptr->mp_feature_1)); +// mp_num_def_config = sFloatingStruct->mp_feature_1; + TRACE(("smp: standard configuration %d\n", sFloatingStruct->mp_feature_1)); /* num_cpus = 2; gKernelArgs.cpu_apic_id[0] = 0; gKernelArgs.cpu_apic_id[1] = 1;