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>
This commit is contained in:
parent
5750ed253a
commit
7863015c3e
|
@ -57,13 +57,6 @@ _start:
|
||||||
* entry16.inc.
|
* 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.
|
/* Note: gas handles memory addresses in 16 bit code very poorly.
|
||||||
* In particular it doesn't appear to have a directive allowing you
|
* In particular it doesn't appear to have a directive allowing you
|
||||||
* associate a section or even an absolute offset with a segment register.
|
* 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
|
* the low 16 bits. This means that the intial segment used
|
||||||
* when start is called must be 64K aligned. This should not
|
* when start is called must be 64K aligned. This should not
|
||||||
* restrict the address as the ip address can be anything.
|
* 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
|
movw %cs, %ax
|
||||||
shlw $4, %ax
|
shlw $4, %ax
|
||||||
|
movw $nullidt_offset, %bx
|
||||||
|
subw %ax, %bx
|
||||||
|
lidt %cs:(%bx)
|
||||||
movw $gdtptr16_offset, %bx
|
movw $gdtptr16_offset, %bx
|
||||||
subw %ax, %bx
|
subw %ax, %bx
|
||||||
data32 lgdt %cs:(%bx)
|
data32 lgdt %cs:(%bx)
|
||||||
|
|
Loading…
Reference in New Issue