1 /*
2 * Parts copyright Michael Brown <mbrown@fensystems.co.uk>
3 *
4 * Copyright (c) 2019, Joyent, Inc.
5 */
6
7 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
8
9 /* CR0: protection enabled */
10 #define CR0_PE ( 1 << 0 )
11
12 /* CR0: paging */
13 #define CR0_PG ( 1 << 31 )
14
15 /* CR4: physical address extensions */
16 #define CR4_PSE ( 1 << 4 )
17 #define CR4_PAE ( 1 << 5 )
18 #define CR4_PGE ( 1 << 7 )
19
20 /* Extended feature enable MSR (EFER) */
21 #define MSR_EFER 0xc0000080
22
23 /* EFER: long mode enable */
24 #define EFER_LME ( 1 << 8 )
25
26 #define GDTSEL_CODE 0x8
27 #define GDTSEL_DATA 0x10
28
29 #if defined(PXE_EFI) && defined(__x86_64__)
30
31 .section ".text", "ax", @progbits
32
33 /*
34 * %rdi -> multiboot2 magic
35 * %rsi -> multiboot info pointer
36 * %rdx -> entry address (32 bits)
37 *
38 *
39 * We need to transition from our 64-bit environment into the one
40 * defined by the multiboot2 spec, section 3.3. Namely, drop down to
41 * 32-bit protected mode with a basic GDT, paging disabled, interrupts
42 * off, and
43 *
44 * %eax -> multiboot2 magic
45 * %ebx -> multiboot info pointer (physical)
46 */
47 .align 16
48 .globl multiboot2_entry
49
50 multiboot2_entry:
51 cli
52
53 movq %rsi, %rbx /* mb2 infop */
54 movq %rdx, %rsi /* entry address */
55
56 /* Load the mb2-mandated code and data segments. */
57 leaq entry_gdt_base(%rip), %rcx
58 leaq entry_gdt(%rip), %rax
59 movq %rax, (%rcx)
60
61 leaq entry_gdtr(%rip), %rax
62 lgdt (%rax)
63
64 /* Load our new %cs. */
65 ljmp *newcs_vector
66
67 .code32
76
77 /* Disable paging */
78 movl %cr0, %eax
79 andl $~CR0_PG, %eax
80 movl %eax, %cr0
81
82 movl %cr4, %eax
83 andb $~(CR4_PAE | CR4_PGE | CR4_PSE), %al
84 movl %eax, %cr4
85
86 /* Disable long mode (clobbers %eax, %edx) */
87 movl $MSR_EFER, %ecx
88 rdmsr
89 andw $~EFER_LME, %ax
90 wrmsr
91
92 /* %ebx still has our infop */
93 movl %edi, %eax
94 jmp *%esi
95
96 /*
97 * %rdi -> struct mb2 *
98 * %rsi -> stack pointer to switch to
99 * %rdx -> &multiboot2_enter_kernel
100 */
101 .align 16
102 .code64
103 .globl multiboot2_bounce
104
105 multiboot2_bounce:
106 movq %rsi, %rsp
107 jmp *%rdx
108
109 .data
110
111 newcs_vector:
112 .long newcs, GDTSEL_CODE
113
114 .align 16
115 entry_gdt:
116 /* null entry */
117 .word 0x0, 0x0
118 .byte 0x0, 0x0, 0x0, 0x0
119
120 /* 32 bit protected mode code segment */
121 .word 0xffff, 0x0
122 .byte 0x0, 0x9f, 0xcf, 0x0
123
124 /* 32 bit protected mode data segment */
125 .word 0xffff, 0x0
126 .byte 0x0, 0x93, 0xcf, 0x0
127
128 entry_gdt_end:
129 .equ entry_gdt_length, entry_gdt_end - entry_gdt
130
131 .align 16
132 entry_gdtr:
133 .word entry_gdt_length - 1
134 entry_gdt_base:
135 .quad 0
136
137 #endif /* PXE_EFI && __x86_64__ */
|
1 /*
2 * Parts copyright Michael Brown <mbrown@fensystems.co.uk>
3 *
4 * Copyright 2020, Joyent, Inc.
5 */
6
7 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
8
9 /* CR0: protection enabled */
10 #define CR0_PE ( 1 << 0 )
11
12 /* CR0: paging */
13 #define CR0_PG ( 1 << 31 )
14
15 /* CR4: physical address extensions */
16 #define CR4_PSE ( 1 << 4 )
17 #define CR4_PAE ( 1 << 5 )
18 #define CR4_PGE ( 1 << 7 )
19
20 /* Extended feature enable MSR (EFER) */
21 #define MSR_EFER 0xc0000080
22
23 /* EFER: long mode enable */
24 #define EFER_LME ( 1 << 8 )
25
26 #define GDTSEL_CODE 0x8
27 #define GDTSEL_DATA 0x10
28
29 #if defined(PXE_EFI) && defined(__x86_64__)
30
31 .section ".text", "ax", @progbits
32
33 .data
34
35 newcs_vector:
36 .long newcs, GDTSEL_CODE
37
38 entry_gdt:
39 /* null entry */
40 .word 0x0, 0x0
41 .byte 0x0, 0x0, 0x0, 0x0
42
43 /* 32 bit protected mode code segment */
44 .word 0xffff, 0x0
45 .byte 0x0, 0x9f, 0xcf, 0x0
46
47 /* 32 bit protected mode data segment */
48 .word 0xffff, 0x0
49 .byte 0x0, 0x93, 0xcf, 0x0
50
51 entry_gdt_end:
52 .equ entry_gdt_length, entry_gdt_end - entry_gdt
53
54 entry_gdtr:
55 .word entry_gdt_length - 1
56 entry_gdt_base:
57 .quad 0
58
59 /*
60 * %rdi -> struct mb2 *
61 * %rsi -> stack pointer to switch to
62 * %rdx -> &multiboot2_enter_kernel
63 */
64 .code64
65 .globl multiboot2_bounce
66
67 multiboot2_bounce:
68 movq %rsi, %rsp
69 jmp *%rdx
70
71 /*
72 * %rdi -> multiboot2 magic
73 * %rsi -> multiboot info pointer
74 * %rdx -> entry address (32 bits)
75 *
76 *
77 * We need to transition from our 64-bit environment into the one
78 * defined by the multiboot2 spec, section 3.3. Namely, drop down to
79 * 32-bit protected mode with a basic GDT, paging disabled, interrupts
80 * off, and
81 *
82 * %eax -> multiboot2 magic
83 * %ebx -> multiboot info pointer (physical)
84 */
85 .globl multiboot2_entry
86
87 multiboot2_entry:
88 cli
89
90 movq %rsi, %rbx /* mb2 infop */
91 movq %rdx, %rsi /* entry address */
92
93 /* Load the mb2-mandated code and data segments. */
94 leaq entry_gdt_base(%rip), %rcx
95 leaq entry_gdt(%rip), %rax
96 movq %rax, (%rcx)
97
98 leaq entry_gdtr(%rip), %rax
99 lgdt (%rax)
100
101 /* Load our new %cs. */
102 ljmp *newcs_vector
103
104 .code32
113
114 /* Disable paging */
115 movl %cr0, %eax
116 andl $~CR0_PG, %eax
117 movl %eax, %cr0
118
119 movl %cr4, %eax
120 andb $~(CR4_PAE | CR4_PGE | CR4_PSE), %al
121 movl %eax, %cr4
122
123 /* Disable long mode (clobbers %eax, %edx) */
124 movl $MSR_EFER, %ecx
125 rdmsr
126 andw $~EFER_LME, %ax
127 wrmsr
128
129 /* %ebx still has our infop */
130 movl %edi, %eax
131 jmp *%esi
132
133 #endif /* PXE_EFI && __x86_64__ */
|