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>
This commit is contained in:
Kyösti Mälkki 2012-07-05 06:31:15 +03:00 committed by Sven Schnelle
parent 9a663f3e97
commit 63539bb9d7
2 changed files with 23 additions and 24 deletions

View File

@ -24,10 +24,9 @@
* We actually handling that case by noting which cpus startup * We actually handling that case by noting which cpus startup
* and not telling anyone about the ones that dont. * and not telling anyone about the ones that dont.
*/ */
static unsigned long get_valid_start_eip(unsigned long orig_start_eip)
{ /* Start-UP IPI vector must be 4kB aligned and below 1MB. */
return (unsigned long)orig_start_eip & 0xffff; // 16 bit to avoid 0xa0000 #define AP_SIPI_VECTOR 0x1000
}
#if CONFIG_HAVE_ACPI_RESUME #if CONFIG_HAVE_ACPI_RESUME
char *lowmem_backup; char *lowmem_backup;
@ -41,19 +40,14 @@ static void copy_secondary_start_to_1m_below(void)
{ {
extern char _secondary_start_end[]; extern char _secondary_start_end[];
unsigned long code_size; 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; code_size = (unsigned long)_secondary_start_end - (unsigned long)_secondary_start;
#if CONFIG_HAVE_ACPI_RESUME #if CONFIG_HAVE_ACPI_RESUME
/* need to save it for RAM resume */ /* need to save it for RAM resume */
lowmem_backup_size = code_size; lowmem_backup_size = code_size;
lowmem_backup = malloc(code_size); lowmem_backup = malloc(code_size);
lowmem_backup_ptr = (char *)start_eip; lowmem_backup_ptr = (char *)AP_SIPI_VECTOR;
if (lowmem_backup == NULL) if (lowmem_backup == NULL)
die("Out of backup memory\n"); 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); memcpy(lowmem_backup, lowmem_backup_ptr, lowmem_backup_size);
#endif #endif
/* copy the _secondary_start to the ram below 1M*/ /* 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; 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) static int lapic_start_cpus(struct bus *cpu_bus)
{ {
int timeout; int timeout;
unsigned long send_status, accept_status, start_eip; unsigned long send_status, accept_status;
int maxlvt; int maxlvt;
/* /*
@ -105,7 +99,6 @@ static int lapic_start_cpus(struct bus *cpu_bus)
} }
return 0; return 0;
} }
start_eip = get_valid_start_eip((unsigned long)_secondary_start);
maxlvt = 4; maxlvt = 4;
@ -125,7 +118,7 @@ static int lapic_start_cpus(struct bus *cpu_bus)
/* Boot on the stack */ /* Boot on the stack */
/* Kick the second */ /* Kick the second */
lapic_write_around(LAPIC_ICR, LAPIC_INT_ASSERT | LAPIC_DM_STARTUP | LAPIC_DEST_ALLBUT 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. * Give the other CPU some time to accept the IPI.

View File

@ -2,8 +2,7 @@
#include <cpu/x86/lapic_def.h> #include <cpu/x86/lapic_def.h>
.text .text
.globl _secondary_start, _secondary_start_end, cpucount .globl _secondary_start, _secondary_start_end, cpucount, ap_protected_start
.balign 4096
_secondary_start: _secondary_start:
.code16 .code16
cli cli
@ -25,9 +24,21 @@ _secondary_start:
orl $0x60000001, %eax /* CD, NW, PE = 1 */ orl $0x60000001, %eax /* CD, NW, PE = 1 */
movl %eax, %cr0 movl %eax, %cr0
ljmpl $0x10, $1f ljmpl $0x10, $__ap_protected_start
1:
gdtaddr:
.word gdt_limit /* the table limit */
.long gdt /* we know the offset */
_secondary_start_end:
ap_protected_start:
.code32 .code32
lgdt gdtaddr
ljmpl $0x10, $__ap_protected_start
__ap_protected_start:
movw $0x18, %ax movw $0x18, %ax
movw %ax, %ds movw %ax, %ds
movw %ax, %es movw %ax, %es
@ -57,9 +68,4 @@ _secondary_start:
cpucount: cpucount:
.long 1 .long 1
gdtaddr:
.word gdt_limit /* the table limit */
.long gdt /* we know the offset */
_secondary_start_end:
.code32 .code32