1/* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12/* 13 * Copyright 2016 Toomas Soome <tsoome@me.com> 14 */ 15 16#include <x86/specialreg.h> 17 18 .file "multiboot_tramp.s" 19 20/* 21 * The current dboot in illumos kernel is running in 32bit mode 22 * and expecting following 32-bit multiboot execution environment: 23 * 24 * EAX: MB magic 25 * EBX: 32-bit physical address of MBI 26 * CS: 32-bit read/execute code segment with offset 0 and limit 0xFFFFFFFF 27 * DS: 32-bit read/write code segment with offset 0 and limit 0xFFFFFFFF 28 * ES: 32-bit read/write code segment with offset 0 and limit 0xFFFFFFFF 29 * FS: 32-bit read/write code segment with offset 0 and limit 0xFFFFFFFF 30 * GS: 32-bit read/write code segment with offset 0 and limit 0xFFFFFFFF 31 * SS: 32-bit read/write data segment with offset 0 and limit 0xFFFFFFFF 32 * A20 enabled 33 * CR0: PG cleared, PE set 34 * EFLAGS: VM cleared, IF cleared 35 * interrupts disabled 36 */ 37 38 .set SEL_SCODE,0x8 39 .set SEL_SDATA,0x10 40 41 .text 42 .p2align 4 43 .globl multiboot_tramp 44 .type multiboot_tramp, STT_FUNC 45 46/* 47 * void multiboot_tramp(uint32_t magic, struct relocator *relocator, 48 * uint64_t entry) 49 */ 50multiboot_tramp: 51 cli 52 movq (%rsi), %rax 53 movq %rax, %rsp /* Switch to temporary stack. */ 54 movq 0x8(%rsi), %rax /* relocator->copy */ 55 pushq %rdi /* save magic */ 56 pushq %rdx /* save entry */ 57 movq %rsi, %rdi 58 callq *%rax 59 movq %rax, %rbx /* MBI */ 60 popq %rsi /* entry to rsi */ 61 popq %rdi /* restore magic */ 62 movq gdt@GOTPCREL(%rip), %rax 63 movq gdtaddr@GOTPCREL(%rip), %rdx 64 movq %rax, (%rdx) 65 movq gdtdesc@GOTPCREL(%rip), %rax 66 lgdt (%rax) 67 68 /* record the address */ 69 movq multiboot_tramp_2@GOTPCREL(%rip), %rcx 70 movq %rsp, %rax 71 pushq $SEL_SDATA 72 pushq %rax 73 pushf 74 pushq $SEL_SCODE 75 movq multiboot_tramp_1@GOTPCREL(%rip), %rax 76 pushq %rax 77 iretq 78 79 .code32 80multiboot_tramp_1: 81 movl $SEL_SDATA, %eax 82 movw %ax, %ss 83 movw %ax, %ds 84 movw %ax, %es 85 movw %ax, %fs 86 movw %ax, %gs 87 88 movl %cr0, %eax /* disable paging */ 89 btrl $31, %eax 90 movl %eax, %cr0 91 jmp *%ecx 92multiboot_tramp_2: 93 movl %cr4, %eax /* disable PAE, PGE, PSE */ 94 andl $~(CR4_PGE | CR4_PAE | CR4_PSE), %eax 95 movl %eax, %cr4 96 movl $MSR_EFER, %ecx 97 rdmsr /* updates %edx:%eax */ 98 btcl $8, %eax /* clear long mode */ 99 wrmsr 100 movl %edi, %eax /* magic */ 101 jmp *%esi /* jump to kernel */ 102 103/* GDT record */ 104 .p2align 4 105gdt: 106 .word 0x0, 0x0 /* NULL entry */ 107 .byte 0x0, 0x0, 0x0, 0x0 108 .word 0xffff, 0x0 /* code segment */ 109 .byte 0x0, 0x9a, 0xcf, 0x0 110 .word 0xffff, 0x0 /* data segment */ 111 .byte 0x0, 0x92, 0xcf, 0x0 112gdt_end: 113 114 .p2align 4 115gdtdesc: .word gdt_end - gdt - 1 /* limit */ 116gdtaddr: .long 0 /* base */ 117 .long 0 118 119multiboot_tramp_end: 120