<p>Patrick Rudolph would like Patrick Rudolph to <strong>review</strong> this change.</p><p><a href="https://review.coreboot.org/29667">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">[WIP]x86|mb/emulation/qemu-q35: 64bit ramstage support<br><br>* Add mmu.c ported from arm64<br>* Generate 4 level page tables for long mode<br>* Enable long mode<br>* Activate long mode in c_start.S<br>* Some fixes for 64bit<br>* Add support for 64bit rmodule<br><br>Non working:<br>* Loading gdt and setting %ds<br><br>Signed-off-by: Patrick Rudolph <siro@das-labor.org><br>Change-Id: If2f02a95b2f91ab51043d4e81054354f4a6eb5d5<br>---<br>M src/arch/x86/Kconfig<br>M src/arch/x86/Makefile.inc<br>M src/arch/x86/boot.c<br>M src/arch/x86/c_start.S<br>M src/arch/x86/exception.c<br>A src/arch/x86/include/arch/mmu.h<br>A src/arch/x86/mmu.c<br>M src/commonlib/include/commonlib/cbmem_id.h<br>M src/cpu/qemu-x86/Kconfig<br>M src/cpu/x86/Makefile.inc<br>M src/lib/timestamp.c<br>M src/mainboard/emulation/qemu-q35/Kconfig<br>M src/mainboard/emulation/qemu-q35/Makefile.inc<br>M src/mainboard/emulation/qemu-q35/romstage.c<br>M src/southbridge/intel/common/smi.c<br>M src/southbridge/intel/i82801ix/hdaudio.c<br>M src/southbridge/intel/i82801ix/lpc.c<br>M src/southbridge/intel/i82801ix/sata.c<br>M util/cbfstool/elf.h<br>M util/cbfstool/elfheaders.c<br>M util/cbfstool/rmodule.c<br>M util/xcompile/xcompile<br>22 files changed, 663 insertions(+), 14 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/67/29667/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/arch/x86/Kconfig b/src/arch/x86/Kconfig</span><br><span>index 7c8371e..ed07a05 100644</span><br><span>--- a/src/arch/x86/Kconfig</span><br><span>+++ b/src/arch/x86/Kconfig</span><br><span>@@ -330,3 +330,7 @@</span><br><span> config HAVE_CF9_RESET_PREPARE</span><br><span> bool</span><br><span> depends on HAVE_CF9_RESET</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+config TTB_SIZE_KB</span><br><span style="color: hsl(120, 100%, 40%);">+ hex "Size of TTB"</span><br><span style="color: hsl(120, 100%, 40%);">+ default 0x1000</span><br><span>diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc</span><br><span>index fcc57c5..c5cf625 100644</span><br><span>--- a/src/arch/x86/Makefile.inc</span><br><span>+++ b/src/arch/x86/Makefile.inc</span><br><span>@@ -398,7 +398,7 @@</span><br><span> </span><br><span> $(objgenerated)/ramstage.o: $$(ramstage-objs) $(COMPILER_RT_ramstage) $$(ramstage-libs)</span><br><span> @printf " CC $(subst $(obj)/,,$(@))\n"</span><br><span style="color: hsl(0, 100%, 40%);">-ifeq ($(CONFIG_ARCH_ROMSTAGE_X86_32),y)</span><br><span style="color: hsl(120, 100%, 40%);">+ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_32),y)</span><br><span> $(LD_ramstage) -m elf_i386 -r -o $@ $(COMPILER_RT_FLAGS_ramstage) --whole-archive --start-group $(filter-out %.ld,$(ramstage-objs)) $(ramstage-libs) --no-whole-archive $(COMPILER_RT_ramstage) --end-group</span><br><span> else</span><br><span> $(LD_ramstage) -m elf_x86_64 -r -o $@ $(COMPILER_RT_FLAGS_ramstage) --whole-archive --start-group $(filter-out %.ld,$(ramstage-objs)) $(ramstage-libs) --no-whole-archive $(COMPILER_RT_ramstage) --end-group</span><br><span>diff --git a/src/arch/x86/boot.c b/src/arch/x86/boot.c</span><br><span>index 2967cf6..fa98704 100644</span><br><span>--- a/src/arch/x86/boot.c</span><br><span>+++ b/src/arch/x86/boot.c</span><br><span>@@ -29,16 +29,17 @@</span><br><span> </span><br><span> return 0;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+ #include <arch/mmu.h></span><br><span> </span><br><span> void arch_prog_run(struct prog *prog)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_DEBUG, "Jumping to %p\n", (void*)prog_entry(prog));</span><br><span> __asm__ volatile (</span><br><span> #ifdef __x86_64__</span><br><span> "jmp *%%rdi\n"</span><br><span> #else</span><br><span> "jmp *%%edi\n"</span><br><span> #endif</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> :: "D"(prog_entry(prog))</span><br><span> );</span><br><span> }</span><br><span>diff --git a/src/arch/x86/c_start.S b/src/arch/x86/c_start.S</span><br><span>index 6426ef3..11b0145 100644</span><br><span>--- a/src/arch/x86/c_start.S</span><br><span>+++ b/src/arch/x86/c_start.S</span><br><span>@@ -12,6 +12,7 @@</span><br><span> */</span><br><span> </span><br><span> #include <cpu/x86/post_code.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/rom_segs.h></span><br><span> </span><br><span> /* Place the stack in the bss section. It's not necessary to define it in the</span><br><span> * the linker script. */</span><br><span>@@ -35,13 +36,57 @@</span><br><span> #else</span><br><span> .code32</span><br><span> #endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> .globl _start</span><br><span> _start:</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> cli</span><br><span style="color: hsl(0, 100%, 40%);">- lgdt %cs:gdtaddr</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef __x86_64__</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Test for page tables installed */</span><br><span style="color: hsl(120, 100%, 40%);">+ mov %cr3, %eax</span><br><span style="color: hsl(120, 100%, 40%);">+ cmp $0, %eax</span><br><span style="color: hsl(120, 100%, 40%);">+ je longmode_setup_err</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Test for long mode active (EFER.LMA = 1 EFER.LME = 1) */</span><br><span style="color: hsl(120, 100%, 40%);">+ movl $0xC0000080, %ecx // EFER MSR number.</span><br><span style="color: hsl(120, 100%, 40%);">+ rdmsr</span><br><span style="color: hsl(120, 100%, 40%);">+ andl $0x500, %eax</span><br><span style="color: hsl(120, 100%, 40%);">+ cmp $0x500, %eax</span><br><span style="color: hsl(120, 100%, 40%);">+ je longmode_active</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Test for long mode disabled (EFER.LME = 0) */</span><br><span style="color: hsl(120, 100%, 40%);">+ cmp $0, %eax</span><br><span style="color: hsl(120, 100%, 40%);">+ je longmode_setup_err</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Previous stage prepared long mode:</span><br><span style="color: hsl(120, 100%, 40%);">+ * + Long mode is enabled (EFER.LME = 1)</span><br><span style="color: hsl(120, 100%, 40%);">+ * + paging is disalbed</span><br><span style="color: hsl(120, 100%, 40%);">+ * + page tables are installed</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Enable paging */</span><br><span style="color: hsl(120, 100%, 40%);">+ mov %cr0, %eax</span><br><span style="color: hsl(120, 100%, 40%);">+ orl $(1 <<31), %eax</span><br><span style="color: hsl(120, 100%, 40%);">+ mov %eax, %cr0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ jmp longmode_active</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+longmode_setup_err:</span><br><span style="color: hsl(120, 100%, 40%);">+ post_code(POST_DEAD_CODE) /* post ee */</span><br><span style="color: hsl(120, 100%, 40%);">+ hlt</span><br><span style="color: hsl(120, 100%, 40%);">+ jmp longmode_setup_err</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+longmode_active:</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ lgdt %cs:gdtaddr</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #ifndef __x86_64__</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Enable protected mode */</span><br><span> ljmp $0x10, $1f</span><br><span> #endif</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Use flat data segment */</span><br><span> 1: movl $0x18, %eax</span><br><span> movl %eax, %ds</span><br><span> movl %eax, %es</span><br><span>@@ -134,7 +179,7 @@</span><br><span> #endif</span><br><span> </span><br><span> .data</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+ .balign 8</span><br><span> /* This is the gdt for GCC part of coreboot.</span><br><span> * It is different from the gdt in ROMCC/ASM part of coreboot</span><br><span> * which is defined in entry32.inc</span><br><span>diff --git a/src/arch/x86/exception.c b/src/arch/x86/exception.c</span><br><span>index 0f42fdf..9dda706 100644</span><br><span>--- a/src/arch/x86/exception.c</span><br><span>+++ b/src/arch/x86/exception.c</span><br><span>@@ -516,7 +516,7 @@</span><br><span> "edi: %08x esi: %08x ebp: %08x esp: %08x\n",</span><br><span> logical_processor, (unsigned int)lapicid(),</span><br><span> info->vector, info->cs, info->eip,</span><br><span style="color: hsl(0, 100%, 40%);">- info->error_code, info->eflags, read_cr2(),</span><br><span style="color: hsl(120, 100%, 40%);">+ info->error_code, info->eflags, (unsigned int)read_cr2(),</span><br><span> info->eax, info->ebx, info->ecx, info->edx,</span><br><span> info->edi, info->esi, info->ebp, info->esp);</span><br><span> u8 *code = (u8 *)((uintptr_t)info->eip - (MDUMP_SIZE >> 1));</span><br><span>diff --git a/src/arch/x86/include/arch/mmu.h b/src/arch/x86/include/arch/mmu.h</span><br><span>new file mode 100644</span><br><span>index 0000000..c3bd3f7</span><br><span>--- /dev/null</span><br><span>+++ b/src/arch/x86/include/arch/mmu.h</span><br><span>@@ -0,0 +1,105 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2014 Google Inc.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef __ARCH_X86_MMU_H__</span><br><span style="color: hsl(120, 100%, 40%);">+#define __ARCH_X86_MMU_H__</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <types.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Memory attributes for mmap regions</span><br><span style="color: hsl(120, 100%, 40%);">+ * These attributes act as tag values for memrange regions</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Descriptor attributes */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define DESC_MASK 0xeaf</span><br><span style="color: hsl(120, 100%, 40%);">+#define INVALID_DESC 0</span><br><span style="color: hsl(120, 100%, 40%);">+#define TABLE_DESC 0x623</span><br><span style="color: hsl(120, 100%, 40%);">+#define PAGE_DESC 0x4a3</span><br><span style="color: hsl(120, 100%, 40%);">+#define BLOCK_DESC 0x2a3</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define AVAIL_SHIFT 9</span><br><span style="color: hsl(120, 100%, 40%);">+#define AVAIL_MASK (7 << AVAIL_SHIFT)</span><br><span style="color: hsl(120, 100%, 40%);">+#define AVAIL_INVAL 0</span><br><span style="color: hsl(120, 100%, 40%);">+#define AVAIL_TABLE 3</span><br><span style="color: hsl(120, 100%, 40%);">+#define AVAIL_PAGE 2</span><br><span style="color: hsl(120, 100%, 40%);">+#define AVAIL_BLOCK 1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Block descriptor */</span><br><span style="color: hsl(120, 100%, 40%);">+#define BLOCK_NS (1 << 5)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define BLOCK_AP_RW (0 << 7)</span><br><span style="color: hsl(120, 100%, 40%);">+#define BLOCK_AP_RO (1 << 7)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define BLOCK_ACCESS (1 << 10)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define BLOCK_XN (1ULL << 54)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define BLOCK_SH_SHIFT (8)</span><br><span style="color: hsl(120, 100%, 40%);">+#define BLOCK_SH_NON_SHAREABLE (0 << BLOCK_SH_SHIFT)</span><br><span style="color: hsl(120, 100%, 40%);">+#define BLOCK_SH_UNPREDICTABLE (1 << BLOCK_SH_SHIFT)</span><br><span style="color: hsl(120, 100%, 40%);">+#define BLOCK_SH_OUTER_SHAREABLE (2 << BLOCK_SH_SHIFT)</span><br><span style="color: hsl(120, 100%, 40%);">+#define BLOCK_SH_INNER_SHAREABLE (3 << BLOCK_SH_SHIFT)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Sentinel descriptor to mark first PTE of an unused table. It must be a value</span><br><span style="color: hsl(120, 100%, 40%);">+ * that cannot occur naturally as part of a page table. (Bits [1:0] = 0b00 makes</span><br><span style="color: hsl(120, 100%, 40%);">+ * this an unmapped page, but some page attribute bits are still set.) */</span><br><span style="color: hsl(120, 100%, 40%);">+#define UNUSED_DESC 0x6EbAAD0BBADbA000ULL</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* XLAT Table Init Attributes */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define VA_START 0x0</span><br><span style="color: hsl(120, 100%, 40%);">+#define BITS_PER_VA 48</span><br><span style="color: hsl(120, 100%, 40%);">+/* Granule size of 4KB is being used */</span><br><span style="color: hsl(120, 100%, 40%);">+#define GRANULE_SIZE_SHIFT 12</span><br><span style="color: hsl(120, 100%, 40%);">+#define GRANULE_SIZE (1 << GRANULE_SIZE_SHIFT)</span><br><span style="color: hsl(120, 100%, 40%);">+#define XLAT_ADDR_MASK ((1ULL << BITS_PER_VA) - GRANULE_SIZE)</span><br><span style="color: hsl(120, 100%, 40%);">+#define GRANULE_SIZE_MASK ((1ULL << GRANULE_SIZE_SHIFT) - 1)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define BITS_RESOLVED_PER_LVL (GRANULE_SIZE_SHIFT - 3)</span><br><span style="color: hsl(120, 100%, 40%);">+#define L0_ADDR_SHIFT (GRANULE_SIZE_SHIFT + BITS_RESOLVED_PER_LVL * 3)</span><br><span style="color: hsl(120, 100%, 40%);">+#define L1_ADDR_SHIFT (GRANULE_SIZE_SHIFT + BITS_RESOLVED_PER_LVL * 2)</span><br><span style="color: hsl(120, 100%, 40%);">+#define L2_ADDR_SHIFT (GRANULE_SIZE_SHIFT + BITS_RESOLVED_PER_LVL * 1)</span><br><span style="color: hsl(120, 100%, 40%);">+#define L3_ADDR_SHIFT (GRANULE_SIZE_SHIFT + BITS_RESOLVED_PER_LVL * 0)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define L0_ADDR_MASK (((1ULL << BITS_RESOLVED_PER_LVL) - 1) << L0_ADDR_SHIFT)</span><br><span style="color: hsl(120, 100%, 40%);">+#define L1_ADDR_MASK (((1ULL << BITS_RESOLVED_PER_LVL) - 1) << L1_ADDR_SHIFT)</span><br><span style="color: hsl(120, 100%, 40%);">+#define L2_ADDR_MASK (((1ULL << BITS_RESOLVED_PER_LVL) - 1) << L2_ADDR_SHIFT)</span><br><span style="color: hsl(120, 100%, 40%);">+#define L3_ADDR_MASK (((1ULL << BITS_RESOLVED_PER_LVL) - 1) << L3_ADDR_SHIFT)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* These macros give the size of the region addressed by each entry of a xlat</span><br><span style="color: hsl(120, 100%, 40%);">+ table at any given level */</span><br><span style="color: hsl(120, 100%, 40%);">+#define L3_XLAT_SIZE (1ULL << L3_ADDR_SHIFT)</span><br><span style="color: hsl(120, 100%, 40%);">+#define L2_XLAT_SIZE (1ULL << L2_ADDR_SHIFT)</span><br><span style="color: hsl(120, 100%, 40%);">+#define L1_XLAT_SIZE (1ULL << L1_ADDR_SHIFT)</span><br><span style="color: hsl(120, 100%, 40%);">+#define L0_XLAT_SIZE (1ULL << L0_ADDR_SHIFT)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define PAT_UC 0</span><br><span style="color: hsl(120, 100%, 40%);">+#define PAT_WC 1</span><br><span style="color: hsl(120, 100%, 40%);">+#define PAT_WT 4</span><br><span style="color: hsl(120, 100%, 40%);">+#define PAT_WP 5</span><br><span style="color: hsl(120, 100%, 40%);">+#define PAT_WB 6</span><br><span style="color: hsl(120, 100%, 40%);">+#define PAT_UC_MINUS 7</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Initialize MMU registers and page table memory region. */</span><br><span style="color: hsl(120, 100%, 40%);">+void mmu_init(void);</span><br><span style="color: hsl(120, 100%, 40%);">+/* Install page tables and enable long mode */</span><br><span style="color: hsl(120, 100%, 40%);">+void mmu_install_pagetables(void);</span><br><span style="color: hsl(120, 100%, 40%);">+void mmu_config_range(uint64_t start, uint64_t size, uint64_t tag);</span><br><span style="color: hsl(120, 100%, 40%);">+/* Disable the MMU (which also disables dcache but not icache). */</span><br><span style="color: hsl(120, 100%, 40%);">+void mmu_disable(void);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#endif /* __ARCH_X86_MMU_H__ */</span><br><span>diff --git a/src/arch/x86/mmu.c b/src/arch/x86/mmu.c</span><br><span>new file mode 100644</span><br><span>index 0000000..a0e3e78</span><br><span>--- /dev/null</span><br><span>+++ b/src/arch/x86/mmu.c</span><br><span>@@ -0,0 +1,403 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2014 Google Inc.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Redistribution and use in source and binary forms, with or without</span><br><span style="color: hsl(120, 100%, 40%);">+ * modification, are permitted provided that the following conditions</span><br><span style="color: hsl(120, 100%, 40%);">+ * are met:</span><br><span style="color: hsl(120, 100%, 40%);">+ * 1. Redistributions of source code must retain the above copyright</span><br><span style="color: hsl(120, 100%, 40%);">+ * notice, this list of conditions and the following disclaimer.</span><br><span style="color: hsl(120, 100%, 40%);">+ * 2. Redistributions in binary form must reproduce the above copyright</span><br><span style="color: hsl(120, 100%, 40%);">+ * notice, this list of conditions and the following disclaimer in the</span><br><span style="color: hsl(120, 100%, 40%);">+ * documentation and/or other materials provided with the distribution.</span><br><span style="color: hsl(120, 100%, 40%);">+ * 3. The name of the author may not be used to endorse or promote products</span><br><span style="color: hsl(120, 100%, 40%);">+ * derived from this software without specific prior written permission.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND</span><br><span style="color: hsl(120, 100%, 40%);">+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE</span><br><span style="color: hsl(120, 100%, 40%);">+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE</span><br><span style="color: hsl(120, 100%, 40%);">+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE</span><br><span style="color: hsl(120, 100%, 40%);">+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL</span><br><span style="color: hsl(120, 100%, 40%);">+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS</span><br><span style="color: hsl(120, 100%, 40%);">+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)</span><br><span style="color: hsl(120, 100%, 40%);">+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT</span><br><span style="color: hsl(120, 100%, 40%);">+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY</span><br><span style="color: hsl(120, 100%, 40%);">+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF</span><br><span style="color: hsl(120, 100%, 40%);">+ * SUCH DAMAGE.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <assert.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdlib.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <symbols.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <console/console.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/mmu.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/cache.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <cpu/x86/msr.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <cbmem.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* This just caches the next free table slot (okay to do since they fill up from</span><br><span style="color: hsl(120, 100%, 40%);">+ * bottom to top and can never be freed up again). It will reset to its initial</span><br><span style="color: hsl(120, 100%, 40%);">+ * value on stage transition, so we still need to check it for UNUSED_DESC. */</span><br><span style="color: hsl(120, 100%, 40%);">+static CAR_GLOBAL uint64_t *next_free_table;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define PTE_PRES (1ULL << 0)</span><br><span style="color: hsl(120, 100%, 40%);">+#define PTE_RW (1ULL << 1)</span><br><span style="color: hsl(120, 100%, 40%);">+#define PTE_US (1ULL << 2)</span><br><span style="color: hsl(120, 100%, 40%);">+#define PTE_PWT (1ULL << 3)</span><br><span style="color: hsl(120, 100%, 40%);">+#define PTE_PCD (1ULL << 4)</span><br><span style="color: hsl(120, 100%, 40%);">+#define PTE_A (1ULL << 5)</span><br><span style="color: hsl(120, 100%, 40%);">+#define PTE_D (1ULL << 6)</span><br><span style="color: hsl(120, 100%, 40%);">+#define PTE_PAT (1ULL << 7)</span><br><span style="color: hsl(120, 100%, 40%);">+#define PTE_G (1ULL << 8)</span><br><span style="color: hsl(120, 100%, 40%);">+#define PTE_XD (1ULL << 63)</span><br><span style="color: hsl(120, 100%, 40%);">+#define PDE_PS (1ULL << 7)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define BLOCK_INDEX_MASK (PTE_PWT | PTE_PCD | PTE_PRES | PTE_RW | PTE_A | PTE_D)</span><br><span style="color: hsl(120, 100%, 40%);">+#define BLOCK_INDEX_SHIFT 0</span><br><span style="color: hsl(120, 100%, 40%);">+#define BLOCK_INDEX_MEM_NORMAL (PTE_PRES | PTE_RW | PTE_A | PTE_D)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void print_tag(int level, uint64_t pat)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (pat) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case PAT_UC:</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(level, "UC\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case PAT_WC:</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(level, "WC\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case PAT_WT:</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(level, "WT\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case PAT_WP:</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(level, "WP\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case PAT_WB:</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(level, "WB\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case PAT_UC_MINUS:</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(level, "UC-\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static uint64_t pte_pat_flags(unsigned long pat)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (pat) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case PAT_UC:</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0 | PTE_PCD | PTE_PWT;</span><br><span style="color: hsl(120, 100%, 40%);">+ case PAT_WC:</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0 | 0 | PTE_PWT;</span><br><span style="color: hsl(120, 100%, 40%);">+ case PAT_WT:</span><br><span style="color: hsl(120, 100%, 40%);">+ return PTE_PAT | PTE_PCD | PTE_PWT;</span><br><span style="color: hsl(120, 100%, 40%);">+ case PAT_WP:</span><br><span style="color: hsl(120, 100%, 40%);">+ return PTE_PAT | 0 | PTE_PWT;</span><br><span style="color: hsl(120, 100%, 40%);">+ case PAT_WB:</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0 | 0 | 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ case PAT_UC_MINUS:</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0 | PTE_PCD | 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_ERR, "PTE PAT defaulting to WB: %lx\n", pat);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0 | 0 | 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static u8 *ttb(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return cbmem_find(CBMEM_ID_TTB);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static u8 *ettb(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return (u8 *)cbmem_find(CBMEM_ID_TTB) + (CONFIG_TTB_SIZE_KB * 1024);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Func : get_block_attr</span><br><span style="color: hsl(120, 100%, 40%);">+ * Desc : Get block descriptor attributes based on the value of tag in memrange</span><br><span style="color: hsl(120, 100%, 40%);">+ * region</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static uint64_t get_block_attr(unsigned long tag, bool ps)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t flags = PTE_PRES | PTE_RW | PTE_US | PTE_A | PTE_D;</span><br><span style="color: hsl(120, 100%, 40%);">+ flags |= pte_pat_flags(tag);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ps) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (flags & PTE_PAT) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* If PS=1 PAT is at position 12 instead of 7 */</span><br><span style="color: hsl(120, 100%, 40%);">+ flags &= ~PTE_PAT;</span><br><span style="color: hsl(120, 100%, 40%);">+ flags |= (PTE_PAT << 5);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ flags |= PDE_PS;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ return flags;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Func : setup_new_table</span><br><span style="color: hsl(120, 100%, 40%);">+ * Desc : Get next free table from TTB and set it up to match old parent entry.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static uint64_t *setup_new_table(uint64_t desc, uint64_t xlat_size)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ while (next_free_table[0] != UNUSED_DESC) {</span><br><span style="color: hsl(120, 100%, 40%);">+ next_free_table += GRANULE_SIZE/sizeof(*next_free_table);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ettb() - (u8 *)next_free_table <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ die("Ran out of page table space!");</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t frame_base = desc & XLAT_ADDR_MASK;</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_DEBUG, "Backing address range [0x%llx:0x%llx) with new page"</span><br><span style="color: hsl(120, 100%, 40%);">+ " table @%p\n", frame_base, frame_base +</span><br><span style="color: hsl(120, 100%, 40%);">+ (xlat_size << BITS_RESOLVED_PER_LVL), next_free_table);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (desc == INVALID_DESC) {</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(next_free_table, 0, GRANULE_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Can reuse old parent entry, but may need to adjust type. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (xlat_size == L3_XLAT_SIZE)</span><br><span style="color: hsl(120, 100%, 40%);">+ desc |= PAGE_DESC;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ int i = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ for (; i < GRANULE_SIZE/sizeof(*next_free_table); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ next_free_table[i] = desc;</span><br><span style="color: hsl(120, 100%, 40%);">+ desc += xlat_size;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return next_free_table;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Func: get_next_level_table</span><br><span style="color: hsl(120, 100%, 40%);">+ * Desc: Check if the table entry is a valid descriptor. If not, initialize new</span><br><span style="color: hsl(120, 100%, 40%);">+ * table, update the entry and return the table addr. If valid, return the addr</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static uint64_t *get_next_level_table(uint64_t *ptr, size_t xlat_size)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t desc = *ptr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((desc & DESC_MASK) != TABLE_DESC) {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t *new_table = setup_new_table(desc, xlat_size);</span><br><span style="color: hsl(120, 100%, 40%);">+ desc = ((uintptr_t)new_table) | TABLE_DESC;</span><br><span style="color: hsl(120, 100%, 40%);">+ *ptr = desc;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ return (uint64_t *)(uintptr_t)(desc & XLAT_ADDR_MASK);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ Func : init_xlat_table</span><br><span style="color: hsl(120, 100%, 40%);">+ * Desc : Given a base address and size, it identifies the indices within</span><br><span style="color: hsl(120, 100%, 40%);">+ * different level XLAT tables which map the given base addr. Similar to table</span><br><span style="color: hsl(120, 100%, 40%);">+ * walk, except that all invalid entries during the walk are updated</span><br><span style="color: hsl(120, 100%, 40%);">+ * accordingly. On success, it returns the size of the block/page addressed by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the final table.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static uint64_t init_xlat_table(uint64_t base_addr,</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t size,</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t tag)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t l0_index = (base_addr & L0_ADDR_MASK) >> L0_ADDR_SHIFT;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t l1_index = (base_addr & L1_ADDR_MASK) >> L1_ADDR_SHIFT;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t l2_index = (base_addr & L2_ADDR_MASK) >> L2_ADDR_SHIFT;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t l3_index = (base_addr & L3_ADDR_MASK) >> L3_ADDR_SHIFT;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t *table = (uint64_t *)ttb();</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t desc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* check if CPU supports 1GB huge tables */</span><br><span style="color: hsl(120, 100%, 40%);">+ const bool hugepage_1gb = !!(cpuid_edx(0x80000001) & (1 << 26));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* L0 entry stores a table descriptor (doesn't support blocks) */</span><br><span style="color: hsl(120, 100%, 40%);">+ table = get_next_level_table(&table[l0_index], L1_XLAT_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* L1 table lookup */</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((size >= L1_XLAT_SIZE) &&</span><br><span style="color: hsl(120, 100%, 40%);">+ IS_ALIGNED(base_addr, (1UL << L1_ADDR_SHIFT)) &&</span><br><span style="color: hsl(120, 100%, 40%);">+ hugepage_1gb) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* If block address is aligned and size is greater than</span><br><span style="color: hsl(120, 100%, 40%);">+ * or equal to size addressed by each L1 entry, we can</span><br><span style="color: hsl(120, 100%, 40%);">+ * directly store a block desc */</span><br><span style="color: hsl(120, 100%, 40%);">+ desc = base_addr | BLOCK_DESC | get_block_attr(tag, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ table[l1_index] = desc;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* L2 lookup is not required */</span><br><span style="color: hsl(120, 100%, 40%);">+ return L1_XLAT_SIZE;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* L1 entry stores a table descriptor */</span><br><span style="color: hsl(120, 100%, 40%);">+ table = get_next_level_table(&table[l1_index], L2_XLAT_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* L2 table lookup */</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((size >= L2_XLAT_SIZE) &&</span><br><span style="color: hsl(120, 100%, 40%);">+ IS_ALIGNED(base_addr, (1UL << L2_ADDR_SHIFT))) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* If block address is aligned and size is greater than</span><br><span style="color: hsl(120, 100%, 40%);">+ * or equal to size addressed by each L2 entry, we can</span><br><span style="color: hsl(120, 100%, 40%);">+ * directly store a block desc */</span><br><span style="color: hsl(120, 100%, 40%);">+ desc = base_addr | BLOCK_DESC | get_block_attr(tag, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ table[l2_index] = desc;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* L3 lookup is not required */</span><br><span style="color: hsl(120, 100%, 40%);">+ return L2_XLAT_SIZE;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* L2 entry stores a table descriptor */</span><br><span style="color: hsl(120, 100%, 40%);">+ table = get_next_level_table(&table[l2_index], L3_XLAT_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* L3 table lookup */</span><br><span style="color: hsl(120, 100%, 40%);">+ desc = base_addr | PAGE_DESC | get_block_attr(tag, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ table[l3_index] = desc;</span><br><span style="color: hsl(120, 100%, 40%);">+ return L3_XLAT_SIZE;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Func : sanity_check</span><br><span style="color: hsl(120, 100%, 40%);">+ * Desc : Check address/size alignment of a table or page.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static void sanity_check(uint64_t addr, uint64_t size)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ assert(!(addr & GRANULE_SIZE_MASK) &&</span><br><span style="color: hsl(120, 100%, 40%);">+ !(size & GRANULE_SIZE_MASK) &&</span><br><span style="color: hsl(120, 100%, 40%);">+ (addr + size < (1ULL << BITS_PER_VA)) &&</span><br><span style="color: hsl(120, 100%, 40%);">+ size >= GRANULE_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Func : get_pte</span><br><span style="color: hsl(120, 100%, 40%);">+ * Desc : Returns the page table entry governing a specific address. */</span><br><span style="color: hsl(120, 100%, 40%);">+static uint64_t get_pte(uint64_t addr)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int shift = L0_ADDR_SHIFT;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Using pointer here is OK, as _ttb must be in 32bit space */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t *pte = (uint64_t *)ttb();</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_DEBUG, "%llx ", addr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ while (1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ int index = ((uintptr_t)addr >> shift) &</span><br><span style="color: hsl(120, 100%, 40%);">+ ((1ULL << BITS_RESOLVED_PER_LVL) - 1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch ((pte[index] & AVAIL_MASK) >> AVAIL_SHIFT) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case AVAIL_INVAL:</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_DEBUG, "INVAL ");break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case AVAIL_TABLE:</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_DEBUG, "TABLE @ %llx\n", pte[index] & XLAT_ADDR_MASK);break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case AVAIL_PAGE:</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_DEBUG, "PAGE %llx, %llx %llx\n", pte[index] & ((XLAT_ADDR_MASK<<1)),</span><br><span style="color: hsl(120, 100%, 40%);">+ (pte[index] & ((XLAT_ADDR_MASK<<1))) + (1ULL << shift) -1,pte[index] & 0xfff);break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ case AVAIL_BLOCK:</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_DEBUG, "BLOCK %llx, %llx %llx\n", pte[index] & ((XLAT_ADDR_MASK<<1)),</span><br><span style="color: hsl(120, 100%, 40%);">+ (pte[index] & ((XLAT_ADDR_MASK<<1))) + (1ULL << shift) -1,pte[index] & 0xfff);break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ //printk(BIOS_DEBUG, "pte[%d] =%llx\n", index, pte[index]);</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((pte[index] & DESC_MASK) != TABLE_DESC ||</span><br><span style="color: hsl(120, 100%, 40%);">+ shift <= GRANULE_SIZE_SHIFT)</span><br><span style="color: hsl(120, 100%, 40%);">+ return pte[index];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ pte = (uint64_t *)(uintptr_t)(pte[index] & XLAT_ADDR_MASK);</span><br><span style="color: hsl(120, 100%, 40%);">+ shift -= BITS_RESOLVED_PER_LVL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Func : assert_correct_ttb_mapping</span><br><span style="color: hsl(120, 100%, 40%);">+ * Desc : Asserts that mapping for addr matches the access type used by the</span><br><span style="color: hsl(120, 100%, 40%);">+ * page table walk (i.e. addr is correctly mapped to be part of the TTB). */</span><br><span style="color: hsl(120, 100%, 40%);">+static void assert_correct_ttb_mapping(uint64_t addr)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t pte = get_pte(addr);</span><br><span style="color: hsl(120, 100%, 40%);">+ assert(((pte >> BLOCK_INDEX_SHIFT) & BLOCK_INDEX_MASK)</span><br><span style="color: hsl(120, 100%, 40%);">+ == BLOCK_INDEX_MEM_NORMAL);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Func : mmu_config_range</span><br><span style="color: hsl(120, 100%, 40%);">+ * Desc : This function repeatedly calls init_xlat_table with the base</span><br><span style="color: hsl(120, 100%, 40%);">+ * address. Based on size returned from init_xlat_table, base_addr is updated</span><br><span style="color: hsl(120, 100%, 40%);">+ * and subsequent calls are made for initializing the xlat table until the whole</span><br><span style="color: hsl(120, 100%, 40%);">+ * region is initialized.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void mmu_config_range(uint64_t start, uint64_t size, uint64_t tag)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t base_addr = start;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t temp_size = size;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_INFO, "Mapping address range [0x%llx:0x%llx) as ",</span><br><span style="color: hsl(120, 100%, 40%);">+ start, start + size);</span><br><span style="color: hsl(120, 100%, 40%);">+ print_tag(BIOS_INFO, tag);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ sanity_check(base_addr, temp_size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ while (temp_size)</span><br><span style="color: hsl(120, 100%, 40%);">+ temp_size -= init_xlat_table(base_addr + (size - temp_size),</span><br><span style="color: hsl(120, 100%, 40%);">+ temp_size, tag);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Func : mmu_init</span><br><span style="color: hsl(120, 100%, 40%);">+ * Desc : Initialize MMU registers and page table memory region. This must be</span><br><span style="color: hsl(120, 100%, 40%);">+ * called exactly ONCE PER BOOT before trying to configure any mappings.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void mmu_init(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ next_free_table = cbmem_find(CBMEM_ID_TTB);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!next_free_table)</span><br><span style="color: hsl(120, 100%, 40%);">+ next_free_table = cbmem_add(CBMEM_ID_TTB, CONFIG_TTB_SIZE_KB * 1024);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!next_free_table)</span><br><span style="color: hsl(120, 100%, 40%);">+ die("Could not allocate memory for TTB\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Initially mark all table slots unused (first PTE == UNUSED_DESC). */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t *table = (uint64_t *)ttb();</span><br><span style="color: hsl(120, 100%, 40%);">+ for (; ettb() - (u8 *)table > 0; table += GRANULE_SIZE/sizeof(*table))</span><br><span style="color: hsl(120, 100%, 40%);">+ table[0] = UNUSED_DESC;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_DEBUG, "Initialize the root table (L0)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Initialize the root table (L0) to be completely unmapped. */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t *root = setup_new_table(INVALID_DESC, L0_XLAT_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+ assert((u8 *)root == ttb());</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Func : mmu_install_pagetables</span><br><span style="color: hsl(120, 100%, 40%);">+ * Desc : Install page tables, enable PAE and enable long mode.</span><br><span style="color: hsl(120, 100%, 40%);">+ * It does not enable paging and thus does not activate long mode!</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void mmu_install_pagetables(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ assert_correct_ttb_mapping((uintptr_t)ttb());</span><br><span style="color: hsl(120, 100%, 40%);">+ assert_correct_ttb_mapping((uintptr_t)ettb() - 1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned long long i;</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0x407a0000; i < 0x408a0000; i += (1024 * 1024)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t pte = get_pte(i);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (pte == 5)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Load the page table address */</span><br><span style="color: hsl(120, 100%, 40%);">+ write_cr3((uintptr_t)cbmem_find(CBMEM_ID_TTB));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_INFO, "MMU: installed page tables\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ CRx_TYPE cr0;</span><br><span style="color: hsl(120, 100%, 40%);">+ CRx_TYPE cr4;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Disable Paging */</span><br><span style="color: hsl(120, 100%, 40%);">+ cr0 = read_cr0();</span><br><span style="color: hsl(120, 100%, 40%);">+ cr0 &= ~CR0_PG;</span><br><span style="color: hsl(120, 100%, 40%);">+ write_cr0(cr0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Enable PAE */</span><br><span style="color: hsl(120, 100%, 40%);">+ cr4 = read_cr4();</span><br><span style="color: hsl(120, 100%, 40%);">+ cr4 |= CR4_PAE;</span><br><span style="color: hsl(120, 100%, 40%);">+ write_cr4(cr4);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_INFO, "MMU: enabled PAE\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ #define MSR_EFER 0xc0000080 /* extended feature register */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Set the LM-bit */</span><br><span style="color: hsl(120, 100%, 40%);">+ msr_t msr = rdmsr(MSR_EFER);</span><br><span style="color: hsl(120, 100%, 40%);">+ msr.lo |= (1 << 8);</span><br><span style="color: hsl(120, 100%, 40%);">+ wrmsr(MSR_EFER, msr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_INFO, "MMU: enabled long mode\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Paging isn't enabled here!</span><br><span style="color: hsl(120, 100%, 40%);">+ * c_start.S will enable it to enter long mode.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/commonlib/include/commonlib/cbmem_id.h b/src/commonlib/include/commonlib/cbmem_id.h</span><br><span>index 042ea6e..366cb3e 100644</span><br><span>--- a/src/commonlib/include/commonlib/cbmem_id.h</span><br><span>+++ b/src/commonlib/include/commonlib/cbmem_id.h</span><br><span>@@ -62,6 +62,7 @@</span><br><span> #define CBMEM_ID_STAGEx_CACHE 0x57a9e100</span><br><span> #define CBMEM_ID_STAGEx_RAW 0x57a9e200</span><br><span> #define CBMEM_ID_STORAGE_DATA 0x53746f72</span><br><span style="color: hsl(120, 100%, 40%);">+#define CBMEM_ID_TTB 0x54544200</span><br><span> #define CBMEM_ID_TCPA_LOG 0x54435041</span><br><span> #define CBMEM_ID_TCPA_TCG_LOG 0x54445041</span><br><span> #define CBMEM_ID_TIMESTAMP 0x54494d45</span><br><span>diff --git a/src/cpu/qemu-x86/Kconfig b/src/cpu/qemu-x86/Kconfig</span><br><span>index 70cce9b..a90acf6 100644</span><br><span>--- a/src/cpu/qemu-x86/Kconfig</span><br><span>+++ b/src/cpu/qemu-x86/Kconfig</span><br><span>@@ -18,7 +18,8 @@</span><br><span> select ARCH_BOOTBLOCK_X86_32</span><br><span> select ARCH_VERSTAGE_X86_32</span><br><span> select ARCH_ROMSTAGE_X86_32</span><br><span style="color: hsl(0, 100%, 40%);">- select ARCH_RAMSTAGE_X86_32</span><br><span style="color: hsl(120, 100%, 40%);">+ #select ARCH_RAMSTAGE_X86_32</span><br><span style="color: hsl(120, 100%, 40%);">+ select ARCH_RAMSTAGE_X86_64</span><br><span> select SMP</span><br><span> select UDELAY_TSC</span><br><span> select C_ENVIRONMENT_BOOTBLOCK</span><br><span>diff --git a/src/cpu/x86/Makefile.inc b/src/cpu/x86/Makefile.inc</span><br><span>index 3e8a664..1c9b83e 100644</span><br><span>--- a/src/cpu/x86/Makefile.inc</span><br><span>+++ b/src/cpu/x86/Makefile.inc</span><br><span>@@ -4,7 +4,7 @@</span><br><span> endif</span><br><span> endif</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-subdirs-y += pae</span><br><span style="color: hsl(120, 100%, 40%);">+#subdirs-y += pae</span><br><span> subdirs-$(CONFIG_PARALLEL_MP) += name</span><br><span> ramstage-$(CONFIG_PARALLEL_MP) += mp_init.c</span><br><span> ramstage-$(CONFIG_MIRROR_PAYLOAD_TO_RAM_BEFORE_LOADING) += mirror_payload.c</span><br><span>diff --git a/src/lib/timestamp.c b/src/lib/timestamp.c</span><br><span>index 105b696..e2c7450 100644</span><br><span>--- a/src/lib/timestamp.c</span><br><span>+++ b/src/lib/timestamp.c</span><br><span>@@ -178,7 +178,7 @@</span><br><span> tse->entry_stamp = ts_time - ts_table->base_time;</span><br><span> </span><br><span> if (IS_ENABLED(CONFIG_TIMESTAMPS_ON_CONSOLE))</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_SPEW, "Timestamp - %s: %" PRIu64 "\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_SPEW, "Timestamp - %s: %llu\n",</span><br><span> timestamp_name(id), ts_time);</span><br><span> </span><br><span> if (ts_table->num_entries == ts_table->max_entries)</span><br><span>diff --git a/src/mainboard/emulation/qemu-q35/Kconfig b/src/mainboard/emulation/qemu-q35/Kconfig</span><br><span>index 3be034a..f14867b 100644</span><br><span>--- a/src/mainboard/emulation/qemu-q35/Kconfig</span><br><span>+++ b/src/mainboard/emulation/qemu-q35/Kconfig</span><br><span>@@ -12,6 +12,7 @@</span><br><span> select MAINBOARD_HAS_NATIVE_VGA_INIT</span><br><span> select MAINBOARD_FORCE_NATIVE_VGA_INIT</span><br><span> select BOOTBLOCK_CONSOLE</span><br><span style="color: hsl(120, 100%, 40%);">+ select IDT_IN_EVERY_STAGE</span><br><span> </span><br><span> config MAINBOARD_DIR</span><br><span> string</span><br><span>diff --git a/src/mainboard/emulation/qemu-q35/Makefile.inc b/src/mainboard/emulation/qemu-q35/Makefile.inc</span><br><span>index 1503220..65b8e70 100644</span><br><span>--- a/src/mainboard/emulation/qemu-q35/Makefile.inc</span><br><span>+++ b/src/mainboard/emulation/qemu-q35/Makefile.inc</span><br><span>@@ -2,4 +2,6 @@</span><br><span> ramstage-y += ../qemu-i440fx/memory.c</span><br><span> ramstage-y += ../qemu-i440fx/fw_cfg.c</span><br><span> romstage-y += ../qemu-i440fx/memory.c</span><br><span style="color: hsl(120, 100%, 40%);">+romstage-y += ../../../arch/x86/mmu.c</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> bootblock-y += bootblock.c</span><br><span>diff --git a/src/mainboard/emulation/qemu-q35/romstage.c b/src/mainboard/emulation/qemu-q35/romstage.c</span><br><span>index 2b8d935..592d33d 100644</span><br><span>--- a/src/mainboard/emulation/qemu-q35/romstage.c</span><br><span>+++ b/src/mainboard/emulation/qemu-q35/romstage.c</span><br><span>@@ -21,15 +21,27 @@</span><br><span> #include <timestamp.h></span><br><span> #include <southbridge/intel/i82801ix/i82801ix.h></span><br><span> #include <program_loading.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/mmu.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/exception.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "../qemu-i440fx/memory.h"</span><br><span> </span><br><span> asmlinkage void car_stage_entry(void)</span><br><span> {</span><br><span> i82801ix_early_init();</span><br><span> console_init();</span><br><span style="color: hsl(120, 100%, 40%);">+ exception_init();</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- cbmem_recovery(0);</span><br><span style="color: hsl(120, 100%, 40%);">+ cbmem_initialize_empty();</span><br><span> </span><br><span> timestamp_add_now(TS_START_ROMSTAGE);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ mmu_init();</span><br><span style="color: hsl(120, 100%, 40%);">+ mmu_config_range(0, 0x100000000ULL, PAT_WT);</span><br><span style="color: hsl(120, 100%, 40%);">+ mmu_config_range(0, (uint64_t)qemu_get_memory_size() * 1024ULL, PAT_WB);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (qemu_get_high_memory_size() > 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ mmu_config_range(0x100000000ULL, (uint64_t)qemu_get_high_memory_size() * 1024ULL, PAT_WB);</span><br><span style="color: hsl(120, 100%, 40%);">+ mmu_install_pagetables();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> run_ramstage();</span><br><span> }</span><br><span>diff --git a/src/southbridge/intel/common/smi.c b/src/southbridge/intel/common/smi.c</span><br><span>index 3c25556..b543b8b 100644</span><br><span>--- a/src/southbridge/intel/common/smi.c</span><br><span>+++ b/src/southbridge/intel/common/smi.c</span><br><span>@@ -150,7 +150,7 @@</span><br><span> "outb %%al, %%dx\n\t"</span><br><span> : /* ignore result */</span><br><span> : "a" (APM_CNT_GNVS_UPDATE),</span><br><span style="color: hsl(0, 100%, 40%);">- "b" ((u32)gnvs),</span><br><span style="color: hsl(120, 100%, 40%);">+ "b" ((u32)(uintptr_t)gnvs),</span><br><span> "d" (APM_CNT)</span><br><span> );</span><br><span> }</span><br><span>diff --git a/src/southbridge/intel/i82801ix/hdaudio.c b/src/southbridge/intel/i82801ix/hdaudio.c</span><br><span>index 607604b..b4cee46 100644</span><br><span>--- a/src/southbridge/intel/i82801ix/hdaudio.c</span><br><span>+++ b/src/southbridge/intel/i82801ix/hdaudio.c</span><br><span>@@ -278,7 +278,7 @@</span><br><span> // NOTE this will break as soon as the Azalia get's a bar above</span><br><span> // 4G. Is there anything we can do about it?</span><br><span> base = res2mmio(res, 0, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_DEBUG, "Azalia: base = %08x\n", (u32)base);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_DEBUG, "Azalia: base = %p\n", base);</span><br><span> codec_mask = codec_detect(base);</span><br><span> </span><br><span> if (codec_mask) {</span><br><span>diff --git a/src/southbridge/intel/i82801ix/lpc.c b/src/southbridge/intel/i82801ix/lpc.c</span><br><span>index a69b879..5d7a226c 100644</span><br><span>--- a/src/southbridge/intel/i82801ix/lpc.c</span><br><span>+++ b/src/southbridge/intel/i82801ix/lpc.c</span><br><span>@@ -553,7 +553,7 @@</span><br><span> </span><br><span> /* Add it to SSDT. */</span><br><span> acpigen_write_scope("\\");</span><br><span style="color: hsl(0, 100%, 40%);">- acpigen_write_name_dword("NVSA", (u32) gnvs);</span><br><span style="color: hsl(120, 100%, 40%);">+ acpigen_write_name_dword("NVSA", (u32) (uintptr_t)gnvs);</span><br><span> acpigen_pop_len();</span><br><span> }</span><br><span> }</span><br><span>diff --git a/src/southbridge/intel/i82801ix/sata.c b/src/southbridge/intel/i82801ix/sata.c</span><br><span>index dcdeeb4..71030948 100644</span><br><span>--- a/src/southbridge/intel/i82801ix/sata.c</span><br><span>+++ b/src/southbridge/intel/i82801ix/sata.c</span><br><span>@@ -32,7 +32,7 @@</span><br><span> u32 reg32;</span><br><span> </span><br><span> /* Initialize AHCI memory-mapped space */</span><br><span style="color: hsl(0, 100%, 40%);">- u8 *abar = (u8 *)pci_read_config32(dev, PCI_BASE_ADDRESS_5);</span><br><span style="color: hsl(120, 100%, 40%);">+ u8 *abar = (u8 *)(uintptr_t)pci_read_config32(dev, PCI_BASE_ADDRESS_5);</span><br><span> printk(BIOS_DEBUG, "ABAR: %p\n", abar);</span><br><span> </span><br><span> /* Set AHCI access mode.</span><br><span>diff --git a/util/cbfstool/elf.h b/util/cbfstool/elf.h</span><br><span>index a0bb35d..43fd7f3 100644</span><br><span>--- a/util/cbfstool/elf.h</span><br><span>+++ b/util/cbfstool/elf.h</span><br><span>@@ -1148,6 +1148,43 @@</span><br><span> /* Keep this the last entry. */</span><br><span> #define R_386_NUM 38</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* AMD64 specific definitions. */</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_NONE 0 /* relocation types */</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_64 1</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_PC32 2</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_GOT32 3</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_PLT32 4</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_COPY 5</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_GLOB_DAT 6</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_JUMP_SLOT 7</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_RELATIVE 8</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_GOTPCREL 9</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_32 10</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_32S 11</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_16 12</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_PC16 13</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_8 14</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_PC8 15</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_DTPMOD64 16</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_DTPOFF64 17</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_TPOFF64 18</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_TLSGD 19</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_TLSLD 20</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_DTPOFF32 21</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_GOTTPOFF 22</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_TPOFF32 23</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_PC64 24</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_GOTOFF64 25</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_GOTPC32 26</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_GOT64 27 /* reserved for future expansion */</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_GOTPCREL64 28 /* reserved for future expansion */</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_GOTPC64 29 /* reserved for future expansion */</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_GOTPLT64 30 /* reserved for future expansion */</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_PLTOFF64 31 /* reserved for future expansion */</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_SIZE32 32</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_SIZE64 33</span><br><span style="color: hsl(120, 100%, 40%);">+#define R_AMD64_NUM 34</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* SUN SPARC specific definitions. */</span><br><span> </span><br><span> /* Legal values for ST_TYPE subfield of st_info (symbol type). */</span><br><span>diff --git a/util/cbfstool/elfheaders.c b/util/cbfstool/elfheaders.c</span><br><span>index 9d02c30..8da54d0 100644</span><br><span>--- a/util/cbfstool/elfheaders.c</span><br><span>+++ b/util/cbfstool/elfheaders.c</span><br><span>@@ -1072,6 +1072,9 @@</span><br><span> case EM_386:</span><br><span> type = R_386_32;</span><br><span> break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case EM_X86_64:</span><br><span style="color: hsl(120, 100%, 40%);">+ type = R_AMD64_64;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span> case EM_ARM:</span><br><span> type = R_ARM_ABS32;</span><br><span> break;</span><br><span>diff --git a/util/cbfstool/rmodule.c b/util/cbfstool/rmodule.c</span><br><span>index 07957cb..b7969c9 100644</span><br><span>--- a/util/cbfstool/rmodule.c</span><br><span>+++ b/util/cbfstool/rmodule.c</span><br><span>@@ -43,6 +43,29 @@</span><br><span> return (type == R_386_32);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int valid_reloc_amd64(Elf64_Rela *rel)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int type;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ type = ELF64_R_TYPE(rel->r_info);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Only these 2 relocations are expected to be found. */</span><br><span style="color: hsl(120, 100%, 40%);">+ return (type == R_AMD64_64 ||</span><br><span style="color: hsl(120, 100%, 40%);">+ type == R_AMD64_PC64 ||</span><br><span style="color: hsl(120, 100%, 40%);">+ type == R_AMD64_32S ||</span><br><span style="color: hsl(120, 100%, 40%);">+ type == R_AMD64_32 ||</span><br><span style="color: hsl(120, 100%, 40%);">+ type == R_AMD64_PC32);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int should_emit_amd64(Elf64_Rela *rel)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int type;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ type = ELF64_R_TYPE(rel->r_info);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return (type == R_AMD64_64);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int valid_reloc_arm(Elf64_Rela *rel)</span><br><span> {</span><br><span> int type;</span><br><span>@@ -100,6 +123,11 @@</span><br><span> .should_emit = should_emit_386,</span><br><span> },</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+ .arch = EM_X86_64,</span><br><span style="color: hsl(120, 100%, 40%);">+ .valid_type = valid_reloc_amd64,</span><br><span style="color: hsl(120, 100%, 40%);">+ .should_emit = should_emit_amd64,</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+ {</span><br><span> .arch = EM_ARM,</span><br><span> .valid_type = valid_reloc_arm,</span><br><span> .should_emit = should_emit_arm,</span><br><span>diff --git a/util/xcompile/xcompile b/util/xcompile/xcompile</span><br><span>index 6d82a4d..60d8a39 100755</span><br><span>--- a/util/xcompile/xcompile</span><br><span>+++ b/util/xcompile/xcompile</span><br><span>@@ -236,7 +236,13 @@</span><br><span> # The Quark processor doesn't support the instructions</span><br><span> # introduced with the Pentium 6 architecture, so allow it</span><br><span> # to use i586 instead.</span><br><span style="color: hsl(0, 100%, 40%);">-if [ "${TARCH}" = "x86_64" ] || [ "${TARCH}" = "x86_32" ]; then</span><br><span style="color: hsl(120, 100%, 40%);">+if [ "${TARCH}" = "x86_64" ]; then</span><br><span style="color: hsl(120, 100%, 40%);">+cat <<EOF</span><br><span style="color: hsl(120, 100%, 40%);">+ GCC_CFLAGS_${TARCH} += -march=core2</span><br><span style="color: hsl(120, 100%, 40%);">+EOF</span><br><span style="color: hsl(120, 100%, 40%);">+fi</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+if [ "${TARCH}" = "x86_32" ]; then</span><br><span> cat <<EOF</span><br><span> </span><br><span> ifneq (\$(CONFIG_USE_MARCH_586)\$(CONFIG_LP_USE_MARCH_586),)</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/29667">change 29667</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/29667"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: If2f02a95b2f91ab51043d4e81054354f4a6eb5d5 </div>
<div style="display:none"> Gerrit-Change-Number: 29667 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Patrick Rudolph <patrick.rudolph@9elements.com> </div>
<div style="display:none"> Gerrit-Reviewer: Patrick Rudolph <siro@das-labor.org> </div>