* Sync up to trunk HEAD (r62502).
[reactos.git] / boot / freeldr / freeldr / arch / amd64 / entry.S
1
2
3 #include <asm.inc>
4 #include <arch/pc/x86common.h>
5
6 EXTERN BootMain:PROC
7
8 .code64
9
10 PUBLIC RealEntryPoint
11 RealEntryPoint:
12 /* Setup segment selectors */
13 mov ax, LMODE_DS
14 mov ds, ax
15 mov es, ax
16 mov fs, ax
17 mov gs, ax
18 // mov ss, ax
19
20 //mov word ptr [HEX(b8000)], HEX(0e00) + '1'
21
22 /* Setup long mode stack */
23 mov rsp, qword ptr [stack64]
24
25 /* Continue execution */
26 jmp qword ptr [ContinueAddress]
27
28 ContinueAddress:
29 .double offset FrldrStartup
30
31 FrldrStartup:
32
33 /* Store BootDrive and BootPartition */
34 mov al, byte ptr [BSS_BootDrive]
35 mov byte ptr [FrldrBootDrive], al
36 xor eax, eax
37 mov al, byte ptr [BSS_BootPartition]
38 mov dword ptr [FrldrBootPartition], eax
39
40 /* Patch long jump with real mode entry point */
41 mov eax, dword ptr [BSS_RealModeEntry]
42 mov dword ptr [AddressOfRealModeEntryPoint], eax
43
44 /* GO! */
45 xor rcx, rcx
46 call BootMain
47
48 /* We should never get here */
49 stop:
50 jmp stop
51 nop
52 nop
53
54
55 PUBLIC Reboot
56 Reboot:
57 /* Set the function ID */
58 mov bx, FNID_Reboot
59
60 /* Switch to real mode (We don't return) */
61 jmp SwitchToReal
62
63
64 /* Internal function for realmode calls
65 * bx must be set to the ID of the realmode function to call. */
66 PUBLIC CallRealMode
67 CallRealMode:
68 /* Save current stack pointer */
69 mov qword ptr [stack64], rsp
70
71 /* Set continue address and switch to real mode */
72 lea rax, [CallRealMode_return]
73 mov qword ptr [ContinueAddress], rax
74
75 SwitchToReal:
76 /* Set sane segments */
77 mov ax, LMODE_DS
78 mov ds, ax
79 mov es, ax
80 mov fs, ax
81 mov gs, ax
82 //mov ss, ax
83
84 //mov word ptr [HEX(0b8008)], HEX(0e00) + '4'
85
86 /* Save 64-bit stack pointer */
87 mov qword ptr [stack64], rsp
88
89 /* Step 1 - jump to compatibility segment */
90 jmp fword ptr [jumpvector]
91
92 jumpvector:
93 .long offset SwitchToRealCompSegment
94 .word CMODE_CS
95
96 SwitchToRealCompSegment:
97 /* Note: In fact the CPU is in 32 bit mode here. But it will interprete
98 the generated instructions accordingly. rax will become eax */
99
100 /* Step 2 - deactivate long mode, by disabling paging */
101 mov rax, cr0
102 and eax, HEX(7fffffff) //~0x80000000, upper bits cleared
103 mov cr0, rax
104
105 // mov word ptr [HEX(0b800a)], HEX(0e00) + '5'
106
107 /* Step 3 - jump to 16-bit segment to set the limit correctly */
108 .byte HEX(0EA) // 32bit long jmp
109 AddressOfRealModeEntryPoint:
110 .long 0 // receives address of RealModeEntryPoint
111 .word HEX(20)//RMODE_CS
112 nop
113
114 CallRealMode_return:
115 /* restore stack pointer */
116 mov rsp, qword ptr [stack64]
117 ret
118
119 /////////////////////////////////////////
120
121
122 /* 64-bit stack pointer */
123 stack64:
124 .double STACK64ADDR
125
126 PUBLIC FrldrBootDrive
127 FrldrBootDrive:
128 .byte 0
129
130 PUBLIC FrldrBootPartition
131 FrldrBootPartition:
132 .long 0
133
134 PUBLIC PxeCallApi
135 PxeCallApi:
136 xor eax, eax
137 ret
138
139 //void __lgdt(void *Source);
140 PUBLIC __lgdt
141 __lgdt:
142 lgdt fword ptr [rcx]
143 ret
144
145 //void __ltr(unsigned short Source);
146 PUBLIC __ltr
147 __ltr:
148 ltr cx
149 ret
150
151
152 END