xref: /openbsd/sys/arch/amd64/stand/efiboot/run_i386.S (revision 73471bf0)
1/*	$OpenBSD: run_i386.S,v 1.1 2015/09/02 01:52:26 yasuoka Exp $	*/
2
3/*
4 * Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <machine/asm.h>
20#include <machine/specialreg.h>
21
22#define	CODE_SEGMENT	0x10
23#define	DATA_SEGMENT	0x18
24
25	.globl _C_LABEL(run_i386_size)
26_C_LABEL(run_i386_size):
27	.long run_i386_end - _C_LABEL(run_i386_start)
28
29	.align	4
30	.text
31	.globl	_C_LABEL(run_i386_start)
32_C_LABEL(run_i386_start):
33start:
34	/*
35	 * run_i386(_start) is to call the loaded kernel's start() with
36	 * 32bit segment mode from x64 mode.
37	 * %rdi == loaded start address, %rsi == kernel start address
38	 */
39
40	/* re-arrange the parameters for the x86 calling convension */
41	mov	%edx, (run_i386_end - start - 0x20)(%rdi)
42	mov	%ecx, (run_i386_end - start - 0x1c)(%rdi)
43	mov	%r8d, (run_i386_end - start - 0x18)(%rdi)
44	mov	%r9d, (run_i386_end - start - 0x14)(%rdi)
45	mov	0x8(%rsp), %edx
46	mov	%edx, (run_i386_end - start - 0x10)(%rdi)
47	mov	0x10(%rsp), %edx
48	mov	%edx, (run_i386_end - start - 0xc)(%rdi)
49	mov	0x18(%rsp), %edx
50	mov	%edx, (run_i386_end - start - 0x8)(%rdi)
51	mov	0x20(%rsp), %edx
52	mov	%edx, (run_i386_end - start - 0x4)(%rdi)
53
54	/* Prepare jump address */
55	lea	(start32a - start)(%rdi), %rax
56	movl	%eax, (start32r - start)(%rdi)
57
58	cli
59
60	/* Setup GDT */
61	lea	(gdt - start)(%rdi), %rax
62	mov	%rax, (gdtrr - start)(%rdi)
63	lgdt	(gdtr - start)(%rdi)
64
65	/* Jump to set %cs */
66	ljmp	*(start32r - start)(%rdi)
67
68	.align	4
69start32a:
70	.code32
71	movl	$DATA_SEGMENT, %eax
72	movl	%eax, %ds
73	movl	%eax, %es
74	movl	%eax, %fs
75	movl	%eax, %gs
76	movl	%eax, %ss
77
78	lea	(run_i386_end - start - 0x20)(%edi), %eax
79	mov	%eax, %esp
80
81	/* Disable Paging in CR0 */
82	movl	%cr0, %eax
83	andl	$(~CR0_PG), %eax
84	movl	%eax, %cr0
85
86	/* Disable PAE in CR4 */
87	movl	%cr4, %eax
88	andl	$(~CR4_PAE), %eax
89	movl	%eax, %cr4
90
91	jmp	start32b
92start32b:
93	.code32
94
95	call	*%esi
96
97	.align	4
98start32r:
99	.long	0
100	.long	CODE_SEGMENT
101	.align	4
102gdt:
103	.long	0, 0
104	.long	0, 0
105	.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x9f, 0xcf, 0x00
106	.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x93, 0xcf, 0x00
107gdtr:
108	.word	gdtr - gdt
109gdtrr:
110	.quad
111start32end:
112	/* Space for the stack */
113	.align	4
114	.space	8192
115run_i386_end:
116