source: mainline/kernel/arch/ia32/src/boot/multiboot.S@ 8781e9d

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8781e9d was 8781e9d, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

Remove realmode VESA code

This simply enables framebuffer setup via multiboot1
(multiboot2 already did it), and removes the obsolete code.

  • Property mode set to 100644
File size: 14.3 KB
RevLine 
[873c681]1/*
2 * Copyright (c) 2001 Jakub Jermar
3 * Copyright (c) 2005 Martin Decky
[6d8c4654]4 * Copyright (c) 2011 Martin Sucha
[873c681]5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * - The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
[f761f1eb]30
[8844e70]31#include <abi/asmtool.h>
[f9447155]32#include <arch/boot/boot.h>
[7ba16eb]33#include <arch/boot/memmap.h>
[8f2153b]34#include <arch/mm/page.h>
35#include <arch/pm.h>
[1f5c9c96]36#include <genarch/multiboot/multiboot.h>
[c18e666]37#include <arch/cpuid.h>
[57c2a87]38#include <arch/cpu.h>
[f9447155]39
[8781e9d]40// TODO: most of this file can be rewritten in C
41
[873c681]42#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
[66def8d]43
[874e312a]44.section K_TEXT_START, "ax"
[f761f1eb]45
[b0bf501]46.code32
[873c681]47
48.macro pm_error msg
49 movl \msg, %esi
50 jmp pm_error_halt
51.endm
52
53.macro pm_status msg
[8781e9d]54#if defined(CONFIG_EGA) && !defined(CONFIG_FB)
[873c681]55 pushl %esi
56 movl \msg, %esi
57 call pm_early_puts
58 popl %esi
59#endif
60.endm
61
62.macro pm2_status msg
63 pushl \msg
64 call early_puts
65.endm
66
[f9447155]67.align 4
68multiboot_header:
69 .long MULTIBOOT_HEADER_MAGIC
[8781e9d]70#ifdef CONFIG_FB
[f9447155]71 .long MULTIBOOT_HEADER_FLAGS
[873c681]72 .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) /* checksum */
[8781e9d]73#else
74 .long MULTIBOOT_HEADER_FLAGS_NOFB
75 .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS_NOFB) /* checksum */
76#endif
[66def8d]77 .long multiboot_header
[bae43dc]78 .long unmapped_start
[f9447155]79 .long 0
80 .long 0
[66def8d]81 .long multiboot_image_start
[8781e9d]82#ifdef CONFIG_FB
83 .long 0
84 .long CONFIG_BFB_WIDTH
85 .long CONFIG_BFB_HEIGHT
86 .long CONFIG_BFB_BPP
87#endif
[421c833]88
[8844e70]89SYMBOL(multiboot_image_start)
[f66c203d]90 cli
[e13daa5d]91 cld
[a35b458]92
[873c681]93 /* Initialize stack pointer */
94 movl $START_STACK, %esp
[a35b458]95
[f66c203d]96 /*
97 * Initialize Global Descriptor Table and
98 * Interrupt Descriptor Table registers
99 */
[1d3d2cf]100 lgdtl bootstrap_gdtr
[f66c203d]101 lidtl bootstrap_idtr
[a35b458]102
[873c681]103 /* Kernel data + stack */
[1d3d2cf]104 movw $GDT_SELECTOR(KDATA_DES), %cx
[5eb1379]105 movw %cx, %es
106 movw %cx, %fs
[ff133e2]107 movw %cx, %gs
[873c681]108 movw %cx, %ds
[5eb1379]109 movw %cx, %ss
[a35b458]110
[1d3d2cf]111 jmpl $GDT_SELECTOR(KTEXT_DES), $multiboot_meeting_point
[4533601]112 multiboot_meeting_point:
[a35b458]113
[1f5c9c96]114 /* Save multiboot arguments */
115 movl %eax, multiboot_eax
116 movl %ebx, multiboot_ebx
[a35b458]117
[873c681]118 pm_status $status_prot
[a35b458]119
[e3e4a2c]120#ifndef PROCESSOR_i486
[a35b458]121
[e3e4a2c]122 pm_status $status_prot2
[a35b458]123
[e3e4a2c]124 movl $(INTEL_CPUID_LEVEL), %eax
125 cpuid
126 cmp $0x0, %eax /* any function > 0? */
127 jbe pse_unsupported
[a35b458]128
[e3e4a2c]129 movl $(INTEL_CPUID_STANDARD), %eax
130 cpuid
131 bt $(INTEL_PSE), %edx
132 jnc pse_unsupported
[a35b458]133
[e3e4a2c]134 /* Map kernel and turn paging on */
135 pm_status $status_pse
136 call map_kernel_pse
137 jmp stack_init
[a35b458]138
[e3e4a2c]139#endif /* PROCESSOR_i486 */
[a35b458]140
[e3e4a2c]141 pse_unsupported:
[a35b458]142
[e3e4a2c]143 /* Map kernel and turn paging on */
144 pm_status $status_non_pse
[fb45c7b]145 call map_kernel_non_pse
[a35b458]146
[e3e4a2c]147 stack_init:
[a35b458]148
[873c681]149 /* Create the first stack frame */
150 pushl $0
151 movl %esp, %ebp
[a35b458]152
[e3e4a2c]153 pm2_status $status_prot3
[a35b458]154
[36df4109]155 /* Call ia32_pre_main(multiboot_eax, multiboot_ebx) */
[1f5c9c96]156 pushl multiboot_ebx
157 pushl multiboot_eax
[36df4109]158 call ia32_pre_main
[a35b458]159
[873c681]160 pm2_status $status_main
[a35b458]161
[873c681]162 /* Call main_bsp() */
[deca67b]163 call main_bsp
[a35b458]164
[873c681]165 /* Not reached */
[d47f0e1]166 cli
[421c833]167 hlt0:
168 hlt
169 jmp hlt0
[d47f0e1]170
[e3e4a2c]171/** Setup mapping for the kernel (PSE variant)
[873c681]172 *
173 * Setup mapping for both the unmapped and mapped sections
174 * of the kernel. For simplicity, we map the entire 4G space.
175 *
176 */
[8844e70]177FUNCTION_BEGIN(map_kernel_pse)
[b112055]178 /* Paging features */
[dcbc8be]179 movl %cr4, %ecx
[57c2a87]180 orl $CR4_PSE, %ecx /* PSE on */
181 andl $~CR4_PAE, %ecx /* PAE off */
[eaf6cd6]182 movl %ecx, %cr4
[a35b458]183
[eaf6cd6]184 movl $(page_directory + 0), %esi
185 movl $(page_directory + 2048), %edi
[cf27a6cb]186 xorl %ecx, %ecx
[e3e4a2c]187 xorl %ebx, %ebx
[a35b458]188
[e3e4a2c]189 floop_pse:
[a0d9abcd]190 movl $(PDE_4M | PDE_RW | PDE_P), %eax
[421c833]191 orl %ebx, %eax
[873c681]192 /* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
193 movl %eax, (%esi, %ecx, 4)
194 /* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
195 movl %eax, (%edi, %ecx, 4)
[e3e4a2c]196 addl $(4 * 1024 * 1024), %ebx
[a35b458]197
[421c833]198 incl %ecx
199 cmpl $512, %ecx
[e3e4a2c]200 jl floop_pse
[a35b458]201
[cf27a6cb]202 movl %esi, %cr3
[a35b458]203
[dcbc8be]204 movl %cr0, %ebx
[57c2a87]205 orl $CR0_PG, %ebx /* paging on */
[dcbc8be]206 movl %ebx, %cr0
[d47f0e1]207 ret
[8844e70]208FUNCTION_END(map_kernel_pse)
[dcbc8be]209
[e3e4a2c]210/** Setup mapping for the kernel (non-PSE variant).
211 *
212 * Setup mapping for both the unmapped and mapped sections
213 * of the kernel. For simplicity, we map the entire 4G space.
214 *
215 */
[8844e70]216FUNCTION_BEGIN(map_kernel_non_pse)
[e3e4a2c]217 /* Paging features */
218 movl %cr4, %ecx
[57c2a87]219 andl $~CR4_PAE, %ecx /* PAE off */
[e3e4a2c]220 movl %ecx, %cr4
[a35b458]221
[e3e4a2c]222 call calc_kernel_end
223 call find_mem_for_pt
[a35b458]224
[e3e4a2c]225 mov kernel_end, %esi
226 mov free_area, %ecx
[a35b458]227
[e3e4a2c]228 cmpl %esi, %ecx
229 jbe use_kernel_end
[a35b458]230
[e3e4a2c]231 mov %ecx, %esi
[a35b458]232
[e3e4a2c]233 /* Align address down to 4k */
[0637ddb]234 andl $(~(PAGE_SIZE - 1)), %esi
[a35b458]235
[e3e4a2c]236 use_kernel_end:
[a35b458]237
[e3e4a2c]238 /* Align address to 4k */
[0637ddb]239 addl $(PAGE_SIZE - 1), %esi
240 andl $(~(PAGE_SIZE - 1)), %esi
[a35b458]241
[e3e4a2c]242 /* Allocate space for page tables */
243 movl %esi, pt_loc
[0637ddb]244 movl $KA2PA(ballocs), %edi
[a35b458]245
[e3e4a2c]246 movl %esi, (%edi)
247 addl $4, %edi
248 movl $(2 * 1024 * 1024), (%edi)
[a35b458]249
[e3e4a2c]250 /* Fill page tables */
251 xorl %ecx, %ecx
252 xorl %ebx, %ebx
[a35b458]253
[e3e4a2c]254 floop_pt:
[a0d9abcd]255 movl $(PTE_RW | PTE_P), %eax
[e3e4a2c]256 orl %ebx, %eax
257 movl %eax, (%esi, %ecx, 4)
[0637ddb]258 addl $PAGE_SIZE, %ebx
[a35b458]259
[e3e4a2c]260 incl %ecx
261 cmpl $(512 * 1024), %ecx
[a35b458]262
[e3e4a2c]263 jl floop_pt
[a35b458]264
[e3e4a2c]265 /* Fill page directory */
266 movl $(page_directory + 0), %esi
267 movl $(page_directory + 2048), %edi
268 xorl %ecx, %ecx
269 movl pt_loc, %ebx
[a35b458]270
[e3e4a2c]271 floop:
[a0d9abcd]272 movl $(PDE_RW | PDE_P), %eax
[e3e4a2c]273 orl %ebx, %eax
[a35b458]274
[e3e4a2c]275 /* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
276 movl %eax, (%esi, %ecx, 4)
[a35b458]277
[e3e4a2c]278 /* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
279 movl %eax, (%edi, %ecx, 4)
[0637ddb]280 addl $PAGE_SIZE, %ebx
[a35b458]281
[e3e4a2c]282 incl %ecx
283 cmpl $512, %ecx
[a35b458]284
[e3e4a2c]285 jl floop
[a35b458]286
[e3e4a2c]287 movl %esi, %cr3
[a35b458]288
[e3e4a2c]289 movl %cr0, %ebx
[57c2a87]290 orl $CR0_PG, %ebx /* paging on */
[e3e4a2c]291 movl %ebx, %cr0
[a35b458]292
[e3e4a2c]293 ret
[8844e70]294FUNCTION_END(map_kernel_non_pse)
[e3e4a2c]295
296/** Calculate unmapped address of the end of the kernel. */
297calc_kernel_end:
[8a1afd2]298 movl $KA2PA(kdata_end), %edi
299 movl %edi, kernel_end
[e3e4a2c]300 ret
301
302/** Find free 2M (+4k for alignment) region where to store page tables */
303find_mem_for_pt:
304 /* Check if multiboot info is present */
[1f5c9c96]305 cmpl $MULTIBOOT_LOADER_MAGIC, multiboot_eax
[e3e4a2c]306 je check_multiboot_map
[a35b458]307
[e3e4a2c]308 ret
[a35b458]309
[e3e4a2c]310 check_multiboot_map:
[a35b458]311
[e3e4a2c]312 /* Copy address of the multiboot info to ebx */
[1f5c9c96]313 movl multiboot_ebx, %ebx
[a35b458]314
[e3e4a2c]315 /* Check if memory map flag is present */
316 movl (%ebx), %edx
[7ba16eb]317 andl $MULTIBOOT_INFO_FLAGS_MMAP, %edx
[e3e4a2c]318 jnz use_multiboot_map
[a35b458]319
[e3e4a2c]320 ret
[a35b458]321
[e3e4a2c]322 use_multiboot_map:
[a35b458]323
[e3e4a2c]324 /* Copy address of the memory map to edx */
[7ba16eb]325 movl MULTIBOOT_INFO_OFFSET_MMAP_ADDR(%ebx), %edx
[e3e4a2c]326 movl %edx, %ecx
[a35b458]327
[7ba16eb]328 addl MULTIBOOT_INFO_OFFSET_MMAP_LENGTH(%ebx), %ecx
[a35b458]329
[e3e4a2c]330 /* Find a free region at least 2M in size */
331 check_memmap_loop:
[a35b458]332
[e3e4a2c]333 /* Is this a free region? */
[7ba16eb]334 cmpl $MEMMAP_MEMORY_AVAILABLE, MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_TYPE(%edx)
[e3e4a2c]335 jnz next_region
[a35b458]336
[e3e4a2c]337 /* Check size */
[7ba16eb]338 cmpl $0, MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_SIZE + 4(%edx)
[e3e4a2c]339 jnz next_region
[7ba16eb]340 cmpl $(2 * 1024 * 1024 + PAGE_SIZE), MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_SIZE(%edx)
[e3e4a2c]341 jbe next_region
[a35b458]342
[7ba16eb]343 cmpl $0, MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_BASE_ADDRESS + 4(%edx)
[e3e4a2c]344 jz found_region
[a35b458]345
[e3e4a2c]346 next_region:
[a35b458]347
[e3e4a2c]348 cmp %ecx, %edx
349 jbe next_region_do
[a35b458]350
[e3e4a2c]351 ret
[a35b458]352
[e3e4a2c]353 next_region_do:
[a35b458]354
[7ba16eb]355 addl MULTIBOOT_MEMMAP_OFFSET_SIZE(%edx), %edx
356 addl $MULTIBOOT_MEMMAP_SIZE_SIZE, %edx
[e3e4a2c]357 jmp check_memmap_loop
[a35b458]358
[e3e4a2c]359 found_region:
[a35b458]360
[e3e4a2c]361 /* Use end of the found region */
[7ba16eb]362 mov MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_BASE_ADDRESS(%edx), %ecx
363 add MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_SIZE(%edx), %ecx
[e3e4a2c]364 sub $(2 * 1024 * 1024), %ecx
365 mov %ecx, free_area
[a35b458]366
[e3e4a2c]367 ret
368
[873c681]369/** Print string to EGA display (in light red) and halt.
370 *
371 * Should be executed from 32 bit protected mode with paging
372 * turned off. Stack is not required. This routine is used even
373 * if CONFIG_EGA is not enabled. Since we are going to halt the
374 * CPU anyway, it is always better to at least try to print
375 * some hints.
376 *
377 * @param %esi NULL-terminated string to print.
378 *
379 */
380pm_error_halt:
381 movl $0xb8000, %edi /* base of EGA text mode memory */
[eaf6cd6]382 xorl %eax, %eax
[a35b458]383
[873c681]384 /* Read bits 8 - 15 of the cursor address */
385 movw $0x3d4, %dx
[eaf6cd6]386 movb $0xe, %al
387 outb %al, %dx
[a35b458]388
[eaf6cd6]389 movw $0x3d5, %dx
390 inb %dx, %al
391 shl $8, %ax
[a35b458]392
[873c681]393 /* Read bits 0 - 7 of the cursor address */
394 movw $0x3d4, %dx
[eaf6cd6]395 movb $0xf, %al
396 outb %al, %dx
[a35b458]397
[eaf6cd6]398 movw $0x3d5, %dx
399 inb %dx, %al
[a35b458]400
[873c681]401 /* Sanity check for the cursor on screen */
402 cmp $2000, %ax
403 jb err_cursor_ok
[a35b458]404
[873c681]405 movw $1998, %ax
[a35b458]406
[873c681]407 err_cursor_ok:
[a35b458]408
[eaf6cd6]409 movw %ax, %bx
410 shl $1, %eax
411 addl %eax, %edi
[a35b458]412
[873c681]413 err_ploop:
[eaf6cd6]414 lodsb
[a35b458]415
[eaf6cd6]416 cmp $0, %al
[873c681]417 je err_ploop_end
[a35b458]418
[873c681]419 movb $0x0c, %ah /* black background, light red foreground */
[eaf6cd6]420 stosw
[a35b458]421
[873c681]422 /* Sanity check for the cursor on the last line */
[421c833]423 inc %bx
[873c681]424 cmp $2000, %bx
425 jb err_ploop
[a35b458]426
[873c681]427 /* Scroll the screen (24 rows) */
428 movl %esi, %edx
429 movl $0xb80a0, %esi
430 movl $0xb8000, %edi
[22c3444]431 movl $960, %ecx
432 rep movsl
[a35b458]433
[873c681]434 /* Clear the 24th row */
435 xorl %eax, %eax
[22c3444]436 movl $40, %ecx
437 rep stosl
[a35b458]438
[873c681]439 /* Go to row 24 */
440 movl %edx, %esi
441 movl $0xb8f00, %edi
442 movw $1920, %bx
[a35b458]443
[873c681]444 jmp err_ploop
445 err_ploop_end:
[a35b458]446
[873c681]447 /* Write bits 8 - 15 of the cursor address */
448 movw $0x3d4, %dx
[eaf6cd6]449 movb $0xe, %al
450 outb %al, %dx
[a35b458]451
[eaf6cd6]452 movw $0x3d5, %dx
453 movb %bh, %al
454 outb %al, %dx
[a35b458]455
[873c681]456 /* Write bits 0 - 7 of the cursor address */
457 movw $0x3d4, %dx
[eaf6cd6]458 movb $0xf, %al
459 outb %al, %dx
[a35b458]460
[eaf6cd6]461 movw $0x3d5, %dx
462 movb %bl, %al
463 outb %al, %dx
[a35b458]464
[421c833]465 cli
466 hlt1:
467 hlt
468 jmp hlt1
[22cf454d]469
[873c681]470/** Print string to EGA display (in light green).
471 *
472 * Should be called from 32 bit protected mode with paging
473 * turned off. A stack space of at least 24 bytes is required,
474 * but the function does not establish a stack frame.
475 *
476 * Macros such as pm_status take care that this function
477 * is used only when CONFIG_EGA is enabled.
478 *
479 * @param %esi NULL-terminated string to print.
480 *
481 */
482pm_early_puts:
483 pushl %eax
484 pushl %ebx
485 pushl %ecx
486 pushl %edx
487 pushl %edi
[a35b458]488
[873c681]489 movl $0xb8000, %edi /* base of EGA text mode memory */
490 xorl %eax, %eax
[a35b458]491
[873c681]492 /* Read bits 8 - 15 of the cursor address */
493 movw $0x3d4, %dx
494 movb $0xe, %al
495 outb %al, %dx
[a35b458]496
[873c681]497 movw $0x3d5, %dx
498 inb %dx, %al
499 shl $8, %ax
[a35b458]500
[873c681]501 /* Read bits 0 - 7 of the cursor address */
502 movw $0x3d4, %dx
503 movb $0xf, %al
504 outb %al, %dx
[a35b458]505
[873c681]506 movw $0x3d5, %dx
507 inb %dx, %al
[a35b458]508
[873c681]509 /* Sanity check for the cursor on screen */
510 cmp $2000, %ax
511 jb pm_puts_cursor_ok
[a35b458]512
[873c681]513 movw $1998, %ax
[a35b458]514
[873c681]515 pm_puts_cursor_ok:
[a35b458]516
[873c681]517 movw %ax, %bx
518 shl $1, %eax
519 addl %eax, %edi
[a35b458]520
[873c681]521 pm_puts_ploop:
522 lodsb
[a35b458]523
[873c681]524 cmp $0, %al
525 je pm_puts_ploop_end
[a35b458]526
[873c681]527 movb $0x0a, %ah /* black background, light green foreground */
528 stosw
[a35b458]529
[873c681]530 /* Sanity check for the cursor on the last line */
531 inc %bx
532 cmp $2000, %bx
533 jb pm_puts_ploop
[a35b458]534
[873c681]535 /* Scroll the screen (24 rows) */
536 movl %esi, %edx
537 movl $0xb80a0, %esi
538 movl $0xb8000, %edi
[22c3444]539 movl $960, %ecx
540 rep movsl
[a35b458]541
[873c681]542 /* Clear the 24th row */
543 xorl %eax, %eax
[22c3444]544 movl $40, %ecx
545 rep stosl
[a35b458]546
[873c681]547 /* Go to row 24 */
548 movl %edx, %esi
549 movl $0xb8f00, %edi
550 movw $1920, %bx
[a35b458]551
[873c681]552 jmp pm_puts_ploop
553 pm_puts_ploop_end:
[a35b458]554
[873c681]555 /* Write bits 8 - 15 of the cursor address */
556 movw $0x3d4, %dx
557 movb $0xe, %al
558 outb %al, %dx
[a35b458]559
[873c681]560 movw $0x3d5, %dx
561 movb %bh, %al
562 outb %al, %dx
[a35b458]563
[873c681]564 /* Write bits 0 - 7 of the cursor address */
565 movw $0x3d4, %dx
566 movb $0xf, %al
567 outb %al, %dx
[a35b458]568
[873c681]569 movw $0x3d5, %dx
570 movb %bl, %al
571 outb %al, %dx
[a35b458]572
[873c681]573 popl %edi
574 popl %edx
575 popl %ecx
576 popl %ebx
577 popl %eax
[a35b458]578
[873c681]579 ret
580
581/** Print string to EGA display.
582 *
583 * Should be called from 32 bit protected mode (with paging
584 * enabled and stack established). This function is ABI compliant.
585 *
586 * If CONFIG_EGA is undefined or CONFIG_FB is defined
587 * then this function does nothing.
588 *
589 * @param %ebp+0x08 NULL-terminated string to print.
590 *
591 */
592early_puts:
[a35b458]593
[873c681]594#if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB)))
[a35b458]595
[873c681]596 /* Prologue, save preserved registers */
597 pushl %ebp
598 movl %esp, %ebp
599 pushl %ebx
600 pushl %esi
601 pushl %edi
[a35b458]602
[873c681]603 movl 0x08(%ebp), %esi
604 movl $(PA2KA(0xb8000)), %edi /* base of EGA text mode memory */
605 xorl %eax, %eax
[a35b458]606
[873c681]607 /* Read bits 8 - 15 of the cursor address */
608 movw $0x3d4, %dx
609 movb $0xe, %al
610 outb %al, %dx
[a35b458]611
[873c681]612 movw $0x3d5, %dx
613 inb %dx, %al
614 shl $8, %ax
[a35b458]615
[873c681]616 /* Read bits 0 - 7 of the cursor address */
617 movw $0x3d4, %dx
618 movb $0xf, %al
619 outb %al, %dx
[a35b458]620
[873c681]621 movw $0x3d5, %dx
622 inb %dx, %al
[a35b458]623
[873c681]624 /* Sanity check for the cursor on screen */
625 cmp $2000, %ax
626 jb early_puts_cursor_ok
[a35b458]627
[873c681]628 movw $1998, %ax
[a35b458]629
[873c681]630 early_puts_cursor_ok:
[a35b458]631
[873c681]632 movw %ax, %bx
633 shl $1, %eax
634 addl %eax, %edi
[a35b458]635
[873c681]636 early_puts_ploop:
637 lodsb
[a35b458]638
[873c681]639 cmp $0, %al
640 je early_puts_ploop_end
[a35b458]641
[873c681]642 movb $0x0e, %ah /* black background, yellow foreground */
643 stosw
[a35b458]644
[873c681]645 /* Sanity check for the cursor on the last line */
646 inc %bx
647 cmp $2000, %bx
648 jb early_puts_ploop
[a35b458]649
[873c681]650 /* Scroll the screen (24 rows) */
651 movl %esi, %edx
652 movl $(PA2KA(0xb80a0)), %esi
653 movl $(PA2KA(0xb8000)), %edi
[22c3444]654 movl $960, %ecx
655 rep movsl
[a35b458]656
[873c681]657 /* Clear the 24th row */
658 xorl %eax, %eax
[22c3444]659 movl $40, %ecx
660 rep stosl
[a35b458]661
[873c681]662 /* Go to row 24 */
663 movl %edx, %esi
664 movl $(PA2KA(0xb8f00)), %edi
665 movw $1920, %bx
[a35b458]666
[873c681]667 jmp early_puts_ploop
668 early_puts_ploop_end:
[a35b458]669
[873c681]670 /* Write bits 8 - 15 of the cursor address */
671 movw $0x3d4, %dx
672 movb $0xe, %al
673 outb %al, %dx
[a35b458]674
[873c681]675 movw $0x3d5, %dx
676 movb %bh, %al
677 outb %al, %dx
[a35b458]678
[873c681]679 /* Write bits 0 - 7 of the cursor address */
680 movw $0x3d4, %dx
681 movb $0xf, %al
682 outb %al, %dx
[a35b458]683
[873c681]684 movw $0x3d5, %dx
685 movb %bl, %al
686 outb %al, %dx
[a35b458]687
[873c681]688 /* Epilogue, restore preserved registers */
689 popl %edi
690 popl %esi
691 popl %ebx
692 leave
[a35b458]693
[873c681]694#endif
[a35b458]695
[873c681]696 ret
697
[874e312a]698.section K_DATA_START, "aw", @progbits
[dcbc8be]699
700.align 4096
701page_directory:
702 .space 4096, 0
[eaf6cd6]703
[8844e70]704SYMBOL(bootstrap_idtr)
[f66c203d]705 .word 0
706 .long 0
707
[8844e70]708SYMBOL(bootstrap_gdtr)
[1d3d2cf]709 .word GDT_SELECTOR(GDT_ITEMS)
710 .long KA2PA(gdt)
711
[8844e70]712SYMBOL(multiboot_eax)
[7cb567cd]713 .long 0
[1f5c9c96]714
[8844e70]715SYMBOL(multiboot_ebx)
[7cb567cd]716 .long 0
717
[b112055]718pt_loc:
719 .long 0
[e3e4a2c]720kernel_end:
[b112055]721 .long 0
722free_area:
723 .long 0
724
[873c681]725status_prot:
726 .asciz "[prot] "
[e3e4a2c]727status_pse:
728 .asciz "[pse] "
729status_non_pse:
730 .asciz "[non_pse] "
[1f5c9c96]731status_multiboot_cmdline:
732 .asciz "[multiboot_cmdline] "
[873c681]733status_prot2:
734 .asciz "[prot2] "
[e3e4a2c]735status_prot3:
736 .asciz "[prot3] "
[873c681]737status_main:
738 .asciz "[main] "
Note: See TracBrowser for help on using the repository browser.