diff options
author | Kyösti Mälkki <kyosti.malkki@gmail.com> | 2012-03-05 09:25:12 +0200 |
---|---|---|
committer | Patrick Georgi <patrick@georgi-clan.de> | 2012-03-16 19:34:14 +0100 |
commit | 7863015c3eabe94c360ff893723f48af23a47a33 (patch) | |
tree | 90a86cfbee75d7cd3cb51c11936c79d30786d161 /src/cpu/x86/16bit/entry16.inc | |
parent | 5750ed253a6ed45e574a8855a7b7b1abe16eae88 (diff) |
Fix address of IDT in real-mode entry
In a case of CS & 0x0fff != 0x0, lidt memory operand does not point
to nullidt, this can raise an exception and shutdown the CPU.
When an AP CPU receives 8-bit Start-Up IPI vector yzH, it starts
execute at physical address 000yz000H. Seems this translates to
either yz00:0000 or y000:z000 (CS:IP), depending of the CPU model.
With the change entry16.inc is relocatable as the commentary suggests
and can be used as ap_sipi_vector on SMP systems.
Change-Id: I885a2888179700ba6e2b11d4f2d6a64ddea4c2dc
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: http://review.coreboot.org/707
Tested-by: build bot (Jenkins)
Reviewed-by: Idwer Vollering <vidwer@gmail.com>
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
Diffstat (limited to 'src/cpu/x86/16bit/entry16.inc')
-rw-r--r-- | src/cpu/x86/16bit/entry16.inc | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/src/cpu/x86/16bit/entry16.inc b/src/cpu/x86/16bit/entry16.inc index 0fa8c11524..e4613bf986 100644 --- a/src/cpu/x86/16bit/entry16.inc +++ b/src/cpu/x86/16bit/entry16.inc @@ -57,13 +57,6 @@ _start: * entry16.inc. */ - /* Load an IDT with NULL limit to prevent the 16bit IDT being used - * in protected mode before c_start.S sets up a 32bit IDT when entering - * ram stage. - */ - movw $nullidt_offset, %bx - lidt %cs:(%bx) - /* Note: gas handles memory addresses in 16 bit code very poorly. * In particular it doesn't appear to have a directive allowing you * associate a section or even an absolute offset with a segment register. @@ -98,10 +91,18 @@ _start: * the low 16 bits. This means that the intial segment used * when start is called must be 64K aligned. This should not * restrict the address as the ip address can be anything. + * + * Also load an IDT with NULL limit to prevent the 16bit IDT being used + * in protected mode before c_start.S sets up a 32bit IDT when entering + * ram stage. In practise: CPU will shutdown on any exception. + * See IA32 manual Vol 3A 19.26 Interrupts. */ movw %cs, %ax shlw $4, %ax + movw $nullidt_offset, %bx + subw %ax, %bx + lidt %cs:(%bx) movw $gdtptr16_offset, %bx subw %ax, %bx data32 lgdt %cs:(%bx) |