source: mainline/kernel/arch/ia32/src/boot/multiboot.S@ 76d0981d

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

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 14.4 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
[873c681]40#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
[66def8d]41
[874e312a]42.section K_TEXT_START, "ax"
[f761f1eb]43
[b0bf501]44.code32
[873c681]45
46.macro pm_error msg
47 movl \msg, %esi
48 jmp pm_error_halt
49.endm
50
51.macro pm_status msg
52#ifdef CONFIG_EGA
53 pushl %esi
54 movl \msg, %esi
55 call pm_early_puts
56 popl %esi
57#endif
58.endm
59
60.macro pm2_status msg
61 pushl \msg
62 call early_puts
63.endm
64
[f9447155]65.align 4
66multiboot_header:
67 .long MULTIBOOT_HEADER_MAGIC
68 .long MULTIBOOT_HEADER_FLAGS
[873c681]69 .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) /* checksum */
[66def8d]70 .long multiboot_header
71 .long unmapped_ktext_start
[f9447155]72 .long 0
73 .long 0
[66def8d]74 .long multiboot_image_start
[421c833]75
[8844e70]76SYMBOL(multiboot_image_start)
[f66c203d]77 cli
[e13daa5d]78 cld
[a35b458]79
[873c681]80 /* Initialize stack pointer */
81 movl $START_STACK, %esp
[a35b458]82
[f66c203d]83 /*
84 * Initialize Global Descriptor Table and
85 * Interrupt Descriptor Table registers
86 */
[1d3d2cf]87 lgdtl bootstrap_gdtr
[f66c203d]88 lidtl bootstrap_idtr
[a35b458]89
[873c681]90 /* Kernel data + stack */
[1d3d2cf]91 movw $GDT_SELECTOR(KDATA_DES), %cx
[5eb1379]92 movw %cx, %es
93 movw %cx, %fs
[ff133e2]94 movw %cx, %gs
[873c681]95 movw %cx, %ds
[5eb1379]96 movw %cx, %ss
[a35b458]97
[1d3d2cf]98 jmpl $GDT_SELECTOR(KTEXT_DES), $multiboot_meeting_point
[4533601]99 multiboot_meeting_point:
[a35b458]100
[1f5c9c96]101 /* Save multiboot arguments */
102 movl %eax, multiboot_eax
103 movl %ebx, multiboot_ebx
[a35b458]104
[873c681]105 pm_status $status_prot
[a35b458]106
[421c833]107#include "vesa_prot.inc"
[a35b458]108
[e3e4a2c]109#ifndef PROCESSOR_i486
[a35b458]110
[e3e4a2c]111 pm_status $status_prot2
[a35b458]112
[e3e4a2c]113 movl $(INTEL_CPUID_LEVEL), %eax
114 cpuid
115 cmp $0x0, %eax /* any function > 0? */
116 jbe pse_unsupported
[a35b458]117
[e3e4a2c]118 movl $(INTEL_CPUID_STANDARD), %eax
119 cpuid
120 bt $(INTEL_PSE), %edx
121 jnc pse_unsupported
[a35b458]122
[e3e4a2c]123 /* Map kernel and turn paging on */
124 pm_status $status_pse
125 call map_kernel_pse
126 jmp stack_init
[a35b458]127
[e3e4a2c]128#endif /* PROCESSOR_i486 */
[a35b458]129
[e3e4a2c]130 pse_unsupported:
[a35b458]131
[e3e4a2c]132 /* Map kernel and turn paging on */
133 pm_status $status_non_pse
[fb45c7b]134 call map_kernel_non_pse
[a35b458]135
[e3e4a2c]136 stack_init:
[a35b458]137
[873c681]138 /* Create the first stack frame */
139 pushl $0
140 movl %esp, %ebp
[a35b458]141
[e3e4a2c]142 pm2_status $status_prot3
[a35b458]143
[36df4109]144 /* Call ia32_pre_main(multiboot_eax, multiboot_ebx) */
[1f5c9c96]145 pushl multiboot_ebx
146 pushl multiboot_eax
[36df4109]147 call ia32_pre_main
[a35b458]148
[873c681]149 pm2_status $status_main
[a35b458]150
[873c681]151 /* Call main_bsp() */
[deca67b]152 call main_bsp
[a35b458]153
[873c681]154 /* Not reached */
[d47f0e1]155 cli
[421c833]156 hlt0:
157 hlt
158 jmp hlt0
[d47f0e1]159
[e3e4a2c]160/** Setup mapping for the kernel (PSE variant)
[873c681]161 *
162 * Setup mapping for both the unmapped and mapped sections
163 * of the kernel. For simplicity, we map the entire 4G space.
164 *
165 */
[8844e70]166FUNCTION_BEGIN(map_kernel_pse)
[b112055]167 /* Paging features */
[dcbc8be]168 movl %cr4, %ecx
[57c2a87]169 orl $CR4_PSE, %ecx /* PSE on */
170 andl $~CR4_PAE, %ecx /* PAE off */
[eaf6cd6]171 movl %ecx, %cr4
[a35b458]172
[eaf6cd6]173 movl $(page_directory + 0), %esi
174 movl $(page_directory + 2048), %edi
[cf27a6cb]175 xorl %ecx, %ecx
[e3e4a2c]176 xorl %ebx, %ebx
[a35b458]177
[e3e4a2c]178 floop_pse:
[a0d9abcd]179 movl $(PDE_4M | PDE_RW | PDE_P), %eax
[421c833]180 orl %ebx, %eax
[873c681]181 /* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
182 movl %eax, (%esi, %ecx, 4)
183 /* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
184 movl %eax, (%edi, %ecx, 4)
[e3e4a2c]185 addl $(4 * 1024 * 1024), %ebx
[a35b458]186
[421c833]187 incl %ecx
188 cmpl $512, %ecx
[e3e4a2c]189 jl floop_pse
[a35b458]190
[cf27a6cb]191 movl %esi, %cr3
[a35b458]192
[dcbc8be]193 movl %cr0, %ebx
[57c2a87]194 orl $CR0_PG, %ebx /* paging on */
[dcbc8be]195 movl %ebx, %cr0
[d47f0e1]196 ret
[8844e70]197FUNCTION_END(map_kernel_pse)
[dcbc8be]198
[e3e4a2c]199/** Setup mapping for the kernel (non-PSE variant).
200 *
201 * Setup mapping for both the unmapped and mapped sections
202 * of the kernel. For simplicity, we map the entire 4G space.
203 *
204 */
[8844e70]205FUNCTION_BEGIN(map_kernel_non_pse)
[e3e4a2c]206 /* Paging features */
207 movl %cr4, %ecx
[57c2a87]208 andl $~CR4_PAE, %ecx /* PAE off */
[e3e4a2c]209 movl %ecx, %cr4
[a35b458]210
[e3e4a2c]211 call calc_kernel_end
212 call find_mem_for_pt
[a35b458]213
[e3e4a2c]214 mov kernel_end, %esi
215 mov free_area, %ecx
[a35b458]216
[e3e4a2c]217 cmpl %esi, %ecx
218 jbe use_kernel_end
[a35b458]219
[e3e4a2c]220 mov %ecx, %esi
[a35b458]221
[e3e4a2c]222 /* Align address down to 4k */
[0637ddb]223 andl $(~(PAGE_SIZE - 1)), %esi
[a35b458]224
[e3e4a2c]225 use_kernel_end:
[a35b458]226
[e3e4a2c]227 /* Align address to 4k */
[0637ddb]228 addl $(PAGE_SIZE - 1), %esi
229 andl $(~(PAGE_SIZE - 1)), %esi
[a35b458]230
[e3e4a2c]231 /* Allocate space for page tables */
232 movl %esi, pt_loc
[0637ddb]233 movl $KA2PA(ballocs), %edi
[a35b458]234
[e3e4a2c]235 movl %esi, (%edi)
236 addl $4, %edi
237 movl $(2 * 1024 * 1024), (%edi)
[a35b458]238
[e3e4a2c]239 /* Fill page tables */
240 xorl %ecx, %ecx
241 xorl %ebx, %ebx
[a35b458]242
[e3e4a2c]243 floop_pt:
[a0d9abcd]244 movl $(PTE_RW | PTE_P), %eax
[e3e4a2c]245 orl %ebx, %eax
246 movl %eax, (%esi, %ecx, 4)
[0637ddb]247 addl $PAGE_SIZE, %ebx
[a35b458]248
[e3e4a2c]249 incl %ecx
250 cmpl $(512 * 1024), %ecx
[a35b458]251
[e3e4a2c]252 jl floop_pt
[a35b458]253
[e3e4a2c]254 /* Fill page directory */
255 movl $(page_directory + 0), %esi
256 movl $(page_directory + 2048), %edi
257 xorl %ecx, %ecx
258 movl pt_loc, %ebx
[a35b458]259
[e3e4a2c]260 floop:
[a0d9abcd]261 movl $(PDE_RW | PDE_P), %eax
[e3e4a2c]262 orl %ebx, %eax
[a35b458]263
[e3e4a2c]264 /* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
265 movl %eax, (%esi, %ecx, 4)
[a35b458]266
[e3e4a2c]267 /* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
268 movl %eax, (%edi, %ecx, 4)
[0637ddb]269 addl $PAGE_SIZE, %ebx
[a35b458]270
[e3e4a2c]271 incl %ecx
272 cmpl $512, %ecx
[a35b458]273
[e3e4a2c]274 jl floop
[a35b458]275
[e3e4a2c]276 movl %esi, %cr3
[a35b458]277
[e3e4a2c]278 movl %cr0, %ebx
[57c2a87]279 orl $CR0_PG, %ebx /* paging on */
[e3e4a2c]280 movl %ebx, %cr0
[a35b458]281
[e3e4a2c]282 ret
[8844e70]283FUNCTION_END(map_kernel_non_pse)
[e3e4a2c]284
285/** Calculate unmapped address of the end of the kernel. */
286calc_kernel_end:
[0637ddb]287 movl $KA2PA(hardcoded_load_address), %edi
[e3e4a2c]288 movl (%edi), %esi
[0637ddb]289 leal KA2PA(0)(%esi), %esi
[a35b458]290
[0637ddb]291 movl $KA2PA(hardcoded_ktext_size), %edi
[e3e4a2c]292 addl (%edi), %esi
[0637ddb]293 leal KA2PA(0)(%esi), %esi
[a35b458]294
[0637ddb]295 movl $KA2PA(hardcoded_kdata_size), %edi
[e3e4a2c]296 addl (%edi), %esi
[0637ddb]297 leal KA2PA(0)(%esi), %esi
[e3e4a2c]298 movl %esi, kernel_end
[a35b458]299
[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
[421c833]698#include "vesa_real.inc"
[22cf454d]699
[874e312a]700.section K_DATA_START, "aw", @progbits
[dcbc8be]701
702.align 4096
703page_directory:
704 .space 4096, 0
[eaf6cd6]705
[8844e70]706SYMBOL(bootstrap_idtr)
[f66c203d]707 .word 0
708 .long 0
709
[8844e70]710SYMBOL(bootstrap_gdtr)
[1d3d2cf]711 .word GDT_SELECTOR(GDT_ITEMS)
712 .long KA2PA(gdt)
713
[8844e70]714SYMBOL(multiboot_eax)
[7cb567cd]715 .long 0
[1f5c9c96]716
[8844e70]717SYMBOL(multiboot_ebx)
[7cb567cd]718 .long 0
719
[b112055]720pt_loc:
721 .long 0
[e3e4a2c]722kernel_end:
[b112055]723 .long 0
724free_area:
725 .long 0
726
[873c681]727status_prot:
728 .asciz "[prot] "
[e3e4a2c]729status_pse:
730 .asciz "[pse] "
731status_non_pse:
732 .asciz "[non_pse] "
[873c681]733status_vesa_copy:
734 .asciz "[vesa_copy] "
[1f5c9c96]735status_multiboot_cmdline:
736 .asciz "[multiboot_cmdline] "
[873c681]737status_vesa_real:
738 .asciz "[vesa_real] "
739status_prot2:
740 .asciz "[prot2] "
[e3e4a2c]741status_prot3:
742 .asciz "[prot3] "
[873c681]743status_main:
744 .asciz "[main] "
Note: See TracBrowser for help on using the repository browser.