0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <linux/linkage.h>
0018 #include <asm/msr.h>
0019 #include <asm/page_types.h>
0020 #include <asm/processor-flags.h>
0021 #include <asm/segment.h>
0022
0023 .code64
0024 .text
0025 SYM_FUNC_START(__efi64_thunk)
0026 push %rbp
0027 push %rbx
0028
0029 movl %ds, %eax
0030 push %rax
0031 movl %es, %eax
0032 push %rax
0033 movl %ss, %eax
0034 push %rax
0035
0036
0037 movq 0x30(%rsp), %rbp
0038 movq 0x38(%rsp), %rbx
0039 movq 0x40(%rsp), %rax
0040
0041
0042
0043
0044 subq $64, %rsp
0045 movl %esi, 0x0(%rsp)
0046 movl %edx, 0x4(%rsp)
0047 movl %ecx, 0x8(%rsp)
0048 movl %r8d, 0xc(%rsp)
0049 movl %r9d, 0x10(%rsp)
0050 movl %ebp, 0x14(%rsp)
0051 movl %ebx, 0x18(%rsp)
0052 movl %eax, 0x1c(%rsp)
0053
0054 leaq 0x20(%rsp), %rbx
0055 sgdt (%rbx)
0056
0057 addq $16, %rbx
0058 sidt (%rbx)
0059
0060 leaq 1f(%rip), %rbp
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 leaq efi32_boot_idt(%rip), %rax
0071 lidt (%rax)
0072 leaq efi32_boot_gdt(%rip), %rax
0073 lgdt (%rax)
0074
0075 movzwl efi32_boot_ds(%rip), %edx
0076 movzwq efi32_boot_cs(%rip), %rax
0077 pushq %rax
0078 leaq efi_enter32(%rip), %rax
0079 pushq %rax
0080 lretq
0081
0082 1: addq $64, %rsp
0083 movq %rdi, %rax
0084
0085 pop %rbx
0086 movl %ebx, %ss
0087 pop %rbx
0088 movl %ebx, %es
0089 pop %rbx
0090 movl %ebx, %ds
0091
0092 xorl %ebx, %ebx
0093 movl %ebx, %fs
0094 movl %ebx, %gs
0095
0096
0097
0098
0099 roll $1, %eax
0100 rorq $1, %rax
0101
0102 pop %rbx
0103 pop %rbp
0104 RET
0105 SYM_FUNC_END(__efi64_thunk)
0106
0107 .code32
0108
0109
0110
0111
0112
0113 SYM_FUNC_START_LOCAL(efi_enter32)
0114
0115 movl %edx, %ds
0116 movl %edx, %es
0117 movl %edx, %fs
0118 movl %edx, %gs
0119 movl %edx, %ss
0120
0121
0122 movl %cr3, %eax
0123 movl %eax, %cr3
0124
0125
0126 movl %cr0, %eax
0127 btrl $X86_CR0_PG_BIT, %eax
0128 movl %eax, %cr0
0129
0130
0131 movl $MSR_EFER, %ecx
0132 rdmsr
0133 btrl $_EFER_LME, %eax
0134 wrmsr
0135
0136 call *%edi
0137
0138
0139 movl %eax, %edi
0140
0141
0142
0143
0144
0145 cli
0146
0147 lidtl (%ebx)
0148 subl $16, %ebx
0149
0150 lgdtl (%ebx)
0151
0152 movl %cr4, %eax
0153 btsl $(X86_CR4_PAE_BIT), %eax
0154 movl %eax, %cr4
0155
0156 movl %cr3, %eax
0157 movl %eax, %cr3
0158
0159 movl $MSR_EFER, %ecx
0160 rdmsr
0161 btsl $_EFER_LME, %eax
0162 wrmsr
0163
0164 xorl %eax, %eax
0165 lldt %ax
0166
0167 pushl $__KERNEL_CS
0168 pushl %ebp
0169
0170
0171 movl %cr0, %eax
0172 btsl $X86_CR0_PG_BIT, %eax
0173 movl %eax, %cr0
0174 lret
0175 SYM_FUNC_END(efi_enter32)
0176
0177 .data
0178 .balign 8
0179 SYM_DATA_START(efi32_boot_gdt)
0180 .word 0
0181 .quad 0
0182 SYM_DATA_END(efi32_boot_gdt)
0183
0184 SYM_DATA_START(efi32_boot_idt)
0185 .word 0
0186 .quad 0
0187 SYM_DATA_END(efi32_boot_idt)
0188
0189 SYM_DATA_START(efi32_boot_cs)
0190 .word 0
0191 SYM_DATA_END(efi32_boot_cs)
0192
0193 SYM_DATA_START(efi32_boot_ds)
0194 .word 0
0195 SYM_DATA_END(efi32_boot_ds)