HelenOS sources
#include <abi/asmtool.h>
#include <arch/boot/boot.h>
#include <arch/mm/page.h>
#include <arch/mm/ptl.h>
#include <arch/pm.h>
#include <genarch/multiboot/multiboot.h>
#include <arch/cpuid.h>
#include <arch/cpu.h>
#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
.section K_TEXT_START, "ax"
.code32
.macro pm_error msg
movl \msg, %esi
jmp pm_error_halt
.endm
.macro pm_status msg
#ifdef CONFIG_EGA
pushl %esi
movl \msg, %esi
call pm_early_puts
popl %esi
#endif
.endm
.macro pm2_status msg
#ifndef CONFIG_FB
pm_status \msg
#endif
.endm
.align 4
multiboot_header:
.long MULTIBOOT_HEADER_MAGIC
.long MULTIBOOT_HEADER_FLAGS
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
.long multiboot_header
.long unmapped_start
.long 0
.long 0
.long multiboot_image_start
SYMBOL(multiboot_image_start)
cli
cld
movl $START_STACK, %esp
lgdtl bootstrap_gdtr
lidtl bootstrap_idtr
movw $GDT_SELECTOR(KDATA_DES), %cx
movw %cx, %es
movw %cx, %ds
movw %cx, %ss
movw $GDT_SELECTOR(UDATA_DES), %cx
movw %cx, %fs
movw %cx, %gs
jmpl $GDT_SELECTOR(KTEXT32_DES), $multiboot_meeting_point
multiboot_meeting_point:
movl %eax, multiboot_eax
movl %ebx, multiboot_ebx
pm_status $status_prot
movl $(INTEL_CPUID_EXTENDED), %eax
cpuid
cmp $(INTEL_CPUID_EXTENDED), %eax
ja extended_cpuid_supported
pm_error $err_extended_cpuid
extended_cpuid_supported:
movl $(AMD_CPUID_EXTENDED), %eax
cpuid
bt $(AMD_EXT_LONG_MODE), %edx
jc long_mode_supported
pm_error $err_long_mode
long_mode_supported:
bt $(AMD_EXT_NOEXECUTE), %edx
jc noexecute_supported
pm_error $err_noexecute
noexecute_supported:
movl $(INTEL_CPUID_STANDARD), %eax
cpuid
bt $(INTEL_FXSAVE), %edx
jc fx_supported
pm_error $err_fx
fx_supported:
bt $(INTEL_SSE2), %edx
jc sse2_supported
pm_error $err_sse2
sse2_supported:
#include "vesa_prot.inc"
pm2_status $status_prot2
movl %cr4, %eax
orl $CR4_PAE, %eax
movl %eax, %cr4
leal ptl_0, %eax
movl %eax, %cr3
movl $AMD_MSR_EFER, %ecx
rdmsr
orl $AMD_LME, %eax
wrmsr
movl %cr0, %eax
orl $CR0_PG, %eax
movl %eax, %cr0
jmpl $GDT_SELECTOR(KTEXT_DES), $start64
pm_error_halt:
movl $0xb8000, %edi
xorl %eax, %eax
movw $0x3d4, %dx
movb $0xe, %al
outb %al, %dx
movw $0x3d5, %dx
inb %dx, %al
shl $8, %ax
movw $0x3d4, %dx
movb $0xf, %al
outb %al, %dx
movw $0x3d5, %dx
inb %dx, %al
cmp $2000, %ax
jb err_cursor_ok
movw $1998, %ax
err_cursor_ok:
movw %ax, %bx
shl $1, %eax
addl %eax, %edi
err_ploop:
lodsb
cmp $0, %al
je err_ploop_end
movb $0x0c, %ah
stosw
inc %bx
cmp $2000, %bx
jb err_ploop
movl %esi, %edx
movl $0xb80a0, %esi
movl $0xb8000, %edi
movl $960, %ecx
rep movsl
xorl %eax, %eax
movl $40, %ecx
rep stosl
movl %edx, %esi
movl $0xb8f00, %edi
movw $1920, %bx
jmp err_ploop
err_ploop_end:
movw $0x3d4, %dx
movb $0xe, %al
outb %al, %dx
movw $0x3d5, %dx
movb %bh, %al
outb %al, %dx
movw $0x3d4, %dx
movb $0xf, %al
outb %al, %dx
movw $0x3d5, %dx
movb %bl, %al
outb %al, %dx
cli
hlt1:
hlt
jmp hlt1
pm_early_puts:
pushl %eax
pushl %ebx
pushl %ecx
pushl %edx
pushl %edi
movl $0xb8000, %edi
xorl %eax, %eax
movw $0x3d4, %dx
movb $0xe, %al
outb %al, %dx
movw $0x3d5, %dx
inb %dx, %al
shl $8, %ax
movw $0x3d4, %dx
movb $0xf, %al
outb %al, %dx
movw $0x3d5, %dx
inb %dx, %al
cmp $2000, %ax
jb pm_puts_cursor_ok
movw $1998, %ax
pm_puts_cursor_ok:
movw %ax, %bx
shl $1, %eax
addl %eax, %edi
pm_puts_ploop:
lodsb
cmp $0, %al
je pm_puts_ploop_end
movb $0x0a, %ah
stosw
inc %bx
cmp $2000, %bx
jb pm_puts_ploop
movl %esi, %edx
movl $0xb80a0, %esi
movl $0xb8000, %edi
movl $960, %ecx
rep movsl
xorl %eax, %eax
movl $40, %ecx
rep stosl
movl %edx, %esi
movl $0xb8f00, %edi
movw $1920, %bx
jmp pm_puts_ploop
pm_puts_ploop_end:
movw $0x3d4, %dx
movb $0xe, %al
outb %al, %dx
movw $0x3d5, %dx
movb %bh, %al
outb %al, %dx
movw $0x3d4, %dx
movb $0xf, %al
outb %al, %dx
movw $0x3d5, %dx
movb %bl, %al
outb %al, %dx
popl %edi
popl %edx
popl %ecx
popl %ebx
popl %eax
ret
.code64
.macro long_status msg
pushq %rdi
movq \msg, %rdi
call early_puts
popq %rdi
.endm
start64:
movq $(PA2KA(START_STACK)), %rsp
pushq $0
movq %rsp, %rbp
long_status $status_long
movl multiboot_eax, %edi
movl multiboot_ebx, %esi
#ifdef MEMORY_MODEL_large
movabsq $amd64_pre_main, %rax
callq *%rax
#else
callq amd64_pre_main
#endif
long_status $status_main
#ifdef MEMORY_MODEL_large
movabsq $main_bsp, %rax
callq *%rax
#else
callq main_bsp
#endif
cli
hlt0:
hlt
jmp hlt0
early_puts:
#if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB)))
pushq %rbp
movq %rsp, %rbp
pushq %rbx
movq %rdi, %rsi
movq $(PA2KA(0xb8000)), %rdi
xorq %rax, %rax
movw $0x3d4, %dx
movb $0xe, %al
outb %al, %dx
movw $0x3d5, %dx
inb %dx, %al
shl $8, %ax
movw $0x3d4, %dx
movb $0xf, %al
outb %al, %dx
movw $0x3d5, %dx
inb %dx, %al
cmp $2000, %ax
jb early_puts_cursor_ok
movw $1998, %ax
early_puts_cursor_ok:
movw %ax, %bx
shl $1, %rax
addq %rax, %rdi
early_puts_ploop:
lodsb
cmp $0, %al
je early_puts_ploop_end
movb $0x0e, %ah
stosw
inc %bx
cmp $2000, %bx
jb early_puts_ploop
movq %rsi, %rdx
movq $(PA2KA(0xb80a0)), %rsi
movq $(PA2KA(0xb8000)), %rdi
movl $480, %ecx
rep movsq
xorl %eax, %eax
movl $20, %ecx
rep stosq
movq %rdx, %rsi
movq $(PA2KA(0xb8f00)), %rdi
movw $1920, %bx
jmp early_puts_ploop
early_puts_ploop_end:
movw $0x3d4, %dx
movb $0xe, %al
outb %al, %dx
movw $0x3d5, %dx
movb %bh, %al
outb %al, %dx
movw $0x3d4, %dx
movb $0xf, %al
outb %al, %dx
movw $0x3d5, %dx
movb %bl, %al
outb %al, %dx
popq %rbx
leave
#endif
ret
#include "vesa_real.inc"
.section K_INI_PTLS, "aw", @progbits
.macro ptl2gen cnt g
.if \cnt
ptl2gen "\cnt - 8" \g
.quad ((\cnt - 8) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad ((\cnt - 7) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad ((\cnt - 6) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad ((\cnt - 5) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad ((\cnt - 4) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad ((\cnt - 3) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad ((\cnt - 2) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.quad ((\cnt - 1) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
.endif
.endm
.align 4096
ptl_2_0g:
ptl2gen 512 0
.align 4096
ptl_2_1g:
ptl2gen 512 1
.align 4096
ptl_2_2g:
ptl2gen 512 2
.align 4096
ptl_2_3g:
ptl2gen 512 3
.align 4096
ptl_2_4g:
ptl2gen 512 4
.align 4096
ptl_2_5g:
ptl2gen 512 5
.align 4096
ptl_2_6g:
ptl2gen 512 6
.align 4096
ptl_2_7g:
ptl2gen 512 7
#ifdef MEMORY_MODEL_kernel
.align 4096
ptl_1:
.quad ptl_2_0g + (PTL_WRITABLE | PTL_PRESENT)
.quad ptl_2_1g + (PTL_WRITABLE | PTL_PRESENT)
.quad ptl_2_2g + (PTL_WRITABLE | PTL_PRESENT)
.quad ptl_2_3g + (PTL_WRITABLE | PTL_PRESENT)
.quad ptl_2_4g + (PTL_WRITABLE | PTL_PRESENT)
.quad ptl_2_5g + (PTL_WRITABLE | PTL_PRESENT)
.quad ptl_2_6g + (PTL_WRITABLE | PTL_PRESENT)
.quad ptl_2_7g + (PTL_WRITABLE | PTL_PRESENT)
.fill 502, 8, 0
.quad ptl_2_0g + (PTL_WRITABLE | PTL_PRESENT)
.quad ptl_2_1g + (PTL_WRITABLE | PTL_PRESENT)
.align 4096
SYMBOL(ptl_0)
.quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT)
.fill 510, 8, 0
.quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT)
#endif
#ifdef MEMORY_MODEL_large
.align 4096
ptl_1:
.quad ptl_2_0g + (PTL_WRITABLE | PTL_PRESENT)
.quad ptl_2_1g + (PTL_WRITABLE | PTL_PRESENT)
.quad ptl_2_2g + (PTL_WRITABLE | PTL_PRESENT)
.quad ptl_2_3g + (PTL_WRITABLE | PTL_PRESENT)
.quad ptl_2_4g + (PTL_WRITABLE | PTL_PRESENT)
.quad ptl_2_5g + (PTL_WRITABLE | PTL_PRESENT)
.quad ptl_2_6g + (PTL_WRITABLE | PTL_PRESENT)
.quad ptl_2_7g + (PTL_WRITABLE | PTL_PRESENT)
.fill 504, 8, 0
.align 4096
SYMBOL(ptl_0)
.quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT)
.fill 255, 8, 0
.quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT)
.fill 255, 8, 0
#endif
.section K_DATA_START, "aw", @progbits
SYMBOL(bootstrap_idtr)
.word 0
.long 0
SYMBOL(bootstrap_gdtr)
.word GDT_SELECTOR(GDT_ITEMS)
.long KA2PA(gdt)
SYMBOL(multiboot_eax)
.long 0
SYMBOL(multiboot_ebx)
.long 0
err_extended_cpuid:
.asciz "Error: Extended CPUID not supported -- CPU is not 64-bit. System halted."
err_long_mode:
.asciz "Error: 64-bit long mode not supported. System halted."
err_noexecute:
.asciz "Error: No-execute pages not supported. System halted."
err_fx:
.asciz "Error: FXSAVE/FXRESTORE instructions not supported. System halted."
err_sse2:
.asciz "Error: SSE2 instructions not supported. System halted."
status_prot:
.asciz "[prot] "
status_vesa_copy:
.asciz "[vesa_copy] "
status_multiboot_cmdline:
.asciz "[multiboot_cmdline] "
status_vesa_real:
.asciz "[vesa_real] "
status_prot2:
.asciz "[prot2] "
status_long:
.asciz "[long] "
status_main:
.asciz "[main] "
HelenOS homepage, sources at GitHub