/* * This file and its contents are supplied under the terms of the * Common Development and Distribution License ("CDDL"), version 1.0. * You may only use this file in accordance with the terms of version * 1.0 of the CDDL. * * A full copy of the text of the CDDL should have accompanied this * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* * Copyright 2016 Toomas Soome */ #include .file "multiboot_tramp.s" /* * dboot expects a 32-bit multiboot environment and to execute in 32-bit mode. * * EAX: MB magic * EBX: 32-bit physical address of MBI * CS: 32-bit read/execute code segment with offset 0 and limit 0xFFFFFFFF * DS: 32-bit read/write data segment with offset 0 and limit 0xFFFFFFFF * ES: 32-bit read/write data segment with offset 0 and limit 0xFFFFFFFF * FS: 32-bit read/write data segment with offset 0 and limit 0xFFFFFFFF * GS: 32-bit read/write data segment with offset 0 and limit 0xFFFFFFFF * SS: 32-bit read/write data segment with offset 0 and limit 0xFFFFFFFF * A20 enabled * CR0: PG cleared, PE set * EFLAGS: VM cleared, IF cleared * interrupts disabled */ .set SEL_SCODE,0x8 .set SEL_SDATA,0x10 .text .p2align 4 .globl multiboot_tramp .type multiboot_tramp, STT_FUNC /* * void multiboot_tramp(uint32_t magic, struct relocator *relocator, * vm_offset_t entry) */ multiboot_tramp: cli movq (%rsi), %rax movq %rax, %rsp /* Switch to temporary stack. */ movq 0x8(%rsi), %rax /* relocator->copy */ pushq %rdi /* save magic */ pushq %rdx /* save entry */ movq %rsi, %rdi callq *%rax movq %rax, %rbx /* MBI */ popq %rsi /* entry to rsi */ popq %rdi /* restore magic */ lea gdt(%rip), %rax lea gdtaddr(%rip), %rdx movq %rax, (%rdx) lea gdtdesc(%rip), %rax lgdt (%rax) /* record the address */ lea multiboot_tramp_2(%rip), %rcx movq %rsp, %rax pushq $SEL_SDATA pushq %rax pushf pushq $SEL_SCODE lea multiboot_tramp_1(%rip), %rax pushq %rax iretq .code32 multiboot_tramp_1: movl $SEL_SDATA, %eax movw %ax, %ss movw %ax, %ds movw %ax, %es movw %ax, %fs movw %ax, %gs movl %cr0, %eax /* disable paging */ btrl $31, %eax movl %eax, %cr0 jmp *%ecx multiboot_tramp_2: movl %cr4, %eax /* disable PAE, PGE, PSE */ andl $~(CR4_PGE | CR4_PAE | CR4_PSE), %eax movl %eax, %cr4 movl $MSR_EFER, %ecx rdmsr /* updates %edx:%eax */ btcl $8, %eax /* clear long mode */ wrmsr movl %edi, %eax /* magic */ jmp *%esi /* jump to kernel */ /* GDT record */ .p2align 4 gdt: /* * This will create access for 4GB flat memory with * base = 0x00000000, segment limit = 0xffffffff * page granulariy 4k * 32-bit protected mode * ring 0 * code segment is executable RW * data segment is not-executable RW */ .word 0x0, 0x0 /* NULL entry */ .byte 0x0, 0x0, 0x0, 0x0 .word 0xffff, 0x0 /* code segment */ .byte 0x0, 0x9a, 0xcf, 0x0 .word 0xffff, 0x0 /* data segment */ .byte 0x0, 0x92, 0xcf, 0x0 gdt_end: .p2align 4 gdtdesc: .word gdt_end - gdt - 1 /* limit */ gdtaddr: .long 0 /* base */ .long 0 multiboot_tramp_end: