<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>