source: mainline/kernel/arch/ia32/src/boot/boot.S@ 2bf2e1d

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 2bf2e1d was 22c3444, checked in by Martin Decky <martin@…>, 15 years ago

improve early printout scrolling speed

  • Property mode set to 100644
File size: 10.2 KB
Line 
1/*
2 * Copyright (c) 2001 Jakub Jermar
3 * Copyright (c) 2005 Martin Decky
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include <arch/boot/boot.h>
31#include <arch/boot/memmap.h>
32#include <arch/mm/page.h>
33#include <arch/pm.h>
34#include <arch/cpuid.h>
35
36#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
37
38.section K_TEXT_START, "ax"
39
40.code32
41
42.macro pm_error msg
43 movl \msg, %esi
44 jmp pm_error_halt
45.endm
46
47.macro pm_status msg
48#ifdef CONFIG_EGA
49 pushl %esi
50 movl \msg, %esi
51 call pm_early_puts
52 popl %esi
53#endif
54.endm
55
56.macro pm2_status msg
57 pushl \msg
58 call early_puts
59.endm
60
61.align 4
62.global multiboot_image_start
63multiboot_header:
64 .long MULTIBOOT_HEADER_MAGIC
65 .long MULTIBOOT_HEADER_FLAGS
66 .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) /* checksum */
67 .long multiboot_header
68 .long unmapped_ktext_start
69 .long 0
70 .long 0
71 .long multiboot_image_start
72
73multiboot_image_start:
74 cld
75
76 /* Initialize stack pointer */
77 movl $START_STACK, %esp
78
79 /* Initialize Global Descriptor Table register */
80 lgdtl KA2PA(bootstrap_gdtr)
81
82 /* Kernel data + stack */
83 movw $gdtselector(KDATA_DES), %cx
84 movw %cx, %es
85 movw %cx, %fs
86 movw %cx, %gs
87 movw %cx, %ds
88 movw %cx, %ss
89
90 jmpl $gdtselector(KTEXT_DES), $multiboot_meeting_point
91 multiboot_meeting_point:
92
93 /* Save GRUB arguments */
94 movl %eax, grub_eax
95 movl %ebx, grub_ebx
96
97 pm_status $status_prot
98
99 movl $(INTEL_CPUID_LEVEL), %eax
100 cpuid
101 cmp $0x0, %eax /* any function > 0? */
102 jbe pse_unsupported
103
104 movl $(INTEL_CPUID_STANDARD), %eax
105 cpuid
106 bt $(INTEL_PSE), %edx
107 jc pse_supported
108
109 pse_unsupported:
110
111 pm_error $err_pse
112
113 pse_supported:
114
115#include "vesa_prot.inc"
116
117 /* Map kernel and turn paging on */
118 call map_kernel
119
120 /* Create the first stack frame */
121 pushl $0
122 movl %esp, %ebp
123
124 pm2_status $status_prot2
125
126 /* Call arch_pre_main(grub_eax, grub_ebx) */
127 pushl grub_ebx
128 pushl grub_eax
129 call arch_pre_main
130
131 pm2_status $status_main
132
133 /* Call main_bsp() */
134 call main_bsp
135
136 /* Not reached */
137 cli
138 hlt0:
139 hlt
140 jmp hlt0
141
142/** Setup mapping for the kernel.
143 *
144 * Setup mapping for both the unmapped and mapped sections
145 * of the kernel. For simplicity, we map the entire 4G space.
146 *
147 */
148.global map_kernel
149map_kernel:
150 movl %cr4, %ecx
151 orl $(1 << 4), %ecx /* PSE on */
152 andl $(~(1 << 5)), %ecx /* PAE off */
153 movl %ecx, %cr4
154
155 movl $(page_directory + 0), %esi
156 movl $(page_directory + 2048), %edi
157 xorl %ecx, %ecx
158 xorl %ebx, %ebx
159
160 floop:
161 movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax
162 orl %ebx, %eax
163 /* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
164 movl %eax, (%esi, %ecx, 4)
165 /* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
166 movl %eax, (%edi, %ecx, 4)
167 addl $(4 * 1024 * 1024), %ebx
168
169 incl %ecx
170 cmpl $512, %ecx
171 jl floop
172
173 movl %esi, %cr3
174
175 movl %cr0, %ebx
176 orl $(1 << 31), %ebx /* paging on */
177 movl %ebx, %cr0
178 ret
179
180/** Print string to EGA display (in light red) and halt.
181 *
182 * Should be executed from 32 bit protected mode with paging
183 * turned off. Stack is not required. This routine is used even
184 * if CONFIG_EGA is not enabled. Since we are going to halt the
185 * CPU anyway, it is always better to at least try to print
186 * some hints.
187 *
188 * @param %esi NULL-terminated string to print.
189 *
190 */
191pm_error_halt:
192 movl $0xb8000, %edi /* base of EGA text mode memory */
193 xorl %eax, %eax
194
195 /* Read bits 8 - 15 of the cursor address */
196 movw $0x3d4, %dx
197 movb $0xe, %al
198 outb %al, %dx
199
200 movw $0x3d5, %dx
201 inb %dx, %al
202 shl $8, %ax
203
204 /* Read bits 0 - 7 of the cursor address */
205 movw $0x3d4, %dx
206 movb $0xf, %al
207 outb %al, %dx
208
209 movw $0x3d5, %dx
210 inb %dx, %al
211
212 /* Sanity check for the cursor on screen */
213 cmp $2000, %ax
214 jb err_cursor_ok
215
216 movw $1998, %ax
217
218 err_cursor_ok:
219
220 movw %ax, %bx
221 shl $1, %eax
222 addl %eax, %edi
223
224 err_ploop:
225 lodsb
226
227 cmp $0, %al
228 je err_ploop_end
229
230 movb $0x0c, %ah /* black background, light red foreground */
231 stosw
232
233 /* Sanity check for the cursor on the last line */
234 inc %bx
235 cmp $2000, %bx
236 jb err_ploop
237
238 /* Scroll the screen (24 rows) */
239 movl %esi, %edx
240 movl $0xb80a0, %esi
241 movl $0xb8000, %edi
242 movl $960, %ecx
243 rep movsl
244
245 /* Clear the 24th row */
246 xorl %eax, %eax
247 movl $40, %ecx
248 rep stosl
249
250 /* Go to row 24 */
251 movl %edx, %esi
252 movl $0xb8f00, %edi
253 movw $1920, %bx
254
255 jmp err_ploop
256 err_ploop_end:
257
258 /* Write bits 8 - 15 of the cursor address */
259 movw $0x3d4, %dx
260 movb $0xe, %al
261 outb %al, %dx
262
263 movw $0x3d5, %dx
264 movb %bh, %al
265 outb %al, %dx
266
267 /* Write bits 0 - 7 of the cursor address */
268 movw $0x3d4, %dx
269 movb $0xf, %al
270 outb %al, %dx
271
272 movw $0x3d5, %dx
273 movb %bl, %al
274 outb %al, %dx
275
276 cli
277 hlt1:
278 hlt
279 jmp hlt1
280
281/** Print string to EGA display (in light green).
282 *
283 * Should be called from 32 bit protected mode with paging
284 * turned off. A stack space of at least 24 bytes is required,
285 * but the function does not establish a stack frame.
286 *
287 * Macros such as pm_status take care that this function
288 * is used only when CONFIG_EGA is enabled.
289 *
290 * @param %esi NULL-terminated string to print.
291 *
292 */
293pm_early_puts:
294 pushl %eax
295 pushl %ebx
296 pushl %ecx
297 pushl %edx
298 pushl %edi
299
300 movl $0xb8000, %edi /* base of EGA text mode memory */
301 xorl %eax, %eax
302
303 /* Read bits 8 - 15 of the cursor address */
304 movw $0x3d4, %dx
305 movb $0xe, %al
306 outb %al, %dx
307
308 movw $0x3d5, %dx
309 inb %dx, %al
310 shl $8, %ax
311
312 /* Read bits 0 - 7 of the cursor address */
313 movw $0x3d4, %dx
314 movb $0xf, %al
315 outb %al, %dx
316
317 movw $0x3d5, %dx
318 inb %dx, %al
319
320 /* Sanity check for the cursor on screen */
321 cmp $2000, %ax
322 jb pm_puts_cursor_ok
323
324 movw $1998, %ax
325
326 pm_puts_cursor_ok:
327
328 movw %ax, %bx
329 shl $1, %eax
330 addl %eax, %edi
331
332 pm_puts_ploop:
333 lodsb
334
335 cmp $0, %al
336 je pm_puts_ploop_end
337
338 movb $0x0a, %ah /* black background, light green foreground */
339 stosw
340
341 /* Sanity check for the cursor on the last line */
342 inc %bx
343 cmp $2000, %bx
344 jb pm_puts_ploop
345
346 /* Scroll the screen (24 rows) */
347 movl %esi, %edx
348 movl $0xb80a0, %esi
349 movl $0xb8000, %edi
350 movl $960, %ecx
351 rep movsl
352
353 /* Clear the 24th row */
354 xorl %eax, %eax
355 movl $40, %ecx
356 rep stosl
357
358 /* Go to row 24 */
359 movl %edx, %esi
360 movl $0xb8f00, %edi
361 movw $1920, %bx
362
363 jmp pm_puts_ploop
364 pm_puts_ploop_end:
365
366 /* Write bits 8 - 15 of the cursor address */
367 movw $0x3d4, %dx
368 movb $0xe, %al
369 outb %al, %dx
370
371 movw $0x3d5, %dx
372 movb %bh, %al
373 outb %al, %dx
374
375 /* Write bits 0 - 7 of the cursor address */
376 movw $0x3d4, %dx
377 movb $0xf, %al
378 outb %al, %dx
379
380 movw $0x3d5, %dx
381 movb %bl, %al
382 outb %al, %dx
383
384 popl %edi
385 popl %edx
386 popl %ecx
387 popl %ebx
388 popl %eax
389
390 ret
391
392/** Print string to EGA display.
393 *
394 * Should be called from 32 bit protected mode (with paging
395 * enabled and stack established). This function is ABI compliant.
396 *
397 * If CONFIG_EGA is undefined or CONFIG_FB is defined
398 * then this function does nothing.
399 *
400 * @param %ebp+0x08 NULL-terminated string to print.
401 *
402 */
403early_puts:
404
405#if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB)))
406
407 /* Prologue, save preserved registers */
408 pushl %ebp
409 movl %esp, %ebp
410 pushl %ebx
411 pushl %esi
412 pushl %edi
413
414 movl 0x08(%ebp), %esi
415 movl $(PA2KA(0xb8000)), %edi /* base of EGA text mode memory */
416 xorl %eax, %eax
417
418 /* Read bits 8 - 15 of the cursor address */
419 movw $0x3d4, %dx
420 movb $0xe, %al
421 outb %al, %dx
422
423 movw $0x3d5, %dx
424 inb %dx, %al
425 shl $8, %ax
426
427 /* Read bits 0 - 7 of the cursor address */
428 movw $0x3d4, %dx
429 movb $0xf, %al
430 outb %al, %dx
431
432 movw $0x3d5, %dx
433 inb %dx, %al
434
435 /* Sanity check for the cursor on screen */
436 cmp $2000, %ax
437 jb early_puts_cursor_ok
438
439 movw $1998, %ax
440
441 early_puts_cursor_ok:
442
443 movw %ax, %bx
444 shl $1, %eax
445 addl %eax, %edi
446
447 early_puts_ploop:
448 lodsb
449
450 cmp $0, %al
451 je early_puts_ploop_end
452
453 movb $0x0e, %ah /* black background, yellow foreground */
454 stosw
455
456 /* Sanity check for the cursor on the last line */
457 inc %bx
458 cmp $2000, %bx
459 jb early_puts_ploop
460
461 /* Scroll the screen (24 rows) */
462 movl %esi, %edx
463 movl $(PA2KA(0xb80a0)), %esi
464 movl $(PA2KA(0xb8000)), %edi
465 movl $960, %ecx
466 rep movsl
467
468 /* Clear the 24th row */
469 xorl %eax, %eax
470 movl $40, %ecx
471 rep stosl
472
473 /* Go to row 24 */
474 movl %edx, %esi
475 movl $(PA2KA(0xb8f00)), %edi
476 movw $1920, %bx
477
478 jmp early_puts_ploop
479 early_puts_ploop_end:
480
481 /* Write bits 8 - 15 of the cursor address */
482 movw $0x3d4, %dx
483 movb $0xe, %al
484 outb %al, %dx
485
486 movw $0x3d5, %dx
487 movb %bh, %al
488 outb %al, %dx
489
490 /* Write bits 0 - 7 of the cursor address */
491 movw $0x3d4, %dx
492 movb $0xf, %al
493 outb %al, %dx
494
495 movw $0x3d5, %dx
496 movb %bl, %al
497 outb %al, %dx
498
499 /* Epilogue, restore preserved registers */
500 popl %edi
501 popl %esi
502 popl %ebx
503 leave
504
505#endif
506
507 ret
508
509#include "vesa_real.inc"
510
511.section K_DATA_START, "aw", @progbits
512
513.align 4096
514page_directory:
515 .space 4096, 0
516
517grub_eax:
518 .long 0
519
520grub_ebx:
521 .long 0
522
523err_pse:
524 .asciz "Page Size Extension not supported. System halted."
525
526status_prot:
527 .asciz "[prot] "
528status_vesa_copy:
529 .asciz "[vesa_copy] "
530status_grub_cmdline:
531 .asciz "[grub_cmdline] "
532status_vesa_real:
533 .asciz "[vesa_real] "
534status_prot2:
535 .asciz "[prot2] "
536status_main:
537 .asciz "[main] "
Note: See TracBrowser for help on using the repository browser.