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