<p>Xiang Wang has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/27972">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">riscv: update misaligned memory access exception handling<br><br>Support for more situations: floating point, compressed instructions, etc.<br>Add support for redirect exception to s-mode.<br>fix DEFINE_MPRV_READ to support that reading the page which is executable-only (R=0 X=1).<br><br>Change-Id: I9983d56245eab1d458a84cb1432aeb805df7a49f<br>Signed-off-by: Xiang Wang <wxjstz@126.com><br>---<br>M src/arch/riscv/Makefile.inc<br>A src/arch/riscv/fp_asm.S<br>M src/arch/riscv/include/arch/exception.h<br>M src/arch/riscv/include/vm.h<br>A src/arch/riscv/misaligend.c<br>M src/arch/riscv/trap_handler.c<br>6 files changed, 617 insertions(+), 65 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/72/27972/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/arch/riscv/Makefile.inc b/src/arch/riscv/Makefile.inc</span><br><span>index 85bec43..86ed8b5 100644</span><br><span>--- a/src/arch/riscv/Makefile.inc</span><br><span>+++ b/src/arch/riscv/Makefile.inc</span><br><span>@@ -46,6 +46,8 @@</span><br><span> bootblock-y = bootblock.S stages.c</span><br><span> bootblock-y += trap_util.S</span><br><span> bootblock-y += trap_handler.c</span><br><span style="color: hsl(120, 100%, 40%);">+bootblock-y += fp_asm.S</span><br><span style="color: hsl(120, 100%, 40%);">+bootblock-y += misaligend.c</span><br><span> bootblock-y += mcall.c</span><br><span> bootblock-y += virtual_memory.c</span><br><span> bootblock-y += boot.c</span><br><span>diff --git a/src/arch/riscv/fp_asm.S b/src/arch/riscv/fp_asm.S</span><br><span>new file mode 100644</span><br><span>index 0000000..92546b4</span><br><span>--- /dev/null</span><br><span>+++ b/src/arch/riscv/fp_asm.S</span><br><span>@@ -0,0 +1,341 @@</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 (C) 2018 HardenedLinux</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%);">+#if __riscv_flen >= 32</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ .text</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* void read_f32(int regnum, uint32_t* v) */</span><br><span style="color: hsl(120, 100%, 40%);">+ .align 1</span><br><span style="color: hsl(120, 100%, 40%);">+ .globl read_f32</span><br><span style="color: hsl(120, 100%, 40%);">+read_f32:</span><br><span style="color: hsl(120, 100%, 40%);">+ la a2, .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ andi a0, a0, 31</span><br><span style="color: hsl(120, 100%, 40%);">+ slli a0, a0, 2</span><br><span style="color: hsl(120, 100%, 40%);">+ add a0, a0, a2</span><br><span style="color: hsl(120, 100%, 40%);">+ lw a0, 0(a0)</span><br><span style="color: hsl(120, 100%, 40%);">+ add a0, a0, a2</span><br><span style="color: hsl(120, 100%, 40%);">+ jr a0</span><br><span style="color: hsl(120, 100%, 40%);">+ .align 2</span><br><span style="color: hsl(120, 100%, 40%);">+.Lr32_t:</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f0 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f1 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f2 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f3 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f4 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f5 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f6 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f7 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f8 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f9 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f10 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f11 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f12 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f13 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f14 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f15 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f16 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f17 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f18 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f19 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f20 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f21 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f22 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f23 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f24 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f25 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f26 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f27 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f28 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f29 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f30 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr32_f31 - .Lr32_t</span><br><span style="color: hsl(120, 100%, 40%);">+#define read32(which) .Lr32_##which: fsw which, 0(a1); ret</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f0)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f1)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f2)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f3)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f4)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f5)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f6)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f7)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f8)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f9)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f10)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f11)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f12)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f13)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f14)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f15)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f16)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f17)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f18)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f19)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f20)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f21)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f22)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f23)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f24)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f25)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f26)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f27)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f28)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f29)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f30)</span><br><span style="color: hsl(120, 100%, 40%);">+ read32(f31)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* void write_f32(int regnum, uint32_t* v) */</span><br><span style="color: hsl(120, 100%, 40%);">+ .align 1</span><br><span style="color: hsl(120, 100%, 40%);">+ .globl write_f32</span><br><span style="color: hsl(120, 100%, 40%);">+write_f32:</span><br><span style="color: hsl(120, 100%, 40%);">+ la a2, .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ andi a0, a0, 31</span><br><span style="color: hsl(120, 100%, 40%);">+ slli a0, a0, 2</span><br><span style="color: hsl(120, 100%, 40%);">+ add a0, a0, a2</span><br><span style="color: hsl(120, 100%, 40%);">+ lw a0, 0(a0)</span><br><span style="color: hsl(120, 100%, 40%);">+ add a0, a0, a2</span><br><span style="color: hsl(120, 100%, 40%);">+ jr a0</span><br><span style="color: hsl(120, 100%, 40%);">+ .align 2</span><br><span style="color: hsl(120, 100%, 40%);">+.Lw32_t:</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f0 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f1 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f2 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f3 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f4 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f5 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f6 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f7 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f8 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f9 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f10 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f11 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f12 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f13 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f14 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f15 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f16 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f17 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f18 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f19 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f20 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f21 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f22 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f23 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f24 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f25 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f26 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f27 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f28 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f29 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f30 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw32_f31 - .Lw32_t</span><br><span style="color: hsl(120, 100%, 40%);">+#define write32(which) .Lw32_##which: flw which, 0(a1); ret</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f0)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f1)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f2)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f3)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f4)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f5)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f6)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f7)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f8)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f9)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f10)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f11)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f12)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f13)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f14)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f15)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f16)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f17)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f18)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f19)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f20)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f21)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f22)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f23)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f24)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f25)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f26)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f27)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f28)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f29)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f30)</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(f31)</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%);">+#if __riscv_flen >= 64</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ .text</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* void read_f64(int regnum, uint64_t* v) */</span><br><span style="color: hsl(120, 100%, 40%);">+ .align 1</span><br><span style="color: hsl(120, 100%, 40%);">+ .globl read_f64</span><br><span style="color: hsl(120, 100%, 40%);">+read_f64:</span><br><span style="color: hsl(120, 100%, 40%);">+ la a2, .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ andi a0, a0, 31</span><br><span style="color: hsl(120, 100%, 40%);">+ slli a0, a0, 2</span><br><span style="color: hsl(120, 100%, 40%);">+ add a0, a0, a2</span><br><span style="color: hsl(120, 100%, 40%);">+ lw a0, 0(a0)</span><br><span style="color: hsl(120, 100%, 40%);">+ add a0, a0, a2</span><br><span style="color: hsl(120, 100%, 40%);">+ jr a0</span><br><span style="color: hsl(120, 100%, 40%);">+ .align 2</span><br><span style="color: hsl(120, 100%, 40%);">+.Lr64_t:</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f0 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f1 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f2 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f3 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f4 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f5 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f6 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f7 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f8 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f9 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f10 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f11 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f12 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f13 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f14 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f15 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f16 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f17 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f18 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f19 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f20 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f21 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f22 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f23 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f24 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f25 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f26 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f27 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f28 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f29 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f30 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lr64_f31 - .Lr64_t</span><br><span style="color: hsl(120, 100%, 40%);">+#define read64(which) .Lr64_##which: fsd which, 0(a1); ret</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f0)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f1)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f2)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f3)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f4)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f5)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f6)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f7)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f8)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f9)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f10)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f11)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f12)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f13)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f14)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f15)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f16)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f17)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f18)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f19)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f20)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f21)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f22)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f23)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f24)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f25)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f26)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f27)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f28)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f29)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f30)</span><br><span style="color: hsl(120, 100%, 40%);">+ read64(f31)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* void write_f64(int regnum, uint64_t* v) */</span><br><span style="color: hsl(120, 100%, 40%);">+ .align 1</span><br><span style="color: hsl(120, 100%, 40%);">+ .globl write_f64</span><br><span style="color: hsl(120, 100%, 40%);">+write_f64:</span><br><span style="color: hsl(120, 100%, 40%);">+ la a2, .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ andi a0, a0, 31</span><br><span style="color: hsl(120, 100%, 40%);">+ slli a0, a0, 2</span><br><span style="color: hsl(120, 100%, 40%);">+ add a0, a0, a2</span><br><span style="color: hsl(120, 100%, 40%);">+ lw a0, 0(a0)</span><br><span style="color: hsl(120, 100%, 40%);">+ add a0, a0, a2</span><br><span style="color: hsl(120, 100%, 40%);">+ jr a0</span><br><span style="color: hsl(120, 100%, 40%);">+ .align 2</span><br><span style="color: hsl(120, 100%, 40%);">+.Lw64_t:</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f0 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f1 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f2 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f3 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f4 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f5 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f6 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f7 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f8 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f9 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f10 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f11 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f12 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f13 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f14 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f15 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f16 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f17 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f18 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f19 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f20 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f21 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f22 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f23 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f24 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f25 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f26 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f27 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f28 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f29 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f30 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+ .word .Lw64_f31 - .Lw64_t</span><br><span style="color: hsl(120, 100%, 40%);">+#define write64(which) .Lw64_##which: fld which, 0(a1); ret</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f0)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f1)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f2)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f3)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f4)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f5)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f6)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f7)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f8)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f9)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f10)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f11)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f12)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f13)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f14)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f15)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f16)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f17)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f18)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f19)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f20)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f21)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f22)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f23)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f24)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f25)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f26)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f27)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f28)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f29)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f30)</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(f31)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span>diff --git a/src/arch/riscv/include/arch/exception.h b/src/arch/riscv/include/arch/exception.h</span><br><span>index fc57b3b..6fbbdf0 100644</span><br><span>--- a/src/arch/riscv/include/arch/exception.h</span><br><span>+++ b/src/arch/riscv/include/arch/exception.h</span><br><span>@@ -32,8 +32,7 @@</span><br><span> </span><br><span> #include <stdint.h></span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-typedef struct</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(120, 100%, 40%);">+typedef struct {</span><br><span> uintptr_t gpr[32];</span><br><span> uintptr_t status;</span><br><span> uintptr_t epc;</span><br><span>@@ -53,9 +52,9 @@</span><br><span> {</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void trap_handler(trapframe* tf);</span><br><span style="color: hsl(0, 100%, 40%);">-void handle_supervisor_call(trapframe* tf);</span><br><span style="color: hsl(0, 100%, 40%);">-void handle_misaligned_load(trapframe *tf);</span><br><span style="color: hsl(0, 100%, 40%);">-void handle_misaligned_store(trapframe *tf);</span><br><span style="color: hsl(120, 100%, 40%);">+void redirect_trap(void);</span><br><span style="color: hsl(120, 100%, 40%);">+void trap_handler(trapframe *tf);</span><br><span style="color: hsl(120, 100%, 40%);">+void handle_supervisor_call(trapframe *tf);</span><br><span style="color: hsl(120, 100%, 40%);">+void handle_misaligned(trapframe *tf);</span><br><span> </span><br><span> #endif</span><br><span>diff --git a/src/arch/riscv/include/vm.h b/src/arch/riscv/include/vm.h</span><br><span>index a30d6bb..2925977 100644</span><br><span>--- a/src/arch/riscv/include/vm.h</span><br><span>+++ b/src/arch/riscv/include/vm.h</span><br><span>@@ -42,7 +42,7 @@</span><br><span> static inline type name(type *p); \</span><br><span> static inline type name(type *p) \</span><br><span> { \</span><br><span style="color: hsl(0, 100%, 40%);">- size_t mprv = MSTATUS_MPRV; \</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t mprv = MSTATUS_MPRV | MSTATUS_MXR; \</span><br><span> type value; \</span><br><span> asm ( \</span><br><span> "csrs mstatus, %1\n" \</span><br><span>diff --git a/src/arch/riscv/misaligend.c b/src/arch/riscv/misaligend.c</span><br><span>new file mode 100644</span><br><span>index 0000000..a282a05</span><br><span>--- /dev/null</span><br><span>+++ b/src/arch/riscv/misaligend.c</span><br><span>@@ -0,0 +1,253 @@</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 (C) 2018 HardenedLinux</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%);">+#include <stddef.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <vm.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%);">+/* this function define in src/arch/riscv/fp_asm.S */</span><br><span style="color: hsl(120, 100%, 40%);">+#if __riscv_flen >= 32</span><br><span style="color: hsl(120, 100%, 40%);">+extern void read_f32(int regnum, uint32_t *v);</span><br><span style="color: hsl(120, 100%, 40%);">+extern void write_f32(int regnum, uint32_t *v);</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%);">+#if __riscv_flen >= 64</span><br><span style="color: hsl(120, 100%, 40%);">+extern void read_f64(int regnum, uint64_t *v);</span><br><span style="color: hsl(120, 100%, 40%);">+extern void write_f64(int regnum, uint64_t *v);</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+union endian_buff {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t b[8];</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t h[4];</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t w[2];</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t d[1];</span><br><span style="color: hsl(120, 100%, 40%);">+ uintptr_t v;</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%);">+struct memory_instruction_info {</span><br><span style="color: hsl(120, 100%, 40%);">+ uintptr_t opcode;</span><br><span style="color: hsl(120, 100%, 40%);">+ uintptr_t mask;</span><br><span style="color: hsl(120, 100%, 40%);">+ int reg_shift;</span><br><span style="color: hsl(120, 100%, 40%);">+ int reg_mask;</span><br><span style="color: hsl(120, 100%, 40%);">+ int reg_addition;</span><br><span style="color: hsl(120, 100%, 40%);">+ int is_fp;</span><br><span style="color: hsl(120, 100%, 40%);">+ int is_load;</span><br><span style="color: hsl(120, 100%, 40%);">+ int width;</span><br><span style="color: hsl(120, 100%, 40%);">+ int sign_extend;</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 struct memory_instruction_info insn_info[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+#if __riscv_xlen == 128</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00002000, 0x0000e003, 2, 7, 8, 0, 1, 16, 1}, // C.LQ</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00002000, 0x0000e003, 2, 7, 8, 1, 1, 8, 0}, // C.FLD</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00004000, 0x0000e003, 2, 7, 8, 0, 1, 4, 1}, // C.LW</span><br><span style="color: hsl(120, 100%, 40%);">+#if __riscv_xlen == 32</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00006000, 0x0000e003, 2, 7, 8, 1, 1, 4, 0}, // C.FLW</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00006000, 0x0000e003, 2, 7, 8, 0, 1, 8, 1}, // C.LD</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%);">+#if __riscv_xlen == 128</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x0000a000, 0x0000e003, 2, 7, 8, 0, 0, 16, 0}, // C.SQ</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x0000a000, 0x0000e003, 2, 7, 8, 1, 0, 8, 0}, // C.FSD</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x0000c000, 0x0000e003, 2, 7, 8, 0, 0, 4, 0}, // C.SW</span><br><span style="color: hsl(120, 100%, 40%);">+#if __riscv_xlen == 32</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x0000e000, 0x0000e003, 2, 7, 8, 1, 0, 4, 0}, // C.FSW</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x0000e000, 0x0000e003, 2, 7, 8, 0, 0, 8, 0}, // C.SD</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%);">+#if __riscv_xlen == 128</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00002002, 0x0000e003, 7, 15, 0, 0, 1, 16, 1}, // C.LQSP</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00002002, 0x0000e003, 7, 15, 0, 1, 1, 8, 0}, // C.FLDSP</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00004002, 0x0000e003, 7, 15, 0, 0, 1, 4, 1}, // C.LWSP</span><br><span style="color: hsl(120, 100%, 40%);">+#if __riscv_xlen == 32</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00006002, 0x0000e003, 7, 15, 0, 1, 1, 4, 0}, // C.FLWSP</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00006002, 0x0000e003, 7, 15, 0, 0, 1, 8, 1}, // C.LDSP</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%);">+#if __riscv_xlen == 128</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x0000a002, 0x0000e003, 2, 15, 0, 0, 0, 16, 0}, // C.SQSP</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x0000a002, 0x0000e003, 2, 15, 0, 1, 0, 8, 0}, // C.FSDSP</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x0000c002, 0x0000e003, 2, 15, 0, 0, 0, 4, 0}, // C.SWSP</span><br><span style="color: hsl(120, 100%, 40%);">+#if __riscv_xlen == 32</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x0000e002, 0x0000e003, 2, 15, 0, 1, 0, 4, 0}, // C.FSWSP</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x0000e002, 0x0000e003, 2, 15, 0, 0, 0, 8, 0}, // C.SDSP</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%);">+ { 0x00000003, 0x0000707f, 7, 15, 0, 0, 1, 1, 1}, // LB</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00001003, 0x0000707f, 7, 15, 0, 0, 1, 2, 1}, // LH</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00002003, 0x0000707f, 7, 15, 0, 0, 1, 4, 1}, // LW</span><br><span style="color: hsl(120, 100%, 40%);">+#if __riscv_xlen > 32</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00003003, 0x0000707f, 7, 15, 0, 0, 1, 8, 1}, // LD</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00004003, 0x0000707f, 7, 15, 0, 0, 1, 1, 0}, // LBU</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00005003, 0x0000707f, 7, 15, 0, 0, 1, 2, 0}, // LHU</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00006003, 0x0000707f, 7, 15, 0, 0, 1, 4, 0}, // LWU</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00000023, 0x0000707f, 20, 15, 0, 0, 0, 1, 0}, // SB</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00001023, 0x0000707f, 20, 15, 0, 0, 0, 2, 0}, // SH</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00002023, 0x0000707f, 20, 15, 0, 0, 0, 4, 0}, // SW</span><br><span style="color: hsl(120, 100%, 40%);">+#if __riscv_xlen > 32</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00003023, 0x0000707f, 20, 15, 0, 0, 0, 8, 0}, // SD</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%);">+#if __riscv_flen >= 32</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00002007, 0x0000707f, 7, 15, 0, 1, 1, 4, 0}, // FLW</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00003007, 0x0000707f, 7, 15, 0, 1, 1, 8, 0}, // FLD</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%);">+#if __riscv_flen >= 64</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00002027, 0x0000707f, 20, 15, 0, 1, 0, 4, 0}, // FSW</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0x00003027, 0x0000707f, 20, 15, 0, 1, 0, 8, 0}, // FSD</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0, 0, 0, 0, 0, 0, 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%);">+static struct memory_instruction_info *match_instruction(uintptr_t insn)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct memory_instruction_info *p;</span><br><span style="color: hsl(120, 100%, 40%);">+ for (p = insn_info; p->opcode; p++)</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((insn & p->mask) == p->opcode)</span><br><span style="color: hsl(120, 100%, 40%);">+ return p;</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</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 int fetch_16bit_instruction(uintptr_t vaddr, uintptr_t *insn)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t t = mprv_read_u16((uint16_t *)vaddr);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (EXTRACT_FIELD(t, 0x3) != 3) {</span><br><span style="color: hsl(120, 100%, 40%);">+ *insn = t;</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ return -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%);">+static int fetch_32bit_instruction(uintptr_t vaddr, uintptr_t *insn)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t t = mprv_read_u32((uint32_t *)vaddr);</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((EXTRACT_FIELD(t, 0x3) == 3) && (EXTRACT_FIELD(t, 0x1c) != 0x7)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ *insn = t;</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ return -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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void handle_misaligned(trapframe *tf)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uintptr_t insn = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ union endian_buff buff;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* try to fetch 16/32 bits instruction */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (fetch_16bit_instruction(tf->epc, &insn))</span><br><span style="color: hsl(120, 100%, 40%);">+ if (fetch_32bit_instruction(tf->epc, &insn))</span><br><span style="color: hsl(120, 100%, 40%);">+ redirect_trap();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* matching instruction */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct memory_instruction_info *match = match_instruction(insn);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (match) {</span><br><span style="color: hsl(120, 100%, 40%);">+ int regnum = ((insn >> match->reg_shift) & match->reg_mask) + \</span><br><span style="color: hsl(120, 100%, 40%);">+ match->reg_addition;</span><br><span style="color: hsl(120, 100%, 40%);">+ buff.v = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (match->is_load) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* load operate */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* reading from memory by bytes prevents misaligned</span><br><span style="color: hsl(120, 100%, 40%);">+ * memory access */</span><br><span style="color: hsl(120, 100%, 40%);">+ for (int i = 0; i < match->width; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+ buff.b[i] = mprv_read_u8((uint8_t *) \</span><br><span style="color: hsl(120, 100%, 40%);">+ (tf->badvaddr + i));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* sign extend for signed integer loading */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (match->sign_extend)</span><br><span style="color: hsl(120, 100%, 40%);">+ if (buff.v >> (8 * match->width - 1))</span><br><span style="color: hsl(120, 100%, 40%);">+ buff.v |= -1 << (8 * match->width);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* write to register */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (match->is_fp) {</span><br><span style="color: hsl(120, 100%, 40%);">+ do {</span><br><span style="color: hsl(120, 100%, 40%);">+#if __riscv_flen >= 32</span><br><span style="color: hsl(120, 100%, 40%);">+ /* single-precision floating-point */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (match->width == 4) {</span><br><span style="color: hsl(120, 100%, 40%);">+ write_f32(regnum, buff.w);</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%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+#if __riscv_flen >= 64</span><br><span style="color: hsl(120, 100%, 40%);">+ /* double-precision floating-point */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (match->width == 8) {</span><br><span style="color: hsl(120, 100%, 40%);">+ write_f64(regnum, buff.d);</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%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+ redirect_trap();</span><br><span style="color: hsl(120, 100%, 40%);">+ } while (0);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ tf->gpr[regnum] = buff.v;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* store operate */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* reading from register */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (match->is_fp) {</span><br><span style="color: hsl(120, 100%, 40%);">+ do {</span><br><span style="color: hsl(120, 100%, 40%);">+#if __riscv_flen >= 32</span><br><span style="color: hsl(120, 100%, 40%);">+ if (match->width == 4) {</span><br><span style="color: hsl(120, 100%, 40%);">+ read_f32(regnum, buff.w);</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%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+#if __riscv_flen >= 64</span><br><span style="color: hsl(120, 100%, 40%);">+ if (match->width == 8) {</span><br><span style="color: hsl(120, 100%, 40%);">+ read_f64(regnum, buff.d);</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%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+ redirect_trap();</span><br><span style="color: hsl(120, 100%, 40%);">+ } while (0);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ buff.v = tf->gpr[regnum];</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%);">+ /* writing to memory by bytes prevents misaligned\</span><br><span style="color: hsl(120, 100%, 40%);">+ * memory access */</span><br><span style="color: hsl(120, 100%, 40%);">+ for (int i = 0; i < match->width; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+ mprv_write_u8((uint8_t *)(tf->badvaddr + i), \</span><br><span style="color: hsl(120, 100%, 40%);">+ buff.b[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ redirect_trap();</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%);">+</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>diff --git a/src/arch/riscv/trap_handler.c b/src/arch/riscv/trap_handler.c</span><br><span>index 7b35c2e..6888c8d 100644</span><br><span>--- a/src/arch/riscv/trap_handler.c</span><br><span>+++ b/src/arch/riscv/trap_handler.c</span><br><span>@@ -167,11 +167,11 @@</span><br><span> break;</span><br><span> case CAUSE_MISALIGNED_LOAD:</span><br><span> print_trap_information(tf);</span><br><span style="color: hsl(0, 100%, 40%);">- handle_misaligned_load(tf);</span><br><span style="color: hsl(120, 100%, 40%);">+ handle_misaligned(tf);</span><br><span> return;</span><br><span> case CAUSE_MISALIGNED_STORE:</span><br><span> print_trap_information(tf);</span><br><span style="color: hsl(0, 100%, 40%);">- handle_misaligned_store(tf);</span><br><span style="color: hsl(120, 100%, 40%);">+ handle_misaligned(tf);</span><br><span> return;</span><br><span> default:</span><br><span> printk(BIOS_EMERG, "================================\n");</span><br><span>@@ -184,62 +184,19 @@</span><br><span> die("Can't recover from trap. Halting.\n");</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static uint32_t fetch_instruction(uintptr_t vaddr) {</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_SPEW, "fetching instruction at 0x%016zx\n", (size_t)vaddr);</span><br><span style="color: hsl(0, 100%, 40%);">- return mprv_read_u32((uint32_t *) vaddr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void redirect_trap(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ write_csr(sbadaddr, read_csr(mbadaddr));</span><br><span style="color: hsl(120, 100%, 40%);">+ write_csr(sepc, read_csr(mepc));</span><br><span style="color: hsl(120, 100%, 40%);">+ write_csr(scause, read_csr(mcause));</span><br><span style="color: hsl(120, 100%, 40%);">+ write_csr(mepc, read_csr(stvec));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ uintptr_t status = read_csr(mstatus);</span><br><span style="color: hsl(120, 100%, 40%);">+ uintptr_t mpp = EXTRACT_FIELD(status, 0x1800);</span><br><span style="color: hsl(120, 100%, 40%);">+ status = INSERT_FIELD(status, 0x1800, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ status = INSERT_FIELD(status, 0x100, mpp & 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ write_csr(mstatus, status);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void handle_misaligned_load(trapframe *tf) {</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_DEBUG, "Trapframe ptr: %p\n", tf);</span><br><span style="color: hsl(0, 100%, 40%);">- uintptr_t faultingInstructionAddr = tf->epc;</span><br><span style="color: hsl(0, 100%, 40%);">- insn_t faultingInstruction = fetch_instruction(faultingInstructionAddr);</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_DEBUG, "Faulting instruction: 0x%x\n", faultingInstruction);</span><br><span style="color: hsl(0, 100%, 40%);">- insn_t widthMask = 0x7000;</span><br><span style="color: hsl(0, 100%, 40%);">- insn_t memWidth = (faultingInstruction & widthMask) >> 12;</span><br><span style="color: hsl(0, 100%, 40%);">- insn_t destMask = 0xF80;</span><br><span style="color: hsl(0, 100%, 40%);">- insn_t destRegister = (faultingInstruction & destMask) >> 7;</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_DEBUG, "Width: %d bits\n", (1 << memWidth) * 8);</span><br><span style="color: hsl(0, 100%, 40%);">- if (memWidth == 3) {</span><br><span style="color: hsl(0, 100%, 40%);">- // load double, handle the issue</span><br><span style="color: hsl(0, 100%, 40%);">- void* badAddress = (void*) tf->badvaddr;</span><br><span style="color: hsl(0, 100%, 40%);">- uint64_t value = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- for (int i = 0; i < 8; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">- value <<= 8;</span><br><span style="color: hsl(0, 100%, 40%);">- value += mprv_read_u8(badAddress+i);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- tf->gpr[destRegister] = value;</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- // panic, this should not have happened</span><br><span style="color: hsl(0, 100%, 40%);">- die("Code should not reach this path, misaligned on a non-64 bit store/load\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- // return to where we came from</span><br><span style="color: hsl(0, 100%, 40%);">- write_csr(mepc, read_csr(mepc) + 4);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void handle_misaligned_store(trapframe *tf) {</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_DEBUG, "Trapframe ptr: %p\n", tf);</span><br><span style="color: hsl(0, 100%, 40%);">- uintptr_t faultingInstructionAddr = tf->epc;</span><br><span style="color: hsl(0, 100%, 40%);">- insn_t faultingInstruction = fetch_instruction(faultingInstructionAddr);</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_DEBUG, "Faulting instruction: 0x%x\n", faultingInstruction);</span><br><span style="color: hsl(0, 100%, 40%);">- insn_t widthMask = 0x7000;</span><br><span style="color: hsl(0, 100%, 40%);">- insn_t memWidth = (faultingInstruction & widthMask) >> 12;</span><br><span style="color: hsl(0, 100%, 40%);">- insn_t srcMask = 0x1F00000;</span><br><span style="color: hsl(0, 100%, 40%);">- insn_t srcRegister = (faultingInstruction & srcMask) >> 20;</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_DEBUG, "Width: %d bits\n", (1 << memWidth) * 8);</span><br><span style="color: hsl(0, 100%, 40%);">- if (memWidth == 3) {</span><br><span style="color: hsl(0, 100%, 40%);">- // store double, handle the issue</span><br><span style="color: hsl(0, 100%, 40%);">- void* badAddress = (void*) tf->badvaddr;</span><br><span style="color: hsl(0, 100%, 40%);">- uint64_t value = tf->gpr[srcRegister];</span><br><span style="color: hsl(0, 100%, 40%);">- for (int i = 0; i < 8; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">- mprv_write_u8(badAddress+i, value);</span><br><span style="color: hsl(0, 100%, 40%);">- value >>= 8;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- // panic, this should not have happened</span><br><span style="color: hsl(0, 100%, 40%);">- die("Code should not reach this path, misaligned on a non-64 bit store/load\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- // return to where we came from</span><br><span style="color: hsl(0, 100%, 40%);">- write_csr(mepc, read_csr(mepc) + 4);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/27972">change 27972</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/27972"/><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: I9983d56245eab1d458a84cb1432aeb805df7a49f </div>
<div style="display:none"> Gerrit-Change-Number: 27972 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Xiang Wang <wxjstz@126.com> </div>