xref: /openbsd/sys/arch/amd64/stand/libsa/run_amd64.S (revision 81621933)
1/*
2 * Copyright (c) 2019 Mike Larkin <mlarkin@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <machine/asm.h>
18#include <machine/specialreg.h>
19
20#define CODE_SEGMENT	0x8
21#define DATA_SEGMENT	0x10
22
23	.text
24	.code32
25	.global	launch_amd64_kernel_long
26	/*
27	 * void launch_amd64_kernel_long(caddr_t base, caddr_t pml4,
28	 *     caddr_t rsp, uint64_t entry, int boothowto, int bootdev,
29	 *     int bootapiver, uint64_t end, int extmem, int cnvmem,
30	 *     int ac, uint64_t av);
31	 */
32launch_amd64_kernel_long:
33asm_start:
34	xchg	%bx, %bx
35
36	/*
37	 * We are in 32 bit mode
38	 *  - compute indirect jump targets
39	 *  - compute GDT locations
40	 */
41	popl	%edi		/* Discard return address */
42	popl	%edi		/* %edi = bootloader base address */
43
44	/* Current mode -> 32 bit jump target */
45	leal	(prot_mode - asm_start)(%edi), %eax
46	movl	%eax, (start32r - asm_start)(%edi)
47
48	/* 32 bit -> 64 bit jump target */
49	leal	(long_mode - asm_start)(%edi), %eax
50	movl	%eax, (start64r - asm_start)(%edi)
51
52	/* Current mode -> 32 bit GDT */
53	leal	(gdt32 - asm_start)(%edi), %eax
54	movl	%eax, (gdtrr32 - asm_start)(%edi)
55
56	/* 32 bit -> 64 bit GDT */
57	leal	(gdt64 - asm_start)(%edi), %eax
58	movl	%eax, (gdtrr64 - asm_start)(%edi)
59
60	cli
61
62	lgdtl	(gdtr32 - asm_start)(%edi)
63
64	mov	%cr0,	%eax
65	orl	$(CR0_PE), %eax
66	mov	%eax,	%cr0
67
68	ljmpl	*(start32r - asm_start)(%edi)
69
70	.align 4
71prot_mode:
72	movw	$DATA_SEGMENT, %ax
73	movw	%ax, %ds
74	movw	%ax, %es
75	movw	%ax, %gs
76	movw	%ax, %ss
77	movw	%ax, %fs
78
79	mov	$(CR4_PAE | CR4_PSE), %eax
80	mov	%eax, %cr4
81
82	lgdtl	(gdtr64 - asm_start)(%edi)
83	movl	$MSR_EFER, %ecx
84	xorl	%edx, %edx
85	movl	$(EFER_LME | EFER_NXE | EFER_SCE), %eax
86	wrmsr
87
88	movl	(%esp), %eax	/* first arg - PML4 */
89	movl	4(%esp), %ebx	/* second arg - kernel stack */
90	movl	%eax, %cr3
91
92	jmp	1f
931:	jmp	1f
941:	movl	%cr0, %eax
95	orl	$CR0_DEFAULT, %eax
96	movl	%eax, %cr0
97
98	jmp	1f
991:	jmp	1f
1001:	ljmpl	*(start64r - asm_start)(%edi)
101
102long_mode:
103	.code64
104	movq	%rsp, %rax
105	movq	%rbx, %rsp
106
107	/*
108	 * params stack at %rax right now:
109	 *
110	 * +0	32 bit PML4 ptr
111	 * +4	32 bit kernel stack
112	 * +8	start va low bytes
113	 + +12  start va high bytes
114	 * +16	boothowto			(%rdi)
115	 * +20	bootdev				(%rsi)
116	 * +24	BOOTARG_APIVER			(%rdx)
117	 * +28	marks[MARK_END] low bytes	(%rcx)
118	 * +32	marks[MARK_END] high bytes	(%rcx)
119	 * +36	extmem		(%r8)
120	 * +40	cnvmem		(%r9)
121	 * +44	ac		(%rsp, will be %rsp + 8 after call below)
122	 * +48	av low bytes	(%rsp + 8, will be %rsp + 16 after call below)
123	 * +52	av high bytes	(%rsp + 16, will be %rsp + 24 after call below)
124	 */
125
126	movl	16(%rax),	%edi
127	movl	20(%rax),	%esi
128	movl	24(%rax),	%edx
129	movq	28(%rax),	%rcx
130	movl	36(%rax),	%r8d
131	movl	40(%rax),	%r9d
132	movq	48(%rax),	%rbx	/* av */
133	pushq	%rbx
134	movl	44(%rax),	%ebx	/* ac */
135	pushq	%rbx
136	movq	8(%rax),	%r11
137
138	/*
139	 * start(howto, bootdev, BOOTARG_APIVER, marks[MARK_END],
140	 *     extmem, cnvmem, ac, av);
141	 */
142	call	*%r11
143
144	cli
145	hlt
146	/* NOTREACHED */
147
148	.align	4
149start32r:
150	.long	0
151	.long	CODE_SEGMENT
152
153start64r:
154	.long	0
155	.long	CODE_SEGMENT
156
157gdt32:
158	.long	0, 0
159	.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x9f, 0xcf, 0x00
160	.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x93, 0xcf, 0x00
161gdtr32:
162	.word	gdtr32 - gdt32
163gdtrr32:
164	.quad
165
166	.align 8
167gdt64:
168        .quad   0x0000000000000000
169        .quad   0x00af9a000000ffff
170        .quad   0x00cf92000000ffff
171
172gdtr64:
173        .word   gdtr64 - gdt64
174gdtrr64:
175        .quad
176