xref: /freebsd/stand/efi/loader/arch/i386/amd64_tramp.S (revision 7937bfbc0ca53fe7cdd0d54414f9296e273a518e)
1/*-
2 * Copyright (c) 2013 The FreeBSD Foundation
3 * Copyright (c) 2023 Ahmad Khalifa <ahmadkhalifa570@gmail.com>
4 *
5 * This software was developed by Benno Rice under sponsorship from
6 * the FreeBSD Foundation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <machine/asmacros.h>
30
31	.text
32	.globl	amd64_tramp
33
34/*
35 * void amd64_tramp(uint32_t stack, void *copy_finish, uint32_t kernend,
36 * 		    uint32_t modulep, uint32_t pagetable, uint32_t gdtr, uint64_t entry)
37 */
38amd64_tramp:
39	cli	/* Make sure we don't get interrupted. */
40
41	calll *8(%esp)	/* Call copy_finish so we're all ready to go. */
42
43	movl %cr0, %eax	/* Paging may be enabled, disable it. */
44	andl $0x7FFFFFFF, %eax
45	movl %eax, %cr0
46
47	movl %cr4, %eax	/* PAE may be disabled, enable it. */
48	orl $0x20, %eax
49	movl %eax, %cr4
50
51	movl 20(%esp), %eax	/* Swap page tables. */
52	movl %eax, %cr3
53
54	movl $0xC0000080, %ecx	/* Enable long mode. */
55	rdmsr
56	orl $0x100, %eax
57	wrmsr
58
59	movl 12(%esp), %edi	/* Stash the kernel and GDT values for later. */
60	movl 16(%esp), %esi
61	movl 24(%esp), %ebx
62	movl 28(%esp), %edx
63	movl 32(%esp), %ebp
64
65	movl 4(%esp), %esp	/* Switch to our temporary stack. */
66
67	movl %cr0, %eax	/* Enable paging and enter compatibility mode. */
68	orl $0x80000000, %eax
69	movl %eax, %cr0
70
71	lgdtl (%ebx)	/* Load GDT. */
72
73	pushl %edi	/* Push kernend. */
74	pushl %esi	/* Push modulep. */
75	pushl $0x0
76	pushl %ebp	/* Push 64-bit entry address. */
77	pushl %edx
78
79	calll 0f	/* Find the address of ".longmode". */
800:	popl %eax
81	addl $(.longmode-0b), %eax
82
83	pushl $0x8	/* Push CS. */
84	pushl %eax	/* Push the address. */
85	lretl	/* "Return" to 64-bit code. */
86
87	.code64
88
89.longmode:
90	retq	/* "Return" to kernel entry. */
91
92	.code32
93
94	ALIGN_TEXT
95amd64_tramp_end:
96
97	.data
98	.globl	amd64_tramp_size
99amd64_tramp_size:
100	.long	amd64_tramp_end-amd64_tramp
101