diff options
author | Damien Zammit <damien@zamaudio.com> | 2022-10-01 10:51:37 +1000 |
---|---|---|
committer | Damien Zammit <damien@zamaudio.com> | 2022-10-01 12:42:40 +1000 |
commit | f724c2b18c69d42a02dd3a0dccec8ae277f7d191 (patch) | |
tree | dc0e7627eb60499020074f749768aa4ed390d836 | |
parent | 1195a87bf344f0c990df1749bc79b3ba0e2fc02e (diff) |
Upstreaming AlmuHS' SMP work
-rw-r--r-- | i386/Makefrag.am | 6 | ||||
-rw-r--r-- | i386/i386/apic.c | 41 | ||||
-rw-r--r-- | i386/i386/apic.h | 97 | ||||
-rw-r--r-- | i386/i386/cpu_number.h | 3 | ||||
-rw-r--r-- | i386/i386/fpu.c | 4 | ||||
-rw-r--r-- | i386/i386/mp_desc.c | 289 | ||||
-rw-r--r-- | i386/i386/smp.c | 33 | ||||
-rw-r--r-- | i386/i386/smp.h | 1 | ||||
-rw-r--r-- | i386/i386/trap.c | 1 | ||||
-rw-r--r-- | i386/i386at/acpi_parse_apic.c | 3 | ||||
-rw-r--r-- | i386/i386at/acpi_parse_apic.h | 1 | ||||
-rw-r--r-- | kern/processor.c | 2 |
12 files changed, 444 insertions, 37 deletions
diff --git a/i386/Makefrag.am b/i386/Makefrag.am index 8d6ef8cd..b74aad35 100644 --- a/i386/Makefrag.am +++ b/i386/Makefrag.am @@ -30,6 +30,8 @@ if HOST_ix86 # libkernel_a_SOURCES += \ + i386/i386at/acpi_parse_apic.h \ + i386/i386at/acpi_parse_apic.c \ i386/i386at/autoconf.c \ i386/i386at/autoconf.h \ i386/i386at/biosmem.c \ @@ -94,7 +96,9 @@ libkernel_a_SOURCES += \ i386/i386/ast_types.h \ i386/i386/cpu.h \ i386/i386/cpu_number.h \ + i386/i386/cpu_number.c \ i386/i386/cswitch.S \ + i386/i386/cpuboot.S \ i386/i386/db_disasm.c \ i386/i386/db_interface.c \ i386/i386/db_interface.h \ @@ -158,6 +162,8 @@ libkernel_a_SOURCES += \ i386/i386/user_ldt.h \ i386/i386/vm_param.h \ i386/i386/xpr.h \ + i386/i386/smp.h \ + i386/i386/smp.c \ i386/intel/pmap.c \ i386/intel/pmap.h \ i386/intel/read_fault.c \ diff --git a/i386/i386/apic.c b/i386/i386/apic.c index 2e0c1776..35314f4b 100644 --- a/i386/i386/apic.c +++ b/i386/i386/apic.c @@ -1,5 +1,5 @@ /* apic.c - APIC controller management for Mach. - Copyright (C) 2020 Free Software Foundation, Inc. + Copyright (C) 2021 Free Software Foundation, Inc. Written by Almudena Garcia Jurado-Centurion This file is part of GNU Mach. @@ -121,6 +121,23 @@ apic_get_cpu_apic_id(int kernel_id) return apic_data.cpu_lapic_list[kernel_id]; } + +/* + * apic_get_cpu_kernel_id: returns the kernel_id of a cpu. + * Receives as input the APIC ID of a CPU. + */ +uint16_t +apic_get_cpu_kernel_id(int apic_id) +{ + int i = 0; + while(apic_data.cpu_lapic_list[i] != apic_id && i < apic_data.ncpus) i++; + + int kernel_id = -1; + if(i < apic_data.ncpus) kernel_id = i; + + return kernel_id; +} + /* apic_get_lapic: returns a reference to the common memory address for Local APIC. */ volatile ApicLocalUnit* apic_get_lapic(void) @@ -234,3 +251,25 @@ void apic_print_info(void) } } } + +void apic_send_ipi(unsigned dest_shorthand, unsigned deliv_mode, unsigned dest_mode, unsigned level, unsigned trig_mode, unsigned vector, unsigned dest_id) +{ + IcrLReg icrl_values; + IcrHReg icrh_values; + + icrl_values.destination_shorthand = dest_shorthand; + icrl_values.delivery_mode = deliv_mode; + icrl_values.destination_mode = dest_mode; + icrl_values.level = level; + icrl_values.trigger_mode = trig_mode; + icrl_values.vector = vector; + icrh_values.destination_field = dest_id; + + //printf("ICR Low: %08x\n", icrl_values.r); + //printf("ICR High: %08x\n", icrh_values.r); + + lapic->icr_high = icrh_values; + lapic->icr_low = icrl_values; + + while(lapic->icr_low.delivery_status == SEND_PENDING); +} diff --git a/i386/i386/apic.h b/i386/i386/apic.h index add1b8cf..b0218b84 100644 --- a/i386/i386/apic.h +++ b/i386/i386/apic.h @@ -61,10 +61,100 @@ union ioapic_route_entry_union { struct ioapic_route_entry both; }; + +/* Grateful to trasterlabs for this snippet */ + +typedef union u_icr_low +{ + uint32_t value[4]; + struct + { + uint32_t r; // FEE0 0300H - 4 bytes + unsigned :32; // FEE0 0304H + unsigned :32; // FEE0 0308H + unsigned :32; // FEE0 030CH + }; + struct + { + unsigned vector: 8; /* Vector of interrupt. Lowest 8 bits of routine address */ + unsigned delivery_mode : 3; + unsigned destination_mode: 1; + unsigned delivery_status: 1; + unsigned :1; + unsigned level: 1; + unsigned trigger_mode: 1; + unsigned :2; + unsigned destination_shorthand: 2; + unsigned :12; + }; + +} IcrLReg; + +typedef union u_icr_high +{ + uint32_t value[4]; + struct + { + uint32_t r; // FEE0 0310H - 4 bytes + unsigned :32; // FEE0 0314H + unsigned :32; // FEE0 0318H + unsigned :32; // FEE0 031CH + }; + struct + { + unsigned :24; // FEE0 0310H - 4 bytes + unsigned destination_field :8; /* APIC ID (in physical mode) or MDA (in logical) of destination processor */ + }; +} IcrHReg; + + +typedef enum e_icr_dest_shorthand +{ + NO_SHORTHAND = 0, + SELF = 1, + ALL_INCLUDING_SELF = 2, + ALL_EXCLUDING_SELF = 3 +} icr_dest_shorthand; + +typedef enum e_icr_deliv_mode +{ + FIXED = 0, + LOWEST_PRIORITY = 1, + SMI = 2, + NMI = 4, + INIT = 5, + STARTUP = 6, +} icr_deliv_mode; + +typedef enum e_icr_dest_mode +{ + PHYSICAL = 0, + LOGICAL = 1 +} icr_dest_mode; + +typedef enum e_icr_deliv_status +{ + IDLE = 0, + SEND_PENDING = 1 +} icr_deliv_status; + +typedef enum e_icr_level +{ + DE_ASSERT = 0, + ASSERT = 1 +} icr_level; + +typedef enum e_irc_trigger_mode +{ + EDGE = 0, + LEVEL = 1 +} irc_trigger_mode; + + typedef struct ApicLocalUnit { ApicReg reserved0; /* 0x000 */ ApicReg reserved1; /* 0x010 */ - ApicReg apic_id; /* 0x020 */ + ApicReg apic_id; /* 0x020. Hardware ID of current processor */ ApicReg version; /* 0x030 */ ApicReg reserved4; /* 0x040 */ ApicReg reserved5; /* 0x050 */ @@ -84,8 +174,8 @@ typedef struct ApicLocalUnit { ApicReg error_status; /* 0x280 */ ApicReg reserved28[6]; /* 0x290 */ ApicReg lvt_cmci; /* 0x2f0 */ - ApicReg icr_low; /* 0x300 */ - ApicReg icr_high; /* 0x310 */ + IcrLReg icr_low; /* 0x300. Store the information to send an IPI (Inter-processor Interrupt) */ + IcrHReg icr_high; /* 0x310. Store the IPI destination */ ApicReg lvt_timer; /* 0x320 */ ApicReg lvt_thermal; /* 0x330 */ ApicReg lvt_performance_monitor; /* 0x340 */ @@ -138,6 +228,7 @@ void apic_add_cpu(uint16_t apic_id); void apic_lapic_init(ApicLocalUnit* lapic_ptr); void apic_add_ioapic(struct IoApicData); void apic_add_irq_override(struct IrqOverrideData irq_over); +void apic_send_ipi(unsigned dest_shorthand, unsigned deliv_mode, unsigned dest_mode, unsigned level, unsigned trig_mode, unsigned vector, unsigned dest_id); IrqOverrideData *acpi_get_irq_override(uint8_t gsi); uint16_t apic_get_cpu_apic_id(int kernel_id); volatile ApicLocalUnit* apic_get_lapic(void); diff --git a/i386/i386/cpu_number.h b/i386/i386/cpu_number.h index 9aef6370..a550979b 100644 --- a/i386/i386/cpu_number.h +++ b/i386/i386/cpu_number.h @@ -42,7 +42,7 @@ /* XXX For now */ #define CPU_NUMBER(reg) movl $0,reg -#define cpu_number() 0 +//#define cpu_number() 0 #else /* NCPUS == 1 */ @@ -53,6 +53,7 @@ #ifndef __ASSEMBLER__ #include "kern/cpu_number.h" +int cpu_number(); #endif #endif /* _I386_CPU_NUMBER_H_ */ diff --git a/i386/i386/fpu.c b/i386/i386/fpu.c index e184ca72..e57227d5 100644 --- a/i386/i386/fpu.c +++ b/i386/i386/fpu.c @@ -183,7 +183,7 @@ init_fpu(void) panic("CPU-provided xstate size %d " "is smaller than our minimum %d!\n", fp_xsave_size, - (int) sizeof(struct i386_fpsave_state)); + sizeof(struct i386_fpsave_state)); fp_save_kind = FP_XSAVES; } else { @@ -195,7 +195,7 @@ init_fpu(void) panic("CPU-provided xstate size %d " "is smaller than our minimum %d!\n", fp_xsave_size, - (int) sizeof(struct i386_fpsave_state)); + sizeof(struct i386_fpsave_state)); if (eax & CPU_FEATURE_XSAVEOPT) fp_save_kind = FP_XSAVEOPT; diff --git a/i386/i386/mp_desc.c b/i386/i386/mp_desc.c index 1e9ea0fc..f0d810f2 100644 --- a/i386/i386/mp_desc.c +++ b/i386/i386/mp_desc.c @@ -26,23 +26,32 @@ #if NCPUS > 1 -#include <string.h> - #include <kern/cpu_number.h> #include <kern/debug.h> #include <kern/printf.h> +#include <kern/smp.h> +#include <kern/kmutex.h> #include <mach/machine.h> #include <mach/xen.h> #include <vm/vm_kern.h> #include <i386/mp_desc.h> #include <i386/lock.h> +#include <i386/apic.h> +#include <i386/locore.h> +#include <i386/gdt.h> +#include <i386/cpu.h> + #include <i386at/model_dep.h> #include <machine/ktss.h> +#include <machine/smp.h> #include <machine/tss.h> #include <machine/io_perm.h> #include <machine/vm_param.h> +#include <i386at/acpi_parse_apic.h> +#include <string.h> + /* * The i386 needs an interrupt stack to keep the PCB stack from being * overrun by interrupts. All interrupt stacks MUST lie at lower addresses @@ -57,9 +66,16 @@ vm_offset_t int_stack_top[NCPUS]; vm_offset_t int_stack_base[NCPUS]; /* + * Addresses of bottom and top of cpu main stacks. + */ +vm_offset_t cpu_stack[NCPUS]; +vm_offset_t _cpu_stack_top[NCPUS]; + +/* * Barrier address. */ vm_offset_t int_stack_high; +vm_offset_t cpu_stack_high; /* * First cpu`s interrupt stack. @@ -68,6 +84,22 @@ extern char _intstack[]; /* bottom */ extern char _eintstack[]; /* top */ /* + * First cpu`s stack. + */ + +char _cpustack[]; /* bottom */ +char _ecpustack[]; /* top */ + + +extern void *apboot, *apbootend; +extern volatile ApicLocalUnit* lapic; +//extern unsigned stop; + +#define AP_BOOT_ADDR (0x7000) +#define STACK_SIZE (4096 * 2) +//#define STACK_SIZE (2*I386_PGBYTES) + +/* * Multiprocessor i386/i486 systems use a separate copy of the * GDT, IDT, LDT, and kernel TSS per processor. The first three * are separate to avoid lock contention: the i386 uses locked @@ -98,6 +130,8 @@ extern struct real_gate idt[IDTSZ]; extern struct real_descriptor gdt[GDTSZ]; extern struct real_descriptor ldt[LDTSZ]; +static struct kmutex mp_cpu_boot_lock; + /* * Allocate and initialize the per-processor descriptor tables. */ @@ -107,6 +141,8 @@ mp_desc_init(int mycpu) { struct mp_desc_table *mpt; + const int master_cpu = 0; + if (mycpu == master_cpu) { /* * Master CPU uses the tables built at boot time. @@ -167,9 +203,63 @@ mp_desc_init(int mycpu) } } -kern_return_t intel_startCPU(int slot_num) +kern_return_t intel_startCPU(int cpu) { - printf("TODO: intel_startCPU\n"); + /*TODO: Get local APIC from cpu*/ + unsigned apic_id = apic_get_cpu_apic_id(cpu); + unsigned long eFlagsRegister; + + kmutex_init(&mp_cpu_boot_lock); + printf("Trying to enable: %d\n", apic_id); + + /* Serialize use of the slave boot stack, etc. */ + kmutex_lock(&mp_cpu_boot_lock, FALSE); + + cpu_intr_save(&eFlagsRegister); + printf("cpu_number: %d\n", cpu_number()); + if (cpu == cpu_number()) + { + cpu_intr_restore(eFlagsRegister); + kmutex_unlock(&mp_cpu_boot_lock); + return KERN_SUCCESS; + } + + /* + * Perform the processor startup sequence with all running + * processors rendezvous'ed. This is required during periods when + * the cache-disable bit is set for MTRR/PAT initialization. + */ + smp_startup_cpu(apic_id, AP_BOOT_ADDR); + + cpu_intr_restore(eFlagsRegister); + kmutex_unlock(&mp_cpu_boot_lock); + + int j = 0; + for(int i = 0; i < 10000000; i++){ + j = i; + } + + /* + * Initialize (or re-initialize) the descriptor tables for this cpu. + * Propagate processor mode to slave. + */ + // + + while(!machine_slot[cpu].running); + printf("cpu %d running\n", cpu); + + mp_desc_init(cpu); + if(!machine_slot[cpu].running) + { + printf("Failed to start CPU %02d, rebooting...\n", cpu); + //halt_cpu(); + return KERN_SUCCESS; + } + else + { + printf("Started cpu %d (lapic id %08x)\n", cpu, apic_id); + return KERN_SUCCESS; + } } /* @@ -183,27 +273,23 @@ interrupt_stack_alloc(void) int cpu_count; vm_offset_t stack_start; - /* - * Count the number of CPUs. - */ - cpu_count = 0; - for (i = 0; i < NCPUS; i++) - if (machine_slot[i].is_cpu) - cpu_count++; - + cpu_count = smp_get_numcpus(); + /* * Allocate an interrupt stack for each CPU except for * the master CPU (which uses the bootstrap stack) */ - if (!init_alloc_aligned(INTSTACK_SIZE*(cpu_count-1), &stack_start)) - panic("not enough memory for interrupt stacks"); - stack_start = phystokv(stack_start); - + if(cpu_count > 1){ + if (!init_alloc_aligned(INTSTACK_SIZE*(cpu_count-1), &stack_start)) + panic("not enough memory for interrupt stacks"); + stack_start = phystokv(stack_start); + } /* * Set up pointers to the top of the interrupt stack. */ - for (i = 0; i < NCPUS; i++) { - if (i == master_cpu) { + + for (i = master_cpu; i < cpu_count; i++) { + if (i == 0) { interrupt_stack[i] = (vm_offset_t) _intstack; int_stack_top[i] = (vm_offset_t) _eintstack; } @@ -219,7 +305,7 @@ interrupt_stack_alloc(void) * Set up the barrier address. All thread stacks MUST * be above this address. */ - int_stack_high = stack_start; + if(cpu_count > 1) int_stack_high = stack_start; } /* XXX should be adjusted per CPU speed */ @@ -257,22 +343,171 @@ interrupt_processor(int cpu) printf("interrupt cpu %d\n",cpu); } + +int +cpu_setup() +{ + + int i = 0; + int ncpus = apic_get_numcpus(); + + //unsigned apic_id = apic_get_current_cpu(); + unsigned apic_id = (((ApicLocalUnit*)phystokv(lapic_addr))->apic_id.r >> 24) & 0xff; + printf("Starting cpu with APIC ID %u setup\n", apic_id); + + printf("ncpus = %d\n", ncpus); + + int cpu = apic_get_cpu_kernel_id(apic_id); + machine_slot[cpu].running = TRUE; + + printf("machine slot (%d) running: %d\n",i, machine_slot[i].running); + /*TODO: Move this code to a separate function*/ + + /* Initialize machine_slot fields with the cpu data */ + machine_slot[cpu].cpu_subtype = CPU_SUBTYPE_AT386; + + int cpu_type = discover_x86_cpu_type (); + + switch (cpu_type) + { + default: + printf("warning: unknown cpu type %d, assuming i386\n", cpu_type); + + case 3: + machine_slot[cpu].cpu_type = CPU_TYPE_I386; + break; + + case 4: + machine_slot[cpu].cpu_type = CPU_TYPE_I486; + break; + + case 5: + machine_slot[cpu].cpu_type = CPU_TYPE_PENTIUM; + break; + case 6: + case 15: + machine_slot[cpu].cpu_type = CPU_TYPE_PENTIUMPRO; + break; + } + + printf("Configuring GDT and IDT\n"); + + /* + * Initialize and activate the real i386 protected-mode structures. + */ + gdt_init(); + printf("GDT configured\n"); + + idt_init(); + printf("IDT configured\n"); + + ldt_init(); + printf("LDT configured\n"); + + ktss_init(); + printf("KTSS configured\n"); + printf("Configured GDT and IDT\n"); + + machine_slot[i].running = TRUE; + + printf("started cpu %d\n", i); + + /* Add cpu to the kernel */ + //slave_main(); + + return 0; +} + +int +cpu_ap_main() +{ + //unsigned lapic_addr = apic_madt->lapic_addr; + unsigned cpu = (((ApicLocalUnit*)phystokv(lapic_addr))->apic_id.r >> 24) & 0xff; + printf("Enabling cpu %d\n", cpu); + + if(cpu_setup()) return -1; + return 0; +} + kern_return_t cpu_start(int cpu) { - if (machine_slot[cpu].running) - return KERN_FAILURE; + if (machine_slot[cpu].running == TRUE) + return KERN_FAILURE; - return intel_startCPU(cpu); + return intel_startCPU(cpu); } + + void -start_other_cpus(void) +cpus_stack_alloc(void) { - int cpu; - for (cpu = 0; cpu < NCPUS; cpu++) - if (cpu != cpu_number()) - cpu_start(cpu); + vm_offset_t stack_start; + int ncpus = smp_get_numcpus(); + + + if(ncpus > 1){ + if (!init_alloc_aligned(STACK_SIZE*(ncpus-1), &stack_start)) + panic("not enough memory for cpu stacks"); + stack_start = phystokv(stack_start); + } + + + for (int i = 1; i < ncpus; i++) + { + if (i == master_cpu) + { + cpu_stack[i] = (vm_offset_t) _cpustack; + _cpu_stack_top[i] = (vm_offset_t) _cpustack + STACK_SIZE; + } + else + { + cpu_stack[i] = stack_start; + _cpu_stack_top[i] = stack_start + STACK_SIZE; + + stack_start += STACK_SIZE; + } + } + + /* + * Set up the barrier address. All thread stacks MUST + * be above this address. + */ + if(ncpus > 1) cpu_stack_high = stack_start; +} + +extern vm_offset_t* *stack_ptr; + +void +start_other_cpus(void) +{ + int ncpus = smp_get_numcpus(); + + machine_slot[0].running = TRUE; + + //Copy cpus initialization assembly routine + memcpy((void*)phystokv(AP_BOOT_ADDR), (void*) &apboot, (uint32_t)&apbootend - (uint32_t)&apboot); + + //Reserve memory for interrupt stacks + interrupt_stack_alloc(); + + //Reserve memory for cpu stack + cpus_stack_alloc(); + printf("cpu stacks reserved\n"); + + printf("starting cpus\n"); + unsigned cpu; + for (cpu = 1; cpu < ncpus; cpu++){ + //Initialize stack pointer for current cpu + *stack_ptr = (vm_offset_t*) cpu_stack[cpu]; + + machine_slot[cpu].running = FALSE; + + //Start cpu + printf("starting cpu %d\n", cpu); + cpu_start(cpu); + } } #endif /* NCPUS > 1 */ diff --git a/i386/i386/smp.c b/i386/i386/smp.c index d7523a73..be0bb7b7 100644 --- a/i386/i386/smp.c +++ b/i386/i386/smp.c @@ -20,9 +20,13 @@ #include <i386/i386/apic.h> #include <i386/i386/smp.h> +#include <i386/i386at/acpi_parse_apic.h> +#include <kern/printf.h> +#include <mach/machine.h> #include <kern/smp.h> +#define AP_BOOT_ADDR (0x7000) /* * smp_data_init: initialize smp_data structure @@ -33,8 +37,37 @@ static void smp_data_init(void) { uint8_t numcpus = apic_get_numcpus(); smp_set_numcpus(numcpus); + + for(int i = 0; i < numcpus; i++){ + machine_slot[i].is_cpu = TRUE; + } + } +void smp_startup_cpu(unsigned apic_id, unsigned vector) +{ + printf("Sending IPI to APIC ID %u\n", apic_id); + + /* First INIT IPI */ + apic_send_ipi(NO_SHORTHAND, INIT, PHYSICAL, ASSERT, EDGE, 0 , apic_id); + + for(int i = 0; i < 10000000; i++); + + /* Second INIT IPI */ + apic_send_ipi(NO_SHORTHAND, INIT, PHYSICAL, DE_ASSERT, LEVEL, 0 , apic_id); + + for(int i = 0; i < 10000000; i++); + + /* First StartUp IPI */ + apic_send_ipi(NO_SHORTHAND, STARTUP, PHYSICAL, ASSERT, EDGE, vector >> 12, apic_id); + + for(int i = 0; i < 10000000; i++); + + /* Second StartUp IPI */ + //apic_send_ipi(NO_SHORTHAND, STARTUP, PHYSICAL, ASSERT, LEVEL, vector >> 12, apic_id); +} + + /* * smp_init: initialize the SMP support, starting the cpus searching * and enumeration. diff --git a/i386/i386/smp.h b/i386/i386/smp.h index b36ead08..43212aaf 100644 --- a/i386/i386/smp.h +++ b/i386/i386/smp.h @@ -19,3 +19,4 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ int smp_init(void); +void smp_startup_cpu(unsigned apic_id, unsigned vector); diff --git a/i386/i386/trap.c b/i386/i386/trap.c index eef9432f..23cb9f17 100644 --- a/i386/i386/trap.c +++ b/i386/i386/trap.c @@ -493,7 +493,6 @@ int user_trap(struct i386_saved_state *regs) opcode = inst_fetch(regs->eip, regs->cs); for (i = 0; i < 4; i++) addr[i] = inst_fetch(regs->eip+i+1, regs->cs); - (void) addr; for (i = 0; i < 2; i++) seg[i] = inst_fetch(regs->eip+i+5, regs->cs); if (opcode == 0x9a && seg[0] == 0x7 && seg[1] == 0) { diff --git a/i386/i386at/acpi_parse_apic.c b/i386/i386at/acpi_parse_apic.c index 3cf6f042..344c42bb 100644 --- a/i386/i386at/acpi_parse_apic.c +++ b/i386/i386at/acpi_parse_apic.c @@ -33,6 +33,7 @@ #include <vm/vm_kern.h> static struct acpi_apic *apic_madt = NULL; +unsigned lapic_addr; /* * acpi_print_info: shows by screen the ACPI's rsdp and rsdt virtual address @@ -281,7 +282,6 @@ acpi_get_apic(struct acpi_rsdt *rsdt, int acpi_rsdt_n) for (int i = 0; i < acpi_rsdt_n; i++) { descr_header = (struct acpi_dhdr*) kmem_map_aligned_table(rsdt->entry[i], sizeof(struct acpi_dhdr), VM_PROT_READ); - /* Check if the entry contains an APIC. */ check_signature = acpi_check_signature(descr_header->signature, ACPI_APIC_SIG, 4*sizeof(uint8_t)); @@ -459,6 +459,7 @@ acpi_apic_setup(struct acpi_apic *apic) return ACPI_BAD_CHECKSUM; /* map common lapic address */ + lapic_addr = apic->lapic_addr; lapic_unit = kmem_map_aligned_table(apic->lapic_addr, sizeof(ApicLocalUnit), VM_PROT_READ | VM_PROT_WRITE); diff --git a/i386/i386at/acpi_parse_apic.h b/i386/i386at/acpi_parse_apic.h index 97a59a2e..5a5cb14d 100644 --- a/i386/i386at/acpi_parse_apic.h +++ b/i386/i386at/acpi_parse_apic.h @@ -159,5 +159,6 @@ struct acpi_apic_irq_override { int acpi_apic_init(void); void acpi_print_info(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt, int acpi_rsdt_n); +extern unsigned lapic_addr; #endif /* __ACPI_H__ */ diff --git a/kern/processor.c b/kern/processor.c index ec56952e..f92ce6ae 100644 --- a/kern/processor.c +++ b/kern/processor.c @@ -57,7 +57,7 @@ struct kmem_cache pset_cache; /* * Exported variables. */ -int master_cpu; +int master_cpu = 0; struct processor_set default_pset; struct processor processor_array[NCPUS]; |