summaryrefslogtreecommitdiff
path: root/sys/arch/amd64/stand/efi32/run_i386.S
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/amd64/stand/efi32/run_i386.S')
-rw-r--r--sys/arch/amd64/stand/efi32/run_i386.S115
1 files changed, 115 insertions, 0 deletions
diff --git a/sys/arch/amd64/stand/efi32/run_i386.S b/sys/arch/amd64/stand/efi32/run_i386.S
new file mode 100644
index 00000000000..ccb423d0079
--- /dev/null
+++ b/sys/arch/amd64/stand/efi32/run_i386.S
@@ -0,0 +1,115 @@
+/* $OpenBSD: run_i386.S,v 1.1 2019/05/11 02:33:34 mlarkin Exp $ */
+
+/*
+ * Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <machine/asm.h>
+#include <machine/specialreg.h>
+
+#define CODE_SEGMENT 0x10
+#define DATA_SEGMENT 0x18
+
+ .globl _C_LABEL(run_i386_size)
+_C_LABEL(run_i386_size):
+ .long run_i386_end - _C_LABEL(run_i386_start)
+
+ .align 4
+ .text
+ .globl _C_LABEL(run_i386_start)
+_C_LABEL(run_i386_start):
+start:
+ /*
+ * run_i386(_start) is to call the loaded kernel's start() with
+ * 32bit segment mode from x64 mode.
+ * %rdi == loaded start address, %rsi == kernel start address
+ */
+
+ /* re-arrange the parameters for the x86 calling convension */
+ mov %edx, (run_i386_end - start - 0x20)(%rdi)
+ mov %ecx, (run_i386_end - start - 0x1c)(%rdi)
+ mov %r8d, (run_i386_end - start - 0x18)(%rdi)
+ mov %r9d, (run_i386_end - start - 0x14)(%rdi)
+ mov 0x8(%rsp), %edx
+ mov %edx, (run_i386_end - start - 0x10)(%rdi)
+ mov 0x10(%rsp), %edx
+ mov %edx, (run_i386_end - start - 0xc)(%rdi)
+ mov 0x18(%rsp), %edx
+ mov %edx, (run_i386_end - start - 0x8)(%rdi)
+ mov 0x20(%rsp), %edx
+ mov %edx, (run_i386_end - start - 0x4)(%rdi)
+
+ /* Prepare jump address */
+ lea (start32a - start)(%rdi), %rax
+ movl %eax, (start32r - start)(%rdi)
+
+ cli
+
+ /* Setup GDT */
+ lea (gdt - start)(%rdi), %rax
+ mov %rax, (gdtrr - start)(%rdi)
+ lgdt (gdtr - start)(%rdi)
+
+ /* Jump to set %cs */
+ ljmp *(start32r - start)(%rdi)
+
+ .align 4
+start32a:
+ .code32
+ movl $DATA_SEGMENT, %eax
+ movl %eax, %ds
+ movl %eax, %es
+ movl %eax, %fs
+ movl %eax, %gs
+ movl %eax, %ss
+
+ lea (run_i386_end - start - 0x20)(%edi), %eax
+ mov %eax, %esp
+
+ /* Disable Paging in CR0 */
+ movl %cr0, %eax
+ andl $(~CR0_PG), %eax
+ movl %eax, %cr0
+
+ /* Disable PAE in CR4 */
+ movl %cr4, %eax
+ andl $(~CR4_PAE), %eax
+ movl %eax, %cr4
+
+ jmp start32b
+start32b:
+ .code32
+
+ call *%esi
+
+ .align 4
+start32r:
+ .long 0
+ .long CODE_SEGMENT
+ .align 4
+gdt:
+ .long 0, 0
+ .long 0, 0
+ .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9f, 0xcf, 0x00
+ .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x93, 0xcf, 0x00
+gdtr:
+ .word gdtr - gdt
+gdtrr:
+ .quad
+start32end:
+ /* Space for the stack */
+ .align 4
+ .space 8192
+run_i386_end: