update for HEAD-2003091401
[reactos.git] / ntoskrnl / ke / i386 / multiboot.S
1 #include <roscfg.h>
2 #include <internal/ntoskrnl.h>
3 #include <internal/i386/segment.h>
4 #include <internal/ps.h>
5
6 #define KERNEL_BASE (0xc0000000)
7
8 #define MULTIBOOT_HEADER_MAGIC (0x1BADB002)
9
10 #define MULTIBOOT_HEADER_FLAGS (0x00010003)
11
12 #define V2P(x) (x - 0xc0000000 + 0x200000)
13
14 #ifdef MP
15
16 #define AP_MAGIC (0x12481020)
17
18 #endif /* MP */
19         
20 .globl _NtProcessStartup
21 .globl _start
22 .globl _init_stack
23 .globl _init_stack_top
24 .globl _trap_stack
25 .globl _trap_stack_top  
26 .globl _unmap_me
27 .globl _unmap_me2
28 .globl _unmap_me3
29 .globl _unmap_me4
30                 
31         /*
32          * This is called by the realmode loader, with protected mode
33          * enabled, paging disabled and the segment registers pointing
34          * a 4Gb, 32-bit segment starting at zero.
35          *
36          *    EAX = Multiboot magic or application processor magic
37          *
38          *    EBX = Points to a structure in lowmem with data from the
39          *    loader
40          */
41
42 _NtProcessStartup:
43 _start:
44         jmp     _multiboot_entry
45
46         /* Align 32 bits boundary */
47         .align 4
48         
49         /* Multiboot header */
50 multiboot_header:
51         /* magic */
52         .long MULTIBOOT_HEADER_MAGIC
53         /* flags */
54         .long MULTIBOOT_HEADER_FLAGS
55         /* checksum */
56         .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
57         /* header_addr */
58         .long (0x200000 + multiboot_header - KERNEL_BASE)
59         /* load_addr */
60         .long 0x200000
61         /* load_end_addr */
62         .long (__bss_start__ + 0x200000 - KERNEL_BASE)
63         /* bss_end_addr */
64         .long (__bss_end__ + 0x200000 - KERNEL_BASE)
65         /* entry_addr */
66         .long (0x200000 + _start - KERNEL_BASE)
67
68 _multiboot_entry:       
69         /*
70          * This must be PIC because we haven't set up paging yet
71          */     
72         
73         /*
74          * Gcc expects this at all times
75          */
76         cld
77
78 #ifdef MP
79
80         /*
81          * Save the multiboot or application processor magic
82          */
83         movl    %eax, %edx
84
85         cmpl    $AP_MAGIC, %edx
86         je      .m1
87
88 #endif /* MP */
89
90         /*
91          * Zero the BSS
92          */
93         movl    %eax, %edx
94         movl    $0, %eax
95         movl    $__bss_end__, %ecx
96         subl    $__bss_start__, %ecx
97         shr     $2, %ecx
98         movl    $__bss_start__, %edi
99         subl    $0xc0000000, %edi
100         addl    $0x200000, %edi
101         rep
102         stosl
103
104         /*
105          * Initialize the page directory
106          */
107         movl    $V2P(startup_pagedirectory), %esi
108         movl    $(V2P(lowmem_pagetable) + 0x7), 0x0(%esi)
109         movl    $(V2P(kernel_pagetable) + 0x7), 0xC00(%esi)
110         movl    $(V2P(kernel_pagetable+4096) + 0x7), 0xC04(%esi)
111         movl    $(V2P(kernel_pagetable+2*4096) + 0x7), 0xC08(%esi)
112         movl    $(V2P(kernel_pagetable+3*4096) + 0x7), 0xC0c(%esi)
113         movl    $(V2P(kernel_pagetable+4*4096) + 0x7), 0xC10(%esi)
114         movl    $(V2P(kernel_pagetable+5*4096) + 0x7), 0xC14(%esi)
115         movl    $(V2P(kernel_pagetable+6*4096) + 0x7), 0xC18(%esi)
116         movl    $(V2P(kernel_pagetable+7*4096) + 0x7), 0xC1c(%esi)
117         movl    $(V2P(kernel_pagetable+8*4096) + 0x7), 0xC20(%esi)
118         movl    $(V2P(kernel_pagetable+9*4096) + 0x7), 0xC24(%esi)
119         movl    $(V2P(kernel_pagetable+10*4096) + 0x7), 0xC28(%esi)
120         movl    $(V2P(kernel_pagetable+11*4096) + 0x7), 0xC2c(%esi)
121         movl    $(V2P(kernel_pagetable+12*4096) + 0x7), 0xC30(%esi)
122         movl    $(V2P(kernel_pagetable+13*4096) + 0x7), 0xC34(%esi)
123         movl    $(V2P(kernel_pagetable+14*4096) + 0x7), 0xC38(%esi)
124         movl    $(V2P(kernel_pagetable+15*4096) + 0x7), 0xC3c(%esi)
125         movl    $(V2P(kernel_pagetable+16*4096) + 0x7), 0xC40(%esi)
126         movl    $(V2P(kernel_pagetable+17*4096) + 0x7), 0xC44(%esi)
127         movl    $(V2P(kernel_pagetable+18*4096) + 0x7), 0xC48(%esi)
128         movl    $(V2P(kernel_pagetable+19*4096) + 0x7), 0xC4c(%esi)
129         movl    $(V2P(kernel_pagetable+20*4096) + 0x7), 0xC50(%esi)
130         movl    $(V2P(kernel_pagetable+21*4096) + 0x7), 0xC54(%esi)
131         movl    $(V2P(kernel_pagetable+22*4096) + 0x7), 0xC58(%esi)
132         movl    $(V2P(kernel_pagetable+23*4096) + 0x7), 0xC5c(%esi)
133         movl    $(V2P(kernel_pagetable+24*4096) + 0x7), 0xC60(%esi)
134         movl    $(V2P(kernel_pagetable+25*4096) + 0x7), 0xC64(%esi)
135         movl    $(V2P(kernel_pagetable+26*4096) + 0x7), 0xC68(%esi)
136         movl    $(V2P(kernel_pagetable+27*4096) + 0x7), 0xC6c(%esi)
137         movl    $(V2P(kernel_pagetable+28*4096) + 0x7), 0xC70(%esi)
138         movl    $(V2P(kernel_pagetable+29*4096) + 0x7), 0xC74(%esi)
139         movl    $(V2P(kernel_pagetable+30*4096) + 0x7), 0xC78(%esi)
140         movl    $(V2P(kernel_pagetable+31*4096) + 0x7), 0xC7c(%esi)
141
142         movl    $(V2P(lowmem_pagetable) + 0x7), 0xD00(%esi)
143         movl    $(V2P(startup_pagedirectory) + 0x7), 0xF00(%esi) 
144 #ifdef MP
145         movl    $(V2P(apic_pagetable) + 0x7), 0xFEC(%esi)
146 #endif /* MP */
147         movl    $(V2P(kpcr_pagetable) + 0x7), 0xFF0(%esi)
148
149         /*
150          * Initialize the page table that maps low memory
151          */
152         movl    $V2P(lowmem_pagetable), %esi
153         movl    $0x7, %eax
154         movl    $0, %edi
155 .l3:
156         movl    %eax, (%esi, %edi)
157         addl    $0x1000, %eax
158         addl    $4, %edi
159         cmpl    $4096, %edi
160         jl      .l3
161
162         /*
163          * Initialize the page table that maps kernel memory
164          */
165         movl    $V2P(kernel_pagetable), %esi
166         movl    $0x200007, %eax
167         movl    $0, %edi
168 .l4:
169         movl    %eax, (%esi, %edi)
170         addl    $0x1000, %eax
171         addl    $4, %edi
172         cmpl    $6144, %edi
173         jl      .l4
174         
175 #ifdef  MP
176
177         /*
178          * Initialize the page table that maps the APIC register address space
179          */
180          
181         /* 
182          * FIXME: APIC register address space can be non-standard so do the 
183          * mapping later 
184          */
185         movl    $V2P(apic_pagetable), %esi
186         movl    $0, %edi
187         movl    $0xFEC0001B, %eax
188         movl    %eax, (%esi, %edi)
189         movl    $0x800, %edi
190         movl    $0xFEE0001B, %eax
191         movl    %eax, (%esi, %edi)
192
193 #endif /* MP */
194
195         /*
196          * Initialize the page table that maps the initial KPCR (at FF000000)
197          */
198         movl    $V2P(kpcr_pagetable), %esi
199         movl    $0, %edi
200         movl    $0x1007, %eax
201         movl    %eax, (%esi, %edi)
202
203 #ifdef MP
204
205 .m1:
206
207 #endif /* MP */
208
209         /*
210          * Set up the PDBR
211          */     
212         movl    $(V2P(startup_pagedirectory)), %eax
213         movl    %eax, %cr3
214
215         /*
216          * Enable paging and set write protect
217          */
218         movl    %cr0, %eax
219         orl     $0x80010000, %eax
220         movl    %eax, %cr0
221
222         /*
223          * Do an absolute jump because we now want to execute above 0xc0000000
224          */     
225         movl    $.l2, %eax
226         jmp     *%eax
227 .l2:
228         
229         /*
230          * Load the GDTR and IDTR with new tables located above
231          * 0xc0000000
232          */
233         
234         /* FIXME: Application processors should have their own GDT/IDT */
235         lgdt    _KiGdtDescriptor
236         lidt    _KiIdtDescriptor
237
238         /*
239          * Reload the data segment registers 
240          */
241         movl    $KERNEL_DS, %eax
242         movl    %eax, %ds
243         movl    %eax, %es
244         movl    %eax, %gs
245         movl    %eax, %ss
246         movl    $0, %eax
247         movl    %eax, %fs
248
249 #ifdef MP
250
251         cmpl    $AP_MAGIC, %edx
252         jne     .m2
253
254         /*
255          * This is an application processor executing
256          */
257
258         /*
259          * Initialize EFLAGS
260          */
261         pushl   $0
262         popfl
263
264         /*
265          * Call the application processor initialization code
266          */
267         pushl   $0
268         pushl   $.l7
269         pushl   $KERNEL_CS
270         pushl   $_KiSystemStartup
271         lret
272
273         /*
274          * Catch illegal returns from KiSystemStartup
275          */
276 .l7:
277         popl    %eax    
278         pushl   $0
279         call    _KeBugCheck@4
280         popl    %eax
281 .l8:
282         jmp     .l8
283
284         
285 .m2:
286
287 #endif /* MP */
288
289         /*
290          * Load the PCR selector
291          */
292         movl    $PCR_SELECTOR, %eax
293         movl    %eax, %fs
294
295         /*
296          * Load the initial kernel stack
297          */
298         movl    $_init_stack_top, %esp
299
300         /*
301          * Initialize EFLAGS
302          */
303         pushl   $0
304         popfl
305
306         /*
307          * Call the main kernel initialization
308          */
309         movl    $0, %ebp
310         pushl   %ebx
311         pushl   %edx
312         pushl   $.l5
313         pushl   $KERNEL_CS
314         pushl   $__main
315         lret
316         
317         /*
318          * Catch illegal returns from main, try bug checking the system,
319          * if that fails then loop forever.
320          */
321 .l5:
322         popl    %eax
323         popl    %eax
324         pushl   $0
325         call    _KeBugCheck@4
326         popl    %eax
327 .l6:
328         jmp     .l6
329
330         
331         /*
332          * This needs to be page aligned so put it at the beginning of the bss
333          * segment
334          */
335 .bss
336 startup_pagedirectory:
337         .fill 4096, 1, 0
338
339 lowmem_pagetable:
340         .fill 4096, 1, 0
341
342 kernel_pagetable:
343         .fill 32*4096, 1, 0     
344
345 #ifdef MP
346 apic_pagetable:
347         .fill 4096, 1, 0        
348 #endif /* MP */
349
350 kpcr_pagetable:
351         .fill 4096, 1, 0        
352
353 _unmap_me:
354         .fill 4096, 1, 0
355         
356 _init_stack:
357         .fill 3*4096, 1, 0
358 _init_stack_top: 
359
360 _unmap_me2:     
361         .fill 4096, 1, 0
362         
363 _trap_stack:    
364         .fill 3*4096, 1, 0
365 _trap_stack_top:        
366         
367 _unmap_me3:     
368         .fill 4096, 1, 0