]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Library/LoadLinuxLib/X64/JumpToKernel.S
OvmfPkg: LoadLinuxLib: Fix kernel entry for 64-bit OVMF
[mirror_edk2.git] / OvmfPkg / Library / LoadLinuxLib / X64 / JumpToKernel.S
index 9ae755b0674873e7d26963e5d25f59e2c50a8ec9..d9b991b703cb4651280dac1714486b9d0fcc2ccb 100644 (file)
@@ -23,8 +23,47 @@ ASM_GLOBAL ASM_PFX(JumpToKernel)
 #   );\r
 #------------------------------------------------------------------------------\r
 ASM_PFX(JumpToKernel):\r
+\r
+    // Set up for executing kernel. BP in %esi, entry point on the stack\r
+    // (64-bit when the 'ret' will use it as 32-bit, but we're little-endian)\r
     movq    %rdx, %rsi\r
-    addq    $0x200, %rcx\r
-    callq   %rcx\r
+    pushq   %rcx\r
+\r
+    // Jump into the compatibility mode CS\r
+    pushq   $0x10\r
+    leaq    1f, %rax\r
+    pushq   %rax\r
+    retfq\r
+\r
+1:  // Now in compatibility mode\r
+.code32\r
+    movl    $0x18, %eax\r
+    movl    %eax, %ds\r
+    movl    %eax, %es\r
+    movl    %eax, %fs\r
+    movl    %eax, %gs\r
+    movl    %eax, %ss\r
+\r
+    // Disable paging\r
+    movl    %cr0, %eax\r
+    btcl    $31, %eax\r
+    movl    %eax, %cr0\r
+\r
+    // Disable long mode in EFER\r
+    movl    $0x0c0000080, %ecx\r
+    rdmsr\r
+    btcl    $8, %eax\r
+    wrmsr\r
+\r
+    // Disable PAE\r
+    movl    %cr4, %eax\r
+    btcl    $5, %eax\r
+    movl    %eax, %cr4\r
+\r
+    // Zero registers and 'return' to kernel\r
+    xorl    %ebp, %ebp\r
+    xorl    %edi, %edi\r
+    xorl    %ebx, %ebx\r
     ret\r
+.code64\r
 \r