Kyösti Mälkki (kyosti.malkki@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1165
-gerrit
commit 1a6da1cbe4efdfe3402496c81ea48c30b970b001 Author: Kyösti Mälkki kyosti.malkki@gmail.com Date: Tue Jul 3 11:56:19 2012 +0300
Only copy real-mode section of SIPI vector
The SIPI vector copy can use a static location below 1MB, aligned to 4kB. Jump out of the copy once in protected mode.
Fix the CPU index parameter passed to secondary_cpu_init().
Change-Id: I6299aa3448270663941cf2c4113efee74bcc7993 Signed-off-by: Kyösti Mälkki kyosti.malkki@gmail.com --- src/cpu/x86/lapic/lapic_cpu_init.c | 23 ++++++++--------------- src/cpu/x86/lapic/secondary.S | 26 ++++++++++++++++---------- 2 files changed, 24 insertions(+), 25 deletions(-)
diff --git a/src/cpu/x86/lapic/lapic_cpu_init.c b/src/cpu/x86/lapic/lapic_cpu_init.c index 061d3d3..b6dc560 100644 --- a/src/cpu/x86/lapic/lapic_cpu_init.c +++ b/src/cpu/x86/lapic/lapic_cpu_init.c @@ -24,10 +24,9 @@ * We actually handling that case by noting which cpus startup * and not telling anyone about the ones that dont. */ -static unsigned long get_valid_start_eip(unsigned long orig_start_eip) -{ - return (unsigned long)orig_start_eip & 0xffff; // 16 bit to avoid 0xa0000 -} + +/* Start-UP IPI vector must be 4kB aligned and below 1MB. */ +#define AP_SIPI_VECTOR 0x1000
#if CONFIG_HAVE_ACPI_RESUME char *lowmem_backup; @@ -41,19 +40,14 @@ static void copy_secondary_start_to_1m_below(void) { extern char _secondary_start_end[]; unsigned long code_size; - unsigned long start_eip;
- /* _secondary_start need to be masked 20 above bit, because 16 bit code in secondary.S - Also We need to copy the _secondary_start to the below 1M region - */ - start_eip = get_valid_start_eip((unsigned long)_secondary_start); code_size = (unsigned long)_secondary_start_end - (unsigned long)_secondary_start;
#if CONFIG_HAVE_ACPI_RESUME /* need to save it for RAM resume */ lowmem_backup_size = code_size; lowmem_backup = malloc(code_size); - lowmem_backup_ptr = (char *)start_eip; + lowmem_backup_ptr = (char *)AP_SIPI_VECTOR;
if (lowmem_backup == NULL) die("Out of backup memory\n"); @@ -61,9 +55,9 @@ static void copy_secondary_start_to_1m_below(void) memcpy(lowmem_backup, lowmem_backup_ptr, lowmem_backup_size); #endif /* copy the _secondary_start to the ram below 1M*/ - memcpy((unsigned char *)start_eip, (unsigned char *)_secondary_start, code_size); + memcpy((unsigned char *)AP_SIPI_VECTOR, (unsigned char *)_secondary_start, code_size);
- printk(BIOS_DEBUG, "start_eip=0x%08lx, offset=0x%08lx, code_size=0x%08lx\n", start_eip, ((unsigned long)_secondary_start - start_eip), code_size); + printk(BIOS_DEBUG, "start_eip=0x%08lx, code_size=0x%08lx\n", (long unsigned int)AP_SIPI_VECTOR, code_size); }
static struct bus *current_cpu_bus; @@ -71,7 +65,7 @@ static struct bus *current_cpu_bus; static int lapic_start_cpus(struct bus *cpu_bus) { int timeout; - unsigned long send_status, accept_status, start_eip; + unsigned long send_status, accept_status; int maxlvt;
/* @@ -105,7 +99,6 @@ static int lapic_start_cpus(struct bus *cpu_bus) } return 0; } - start_eip = get_valid_start_eip((unsigned long)_secondary_start);
maxlvt = 4;
@@ -125,7 +118,7 @@ static int lapic_start_cpus(struct bus *cpu_bus) /* Boot on the stack */ /* Kick the second */ lapic_write_around(LAPIC_ICR, LAPIC_INT_ASSERT | LAPIC_DM_STARTUP | LAPIC_DEST_ALLBUT - | (start_eip >> 12)); + | ((AP_SIPI_VECTOR >> 12) & 0xff));
/* * Give the other CPU some time to accept the IPI. diff --git a/src/cpu/x86/lapic/secondary.S b/src/cpu/x86/lapic/secondary.S index 67e44c4..15bae5e 100644 --- a/src/cpu/x86/lapic/secondary.S +++ b/src/cpu/x86/lapic/secondary.S @@ -2,8 +2,7 @@ #include <cpu/x86/lapic_def.h>
.text - .globl _secondary_start, _secondary_start_end, cpucount - .balign 4096 + .globl _secondary_start, _secondary_start_end, cpucount, ap_protected_start _secondary_start: .code16 cli @@ -25,9 +24,21 @@ _secondary_start: orl $0x60000001, %eax /* CD, NW, PE = 1 */ movl %eax, %cr0
- ljmpl $0x10, $1f -1: + ljmpl $0x10, $__ap_protected_start + +gdtaddr: + .word gdt_limit /* the table limit */ + .long gdt /* we know the offset */ + +_secondary_start_end: + +ap_protected_start: .code32 + lgdt gdtaddr + ljmpl $0x10, $__ap_protected_start + +__ap_protected_start: + movw $0x18, %ax movw %ax, %ds movw %ax, %es @@ -41,8 +52,8 @@ _secondary_start: /* increment our cpu index */ movl $1, %eax lock xadd %eax, cpucount - incl %eax movl %eax, %ecx + incl %eax
/* assign stack for this specific cpu */ mov _stack, %esp @@ -57,9 +68,4 @@ _secondary_start:
cpucount: .long 1 -gdtaddr: - .word gdt_limit /* the table limit */ - .long gdt /* we know the offset */ - -_secondary_start_end: .code32