summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2022-10-01 10:51:37 +1000
committerDamien Zammit <damien@zamaudio.com>2022-10-01 12:42:40 +1000
commitf724c2b18c69d42a02dd3a0dccec8ae277f7d191 (patch)
treedc0e7627eb60499020074f749768aa4ed390d836
parent1195a87bf344f0c990df1749bc79b3ba0e2fc02e (diff)
Upstreaming AlmuHS' SMP work
-rw-r--r--i386/Makefrag.am6
-rw-r--r--i386/i386/apic.c41
-rw-r--r--i386/i386/apic.h97
-rw-r--r--i386/i386/cpu_number.h3
-rw-r--r--i386/i386/fpu.c4
-rw-r--r--i386/i386/mp_desc.c289
-rw-r--r--i386/i386/smp.c33
-rw-r--r--i386/i386/smp.h1
-rw-r--r--i386/i386/trap.c1
-rw-r--r--i386/i386at/acpi_parse_apic.c3
-rw-r--r--i386/i386at/acpi_parse_apic.h1
-rw-r--r--kern/processor.c2
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];