xref: /titanic_52/usr/src/boot/sys/boot/efi/loader/arch/amd64/multiboot_tramp.S (revision 59dfa57d51ab43df898b757f7913486cd6da89cb)
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