diff options
Diffstat (limited to 'src/cpu/qemu-x86')
-rw-r--r-- | src/cpu/qemu-x86/Makefile.inc | 1 | ||||
-rw-r--r-- | src/cpu/qemu-x86/cache_as_ram_bootblock.S | 55 |
2 files changed, 55 insertions, 1 deletions
diff --git a/src/cpu/qemu-x86/Makefile.inc b/src/cpu/qemu-x86/Makefile.inc index fb560d6b7c..3f27e8b247 100644 --- a/src/cpu/qemu-x86/Makefile.inc +++ b/src/cpu/qemu-x86/Makefile.inc @@ -2,6 +2,7 @@ bootblock-y += cache_as_ram_bootblock.S bootblock-y += bootblock.c +bootblock-$(CONFIG_ARCH_BOOTBLOCK_X86_64) += $(top)/src/arch/x86/walkcbfs.S romstage-y += ../intel/car/romstage.c diff --git a/src/cpu/qemu-x86/cache_as_ram_bootblock.S b/src/cpu/qemu-x86/cache_as_ram_bootblock.S index e3a26b0699..07f848a019 100644 --- a/src/cpu/qemu-x86/cache_as_ram_bootblock.S +++ b/src/cpu/qemu-x86/cache_as_ram_bootblock.S @@ -2,7 +2,14 @@ #include <cpu/x86/post_code.h> +#define CBFS_FILE_MAGIC 0 +#define CBFS_FILE_LEN (CBFS_FILE_MAGIC + 8) +#define CBFS_FILE_TYPE (CBFS_FILE_LEN + 4) +#define CBFS_FILE_CHECKSUM (CBFS_FILE_TYPE + 4) +#define CBFS_FILE_OFFSET (CBFS_FILE_CHECKSUM + 4) + .section .init, "ax", @progbits +.code32 .global bootblock_pre_c_entry bootblock_pre_c_entry: @@ -24,12 +31,55 @@ cache_as_ram: post_code(0x21) +#if defined(__x86_64__) + /* + * Copy page tables to final location in DRAM. This prevents some strange + * bugs when running KVM enabled: + * Accessing MMX instructions in long mode causes an abort + * Some physical addresses aren't properly translated + * Emulation fault on every instruction fetched due to page tables in ROM + * Enabling or disabling paging causes a fault + * + * First, find page tables in CBFS: + */ + lea pagetables_name, %esi + mov $1f, %esp + jmp walkcbfs_asm +1: + cmpl $0, %eax + je .Lhlt + + /* Test if page tables are memory-mapped and skip relocation */ + cmpl $(CONFIG_ARCH_X86_64_PGTBL_LOC), %eax + je pages_done + + movl CBFS_FILE_OFFSET(%eax), %ebx + bswap %ebx + addl %eax, %ebx + movl %ebx, %esi + + movl CBFS_FILE_LEN(%eax), %ecx + bswap %ecx + shr $2, %ecx + + movl $(CONFIG_ARCH_X86_64_PGTBL_LOC), %edi + +loop: + movl (%esi), %eax + movl %eax, (%edi) + addl $4, %esi + addl $4, %edi + decl %ecx + jnz loop +pages_done: +#endif + movl $_ecar_stack, %esp /* Align the stack and keep aligned for call to bootblock_c_entry() */ and $0xfffffff0, %esp - /* entry64.inc preserves ebx. */ + /* entry64.inc preserves ebx. */ #include <cpu/x86/64bit/entry64.inc> /* Restore the BIST result and timestamps. */ @@ -60,3 +110,6 @@ before_c_entry: post_code(POST_DEAD_CODE) hlt jmp .Lhlt + +pagetables_name: + .string "pagetables" |