Angel Pons | f23ae0b | 2020-04-02 23:48:12 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Patrick Rudolph | b1ef725 | 2019-09-28 17:44:01 +0200 | [diff] [blame] | 2 | |
| 3 | /* |
| 4 | * For starting coreboot in long mode. |
| 5 | * |
| 6 | * For reference see "AMD64 ArchitectureProgrammer's Manual Volume 2", |
| 7 | * Document 24593-Rev. 3.31-July 2019 Chapter 5.3 |
| 8 | * |
| 9 | * Clobbers: eax, ecx, edx |
| 10 | */ |
| 11 | |
Patrick Rudolph | adcf782 | 2020-08-27 20:50:18 +0200 | [diff] [blame] | 12 | #if ENV_X86_64 |
Patrick Rudolph | b1ef725 | 2019-09-28 17:44:01 +0200 | [diff] [blame] | 13 | .code32 |
| 14 | #if (CONFIG_ARCH_X86_64_PGTBL_LOC & 0xfff) > 0 |
| 15 | #error pagetables must be 4KiB aligned! |
| 16 | #endif |
| 17 | |
| 18 | #include <cpu/x86/msr.h> |
Patrick Rudolph | a169550 | 2019-12-01 07:23:59 +0100 | [diff] [blame] | 19 | #if defined(__RAMSTAGE__) |
| 20 | #include <arch/ram_segs.h> |
| 21 | #else |
Patrick Rudolph | b1ef725 | 2019-09-28 17:44:01 +0200 | [diff] [blame] | 22 | #include <arch/rom_segs.h> |
Patrick Rudolph | a169550 | 2019-12-01 07:23:59 +0100 | [diff] [blame] | 23 | #endif |
| 24 | |
Patrick Rudolph | b1ef725 | 2019-09-28 17:44:01 +0200 | [diff] [blame] | 25 | |
| 26 | setup_longmode: |
| 27 | /* Get page table address */ |
| 28 | movl $(CONFIG_ARCH_X86_64_PGTBL_LOC), %eax |
| 29 | |
| 30 | /* load identity mapped page tables */ |
| 31 | movl %eax, %cr3 |
| 32 | |
| 33 | /* enable PAE */ |
| 34 | movl %cr4, %eax |
| 35 | btsl $5, %eax |
| 36 | movl %eax, %cr4 |
| 37 | |
| 38 | /* enable long mode */ |
| 39 | movl $(IA32_EFER), %ecx |
| 40 | rdmsr |
| 41 | btsl $8, %eax |
| 42 | wrmsr |
| 43 | |
| 44 | /* enable paging */ |
| 45 | movl %cr0, %eax |
| 46 | btsl $31, %eax |
| 47 | movl %eax, %cr0 |
| 48 | |
| 49 | /* use long jump to switch to 64-bit code segment */ |
Patrick Rudolph | a169550 | 2019-12-01 07:23:59 +0100 | [diff] [blame] | 50 | #if defined(__RAMSTAGE__) |
| 51 | ljmp $RAM_CODE_SEG64, $__longmode_start |
| 52 | #else |
Patrick Rudolph | b1ef725 | 2019-09-28 17:44:01 +0200 | [diff] [blame] | 53 | ljmp $ROM_CODE_SEG64, $__longmode_start |
Patrick Rudolph | a169550 | 2019-12-01 07:23:59 +0100 | [diff] [blame] | 54 | |
| 55 | #endif |
Patrick Rudolph | b1ef725 | 2019-09-28 17:44:01 +0200 | [diff] [blame] | 56 | .code64 |
| 57 | __longmode_start: |
| 58 | |
| 59 | #endif |