-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathexit.S
112 lines (101 loc) · 1.77 KB
/
exit.S
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*
* exit.S Copyright (C) 2012 Michael Brown <mcb30@ipxe.org>
*
*/
#include "defs.h"
.text
.code32
.globl exit
exit:
/* Exit status to %eax */
movl 4(%esp), %eax
/* Calculate real-mode exit %ss:esp in %dx:%edi */
xorw %dx, %dx
xorl %edi, %edi
movl exit_esp, %ebp
cmpl $EXIT_MAGIC, 0(%ebp)
jne 1f
movl 8(%ebp), %edi
movw 6(%ebp), %dx
1:
/* Load IDT and GDT and switch to 16-bit code segment */
cli
lidt idt_descr
lgdt gdt_descr
ljmp $REAL_CS, $(1f - LOW_TEST_ADR)
1:
.code16
/* Load 16-bit limits for other segment registers */
movw $REAL_DS, %bx
movw %bx, %ds
movw %bx, %es
movw %bx, %fs
movw %bx, %gs
movw %bx, %ss
movl $LOW_TEST_ADR, %esp
/* Switch to real mode */
movl %cr0, %ebx
andb $~0x01, %bl
movl %ebx, %cr0
ljmp $(LOW_TEST_ADR >> 4), $1f
1:
/* Load real-mode segment registers */
xorw %bx, %bx
movw %bx, %ds
movw %bx, %es
movw %bx, %fs
movw %bx, %gs
movw %bx, %ss
/* Reenable interrupts */
sti
/* If we have a real-mode exit stack, restore registers
* (except exit status) and return
*/
testl %edi, %edi
jz reset
movw %dx, %ss
movl %edi, %esp
movw %sp, %bp
movl %eax, 36(%bp)
popw %ds
popw %es
popw %fs
popw %gs
popal
popfl
lret
reset:
/* Perform a warm reset */
movw $0x1234, %ax
movw %ax, 0x472
movb $0xfe, %al
outb %al, $0x64
/* If reset failed, halt the CPU */
cli
hlt
.align 16
gdt:
/* Dummy */
.word 0,0,0,0
/* Unused */
.word 0,0,0,0
/* Unused */
.word 0,0,0,0
/* Unused */
.word 0,0,0,0
/* 16 bit real mode code segment */
.word 0xffff, ( LOW_TEST_ADR & 0xffff )
.word ( 0x9b00 | ( LOW_TEST_ADR >> 16 ) ), 0
/* 16 bit real mode data segment */
.word 0xffff, 0, 0x9300, 0
gdt_end:
gdt_descr:
.word gdt_end - gdt - 1
.long gdt
.align 16
idt_descr:
.word 0xffff
.long 0
.globl exit_esp
exit_esp:
.long 0