summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyösti Mälkki <kyosti.malkki@gmail.com>2012-07-05 06:31:15 +0300
committerSven Schnelle <svens@stackframe.org>2012-07-05 22:49:31 +0200
commit63539bb9d7fe9ae55a364cadfcbd79ecb98a9412 (patch)
tree09fd72ad7a5ba7ac47ec84300c47f275c3e67dd1
parent9a663f3e97fff9cfc3eb9ed2c6e843a68bcabf90 (diff)
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. Change-Id: I6299aa3448270663941cf2c4113efee74bcc7993 Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: http://review.coreboot.org/1165 Tested-by: build bot (Jenkins) Reviewed-by: Sven Schnelle <svens@stackframe.org>
-rw-r--r--src/cpu/x86/lapic/lapic_cpu_init.c23
-rw-r--r--src/cpu/x86/lapic/secondary.S24
2 files changed, 23 insertions, 24 deletions
diff --git a/src/cpu/x86/lapic/lapic_cpu_init.c b/src/cpu/x86/lapic/lapic_cpu_init.c
index 061d3d3c41..b6dc560308 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 2ad70296ea..15bae5e5db 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
@@ -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