[PATCH v7 11/11] target/riscv: Add system test for Smmpt34

LIU Zhiwei <[email protected]>
Newsgroups org.nongnu.qemu-riscv,org.nongnu.qemu-devel
Message-ID <[email protected]>
Add SMMPT system-test coverage for Smmpt34, the RV32-only memory
protection scheme (2-level MPT with 4-byte entries).

Smmpt34 requires a 32-bit CPU, but qemu-system-riscv64 can run a 32-bit
CPU (-cpu rv32), so the test lives in tests/tcg/riscv64 alongside the
RV64 Smmpt tests and shares the same harness (smmpt-common.S). It only
differs in the table geometry: 4-byte MPTEs, two radix levels, a 10-bit
level-0 index and the RV32 mmpt CSR layout (MODE in bits[31:30]). It
exercises the same permission and structural checks as the RV64 tests
(all XWR encodings for load and store, V=0 and reserved-bit leaves, and
NAPOT leaves with a valid and a reserved G field), using the same access
addresses. It is built for RV32 and run on qemu-system-riscv64 with
-cpu rv32.

Signed-off-by: LIU Zhiwei <[email protected]>
---
 tests/tcg/riscv64/test-smmpt34.S | 97 ++++++++++++++++++++++++++++++++
 1 file changed, 97 insertions(+)
 create mode 100644 tests/tcg/riscv64/test-smmpt34.S

diff --git a/tests/tcg/riscv64/test-smmpt34.S b/tests/tcg/riscv64/test-smmpt34.S
new file mode 100644
index 0000000000..92c8320999
--- /dev/null
+++ b/tests/tcg/riscv64/test-smmpt34.S
@@ -0,0 +1,97 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Test for the Smmpt34 (Supervisor Memory Protection Table) extension,
+ * per SMMTT specification v0.4.9.  Smmpt34 is the RV32-only scheme.
+ *
+ * Although Smmpt34 requires a 32-bit CPU, the program is run on
+ * qemu-system-riscv64 with a 32-bit CPU (-cpu rv32), which lives in the
+ * same target as the RV64 Smmpt tests.  It is therefore kept here in
+ * tests/tcg/riscv64 alongside the other Smmpt tests and shares the same
+ * harness (smmpt-common.S).  Build it for RV32 and run it as:
+ *
+ *   $CC -march=rv32ima_zicsr -mabi=ilp32 -I tests/tcg/riscv64 \
+ *       tests/tcg/riscv64/test-smmpt34.S -Wa,--noexecstack -c -o smmpt34.o
+ *   $LD -m elf32lriscv -T tests/tcg/riscv64/semihost.ld smmpt34.o -o smmpt34
+ *   qemu-system-riscv64 -cpu rv32,x-smmpt=true -M virt -display none \
+ *       -semihosting -device loader,file=smmpt34
+ *
+ * Smmpt34 uses a 2-level MPT with 4-byte entries (8 pages per leaf,
+ * pi = SPA[14:12]).  The supervisor physical address is partitioned as
+ * pn[1] = SPA[33:25] (9-bit root index), pn[0] = SPA[24:15] (10-bit level-0
+ * index) and range offset SPA[14:0].  For the RAM addresses used here
+ * (0x8xxx_xxxx, < 4 GiB) pn[1] resolves to 64.  See smmpt-common.S for the
+ * MPRV trick, the shared address layout and the exit-code convention.
+ *
+ * This test reuses the same shared harness and the same access addresses as
+ * the RV64 tests; only the table geometry (4-byte entries, 2 levels, 10-bit
+ * level-0 index) and the RV32 mmpt layout differ.
+ *
+ * MPT layout (Smmpt34, 2 levels, 4-byte entries):
+ *
+ *   L1 (root) @ 0x8040_0000 : entry[64]  -> non-leaf, PPN(L0)=0x80410
+ *   L0        @ 0x8041_0000 :
+ *     entry[160] -> non-NAPOT leaf (LEAF_ALL_XWR)  covering 0x8050_0000+
+ *     entry[162] -> V=0 (invalid)                  covering 0x8051_0000
+ *     entry[164] -> leaf with a reserved bit set    covering 0x8052_0000
+ *     entry[192] -> NAPOT leaf, G=6, XWR=RW         covering 0x8060_0000
+ *     entry[256] -> NAPOT leaf, reserved G=0        covering 0x8080_0000
+ *
+ *   mmpt = MODE(1=Smmpt34)<<30 | PPN(0x80400)
+ */
+
+#include "smmpt-common.S"
+
+	.option	norvc
+
+	.text
+	.global	_start
+_start:
+	/* Install the M-mode trap handler */
+	lla	t0, mtrap
+	csrw	mtvec, t0
+	csrw	medeleg, zero
+
+	/* PMP entry 0: NAPOT covering the whole space, RWX. */
+	li	t0, -1
+	csrw	pmpaddr0, t0
+	li	t0, 0x1f
+	csrw	pmpcfg0, t0
+
+	/* Build the MPT tables (M-mode stores bypass the MPT). */
+	/* L1[64] = non-leaf -> L0 (PPN 0x80410): (0x80410 << 10) | V */
+	li	t0, 0x80400000
+	li	t1, 0x20104001
+	sw	t1, 0x100(t0)		/* 64 * 4 = 0x100 */
+
+	li	t0, 0x80410000
+	/* L0[160] = non-NAPOT leaf carrying all XWR encodings (pi0..pi7) */
+	li	t1, LEAF_ALL_XWR
+	sw	t1, 0x280(t0)		/* 160 * 4 = 0x280 */
+	/* L0[162] = 0: invalid entry (V=0) */
+	sw	x0, 0x288(t0)		/* 162 * 4 = 0x288 */
+	/* L0[164] = leaf with reserved bit 3 set (V|L|rsv|XWR[pi0]=RW) */
+	li	t1, 0x30B
+	sw	t1, 0x290(t0)		/* 164 * 4 = 0x290 */
+	/* L0[192] = NAPOT leaf: V|L|N | XWR=RW(0x300) | G=6(0x6000) */
+	li	t1, 0x6307
+	sw	t1, 0x300(t0)		/* 192 * 4 = 0x300 */
+	/* L0[256] = NAPOT leaf with reserved G=0: V|L|N | XWR=RW | G=0 */
+	li	t1, 0x307
+	sw	t1, 0x400(t0)		/* 256 * 4 = 0x400 */
+
+	/* Program mmpt: MODE=1 (Smmpt34) at bits[31:30], PPN = 0x80400 */
+	li	t0, 0x40080400
+	csrw	0x382, t0		/* CSR_MMPT */
+
+	/* mfence.pa must not fault in M-mode */
+	TEST_MFENCE_PA 1
+
+	/* Run the shared permission and structural checks */
+	RUN_LEAF_CHECKS
+
+	/* All tests passed */
+	li	a0, 0
+	j	_exit
+
+	SMMPT_HARNESS
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.