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