mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
initial import of openbios--main--1.0--patch-26
git-svn-id: svn://coreboot.org/openbios/openbios-devel@1 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
300
arch/x86/entry.S
Normal file
300
arch/x86/entry.S
Normal file
@@ -0,0 +1,300 @@
|
||||
.globl entry, __switch_context, __exit_context, halt, init_exceptions
|
||||
|
||||
.text
|
||||
.align 4
|
||||
|
||||
/*
|
||||
* Entry point
|
||||
* We start execution from here.
|
||||
* It is assumed that CPU is in 32-bit protected mode and
|
||||
* all segments are 4GB and base zero (flat model).
|
||||
*/
|
||||
entry:
|
||||
/* Save boot context and switch to our main context.
|
||||
* Main context is statically defined in C.
|
||||
*/
|
||||
pushl %cs
|
||||
call __switch_context
|
||||
|
||||
/* We get here when the main context switches back to
|
||||
* the boot context.
|
||||
* Return to previous bootloader.
|
||||
*/
|
||||
ret
|
||||
|
||||
/*
|
||||
* Switch execution context
|
||||
* This saves registers, segments, and GDT in the stack, then
|
||||
* switches the stack, and restores everything from the new stack.
|
||||
* This function takes no argument. New stack pointer is
|
||||
* taken from global variable __context, and old stack pointer
|
||||
* is also saved to __context. This way we can just jump to
|
||||
* this routine to get back to the original context.
|
||||
*
|
||||
* Call this routine with lcall or pushl %cs; call.
|
||||
*/
|
||||
__switch_context:
|
||||
/* Save everything in current stack */
|
||||
pushfl /* 56 */
|
||||
pushl %ds /* 52 */
|
||||
pushl %es /* 48 */
|
||||
pushl %fs /* 44 */
|
||||
pushl %gs /* 40 */
|
||||
pushal /* 8 */
|
||||
subl $8, %esp
|
||||
movw %ss, (%esp) /* 0 */
|
||||
sgdt 2(%esp) /* 2 */
|
||||
|
||||
#if 0
|
||||
/* Swap %cs and %eip on the stack, so lret will work */
|
||||
movl 60(%esp), %eax
|
||||
xchgl %eax, 64(%esp)
|
||||
movl %eax, 60(%esp)
|
||||
#endif
|
||||
|
||||
/* At this point we don't know if we are on flat segment
|
||||
* or relocated. So compute the address offset from %eip.
|
||||
* Assuming CS.base==DS.base==SS.base.
|
||||
*/
|
||||
call 1f
|
||||
1: popl %ebx
|
||||
subl $1b, %ebx
|
||||
|
||||
/* Interrupts are not allowed... */
|
||||
cli
|
||||
|
||||
/* Current context pointer is our stack pointer */
|
||||
movl %esp, %esi
|
||||
|
||||
/* Normalize the ctx pointer */
|
||||
subl %ebx, %esi
|
||||
|
||||
/* Swap it with new value */
|
||||
xchgl %esi, __context(%ebx)
|
||||
|
||||
/* Adjust new ctx pointer for current address offset */
|
||||
addl %ebx, %esi
|
||||
|
||||
/* Load new %ss and %esp to temporary */
|
||||
movzwl (%esi), %edx
|
||||
movl 20(%esi), %eax
|
||||
|
||||
/* Load new GDT */
|
||||
lgdt 2(%esi)
|
||||
|
||||
/* Load new stack segment with new GDT */
|
||||
movl %edx, %ss
|
||||
|
||||
/* Set new stack pointer, but we have to adjust it because
|
||||
* pushal saves %esp value before pushal, and we want the value
|
||||
* after pushal.
|
||||
*/
|
||||
leal -32(%eax), %esp
|
||||
|
||||
/* Load the rest from new stack */
|
||||
popal
|
||||
popl %gs
|
||||
popl %fs
|
||||
popl %es
|
||||
popl %ds
|
||||
popfl
|
||||
|
||||
/* Finally, load new %cs and %eip */
|
||||
lret
|
||||
|
||||
__exit_context:
|
||||
/* Get back to the original context */
|
||||
pushl %cs
|
||||
call __switch_context
|
||||
|
||||
/* We get here if the other context attempt to switch to this
|
||||
* dead context. This should not happen. */
|
||||
|
||||
halt:
|
||||
cli
|
||||
hlt
|
||||
jmp halt
|
||||
|
||||
/*
|
||||
* initialize exception handler. All exceptions end up in the same
|
||||
* C function.
|
||||
*/
|
||||
|
||||
init_exceptions:
|
||||
pushl %ebx
|
||||
pushl %edi
|
||||
|
||||
/* Initialize the Interrupt Descriptor table */
|
||||
leal _idt, %edi
|
||||
leal vec0, %ebx
|
||||
movl $(0x08 << 16), %eax /* cs selector */
|
||||
|
||||
1: movw %bx, %ax
|
||||
movl %ebx, %edx
|
||||
movw $0x8E00, %dx /* Interrupt gate - dpl=0, present */
|
||||
movl %eax, 0(%edi)
|
||||
movl %edx, 4(%edi)
|
||||
addl $6, %ebx
|
||||
addl $8, %edi
|
||||
cmpl $_idt_end, %edi
|
||||
jne 1b
|
||||
|
||||
/* Load the Interrupt descriptor table */
|
||||
lidt idtarg
|
||||
|
||||
movl $0, %eax
|
||||
popl %edi
|
||||
popl %ebx
|
||||
ret
|
||||
|
||||
vec0:
|
||||
pushl $0 /* error code */
|
||||
pushl $0 /* vector */
|
||||
jmp int_hand
|
||||
vec1:
|
||||
pushl $0 /* error code */
|
||||
pushl $1 /* vector */
|
||||
jmp int_hand
|
||||
|
||||
vec2:
|
||||
pushl $0 /* error code */
|
||||
pushl $2 /* vector */
|
||||
jmp int_hand
|
||||
|
||||
vec3:
|
||||
pushl $0 /* error code */
|
||||
pushl $3 /* vector */
|
||||
jmp int_hand
|
||||
|
||||
vec4:
|
||||
pushl $0 /* error code */
|
||||
pushl $4 /* vector */
|
||||
jmp int_hand
|
||||
|
||||
vec5:
|
||||
pushl $0 /* error code */
|
||||
pushl $5 /* vector */
|
||||
jmp int_hand
|
||||
|
||||
vec6:
|
||||
pushl $0 /* error code */
|
||||
pushl $6 /* vector */
|
||||
jmp int_hand
|
||||
vec7:
|
||||
pushl $0 /* error code */
|
||||
pushl $7 /* vector */
|
||||
jmp int_hand
|
||||
|
||||
vec8:
|
||||
/* error code */
|
||||
pushl $8 /* vector */
|
||||
jmp int_hand
|
||||
.word 0x9090
|
||||
|
||||
vec9:
|
||||
pushl $0 /* error code */
|
||||
pushl $9 /* vector */
|
||||
jmp int_hand
|
||||
|
||||
vec10:
|
||||
/* error code */
|
||||
pushl $10 /* vector */
|
||||
jmp int_hand
|
||||
.word 0x9090
|
||||
|
||||
vec11:
|
||||
/* error code */
|
||||
pushl $11 /* vector */
|
||||
jmp int_hand
|
||||
.word 0x9090
|
||||
|
||||
vec12:
|
||||
/* error code */
|
||||
pushl $12 /* vector */
|
||||
jmp int_hand
|
||||
.word 0x9090
|
||||
|
||||
vec13:
|
||||
/* error code */
|
||||
pushl $13 /* vector */
|
||||
jmp int_hand
|
||||
.word 0x9090
|
||||
|
||||
vec14:
|
||||
/* error code */
|
||||
pushl $14 /* vector */
|
||||
jmp int_hand
|
||||
.word 0x9090
|
||||
|
||||
vec15:
|
||||
pushl $0 /* error code */
|
||||
pushl $15 /* vector */
|
||||
jmp int_hand
|
||||
|
||||
vec16:
|
||||
pushl $0 /* error code */
|
||||
pushl $16 /* vector */
|
||||
jmp int_hand
|
||||
|
||||
vec17:
|
||||
/* error code */
|
||||
pushl $17 /* vector */
|
||||
jmp int_hand
|
||||
.word 0x9090
|
||||
|
||||
vec18:
|
||||
pushl $0 /* error code */
|
||||
pushl $18 /* vector */
|
||||
jmp int_hand
|
||||
|
||||
vec19:
|
||||
pushl $0 /* error code */
|
||||
pushl $19 /* vector */
|
||||
jmp int_hand
|
||||
|
||||
int_hand:
|
||||
/* At this point on the stack there is:
|
||||
* 0(%esp) vector
|
||||
* 4(%esp) error code
|
||||
* 8(%esp) eip
|
||||
* 12(%esp) cs
|
||||
* 16(%esp) eflags
|
||||
*/
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
pushl %ebp
|
||||
/* Original stack pointer */
|
||||
leal 32(%esp), %ebp
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %edx
|
||||
pushl %ecx
|
||||
pushl %eax
|
||||
|
||||
pushl %esp /* Pointer to structure on the stack */
|
||||
|
||||
call x86_exception
|
||||
pop %eax /* Drop the pointer */
|
||||
|
||||
popl %eax
|
||||
popl %ecx
|
||||
popl %edx
|
||||
popl %ebx
|
||||
popl %ebp /* Ignore saved %esp value */
|
||||
popl %ebp
|
||||
popl %esi
|
||||
popl %edi
|
||||
|
||||
addl $8, %esp /* pop of the vector and error code */
|
||||
|
||||
iret
|
||||
|
||||
idtarg:
|
||||
.word _idt_end - _idt - 1 /* limit */
|
||||
.long _idt
|
||||
.word 0
|
||||
_idt:
|
||||
.fill 20, 8, 0 # idt is unitiailzed
|
||||
_idt_end:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user