From 17fc77cef28990033e7b12486befcc7fa9867e16 Mon Sep 17 00:00:00 2001 From: Jordan Niethe Date: Tue, 7 Jul 2020 20:37:52 +1000 Subject: [PATCH 1/2] core: Implement PVR register Microwatt has been allocated a PVR version of 0x0063. Implement a PVR with this value. Signed-off-by: Jordan Niethe --- common.vhdl | 3 +++ execute1.vhdl | 3 +++ 2 files changed, 6 insertions(+) diff --git a/common.vhdl b/common.vhdl index 18378d5..a193df1 100644 --- a/common.vhdl +++ b/common.vhdl @@ -6,6 +6,8 @@ library work; use work.decode_types.all; package common is + -- Processor Version Number + constant PVR_MICROWATT : std_ulogic_vector(31 downto 0) := x"00630000"; -- MSR bit numbers constant MSR_SF : integer := (63 - 0); -- Sixty-Four bit mode @@ -43,6 +45,7 @@ package common is constant SPR_HSPRG1 : spr_num_t := 305; constant SPR_PID : spr_num_t := 48; constant SPR_PRTBL : spr_num_t := 720; + constant SPR_PVR : spr_num_t := 287; -- GPR indices in the register file (GPR only) subtype gpr_index_t is std_ulogic_vector(4 downto 0); diff --git a/execute1.vhdl b/execute1.vhdl index a1cd008..3b2007a 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -766,6 +766,9 @@ begin spr_val := ctrl.dec; when SPR_CFAR => spr_val := ctrl.cfar; + when SPR_PVR => + spr_val(63 downto 32) := (others => '0'); + spr_val(31 downto 0) := PVR_MICROWATT; when 724 => -- LOG_ADDR SPR spr_val := log_wr_addr & r.log_addr_spr; when 725 => -- LOG_DATA SPR From 737ebd92f583d18f4b78c21d07de3f26edb57678 Mon Sep 17 00:00:00 2001 From: Jordan Niethe Date: Wed, 8 Jul 2020 14:34:42 +1000 Subject: [PATCH 2/2] tests: Add tests for the PVR The PVR is a privileged read-only SPR. Test reading and writing in both supervisor and problem state. In supervisor state reading returns microwatt's assigned PVR number and writing is a noop. In problem state both reading and writing cause privileged instruction interrupts. Signed-off-by: Jordan Niethe --- tests/misc/head.S | 37 ++++++++++++++++++++++++++++++ tests/misc/misc.c | 18 +++++++++++++++ tests/privileged/privileged.c | 17 ++++++++++++++ tests/test_misc.bin | Bin 5288 -> 5424 bytes tests/test_misc.console_out | 2 ++ tests/test_privileged.bin | Bin 16408 -> 16408 bytes tests/test_privileged.console_out | 2 ++ 7 files changed, 76 insertions(+) diff --git a/tests/misc/head.S b/tests/misc/head.S index 9eb752c..b0acb7f 100644 --- a/tests/misc/head.S +++ b/tests/misc/head.S @@ -16,6 +16,7 @@ */ #define STACK_TOP 0x2000 +#define PVR 287 /* Load an immediate 64-bit value into a register */ #define LOAD_IMM64(r, e) \ @@ -100,3 +101,39 @@ test_addpcis_2: blr +/* Test reading the PVR */ +.global test_mfpvr +test_mfpvr: + mflr %r0 + std %r0, 16(%r1) + stdu %r1, -32(%r1) + + /* + * If r3 happened to already contain PVR_MICROWATT the test + * would succeed even if the PVR is not implemented. + */ + LOAD_IMM64(%r3, 0xdeadbeef) + mfpvr %r3 + + addi %r1, %r1, 32 + ld %r0, 16(%r1) + mtlr %r0 + + blr + +/* Test writing the PVR does nothing */ +.global test_mtpvr +test_mtpvr: + mflr %r0 + std %r0, 16(%r1) + stdu %r1, -32(%r1) + + LOAD_IMM64(%r3, 0xdeadbeef) + mtspr PVR, %r3 + mfpvr %r3 + + addi %r1, %r1, 32 + ld %r0, 16(%r1) + mtlr %r0 + + blr diff --git a/tests/misc/misc.c b/tests/misc/misc.c index f96203e..283ca7f 100644 --- a/tests/misc/misc.c +++ b/tests/misc/misc.c @@ -8,8 +8,12 @@ #define PASS "PASS\n" #define FAIL "FAIL\n" +#define PVR_MICROWATT 0x00630000 + extern long test_addpcis_1(void); extern long test_addpcis_2(void); +extern long test_mfpvr(void); +extern long test_mtpvr(void); // i < 100 void print_test_number(int i) @@ -40,5 +44,19 @@ int main(void) } else puts(PASS); + print_test_number(3); + if (test_mfpvr() != PVR_MICROWATT) { + fail = 1; + puts(FAIL); + } else + puts(PASS); + + print_test_number(4); + if (test_mtpvr() != PVR_MICROWATT) { + fail = 1; + puts(FAIL); + } else + puts(PASS); + return fail; } diff --git a/tests/privileged/privileged.c b/tests/privileged/privileged.c index 154e9b4..68e30bc 100644 --- a/tests/privileged/privileged.c +++ b/tests/privileged/privileged.c @@ -15,6 +15,7 @@ extern int call_with_msr(unsigned long arg, int (*fn)(unsigned long), unsigned l #define SRR1 27 #define PID 48 #define PRTBL 720 +#define PVR 287 static inline unsigned long mfspr(int sprnum) { @@ -186,6 +187,20 @@ int priv_fn_6(unsigned long x) return 0; } +int priv_fn_7(unsigned long x) +{ + mfspr(PVR); + __asm__ volatile("sc"); + return 0; +} + +int priv_fn_8(unsigned long x) +{ + mtspr(PVR, x); + __asm__ volatile("sc"); + return 0; +} + int priv_test(int (*fn)(unsigned long)) { unsigned long msr; @@ -239,6 +254,8 @@ int main(void) do_test(4, priv_fn_4); do_test(5, priv_fn_5); do_test(6, priv_fn_6); + do_test(7, priv_fn_7); + do_test(8, priv_fn_8); return fail; } diff --git a/tests/test_misc.bin b/tests/test_misc.bin index f080480ecd9086a9638636dee8f5753ca4511f4f..7e68e1cca7d67ba1d7e134d6bb8dd93a9c3640fe 100755 GIT binary patch delta 388 zcmZ3Xxj}2ff{8gi;tUK4HVh2O3CGxzE7smiPIP*2W9?)|0bx~9CI$}%piVA^dYOO^$u$NH$rfAKlWYDmLd2~Y z5-dJWt`sn4JUe-l|NZx#h^9UTO?@X+y#a%wMaA#OVf7P$nn3Pi x0J=*7=&nqtf)JqPAaRgbC{!#5Nz4%{)`29Z3l&?k*-_A+k?F;s&69-0m;klth-Lr) delta 198 zcmdm>wL){kg3UaPU-%{~Fy>4WFyUQLl58Qs!1&|hf5jiFlN|+wReKp3JQx@l61W)Z zWdc4V*BCG)TWn!Zt|^6zTQMY9WKOOWFlKa}yjDP3D1c#}t&pL zOF+uk22D5-s@;G=(W2t_}w}qP>^JDuAh8fL2@#OI?rSQMFrj)|NeVdvNCuu zFfb%MnQW*mJvl;Ahp}ODtD-y;C+p;8igvOGGLtO?7#M$C{IB>!_WytHYrp^18!*&c zY++BXSv#3gNnC0w3&a2`h6IaFDBFNR(c;SA%|=Q}jEtp|LzQPUefd54ld_ZS#oPbA zLAEilH|vWq%yVR9NKOD51=6r%a-d2w zECPY-|NoP0HcaMK6=&T6l$`)_H7Ce{4}lIWob0RG4RmFb4Li^=EQu`^OMyNF@i~Be a1t5Rw=Bujdj7%$jY_?O+mYB@wAPxZQGi(U} delta 207 zcmbQyz&N9Uae@Y;#YWBB3X>Dmc_w=(DzFOt|L+|+Iakr2amVDnite8miIH*b z#B-NMr0;i{Qdpk zdl^%8jQ~S~h2@|B-v9q6*(6MkRaIvUoZPC~z1cu5g^`Kj=jLhZ*%A{IA|^9Bhyws4 CL_*~N diff --git a/tests/test_privileged.console_out b/tests/test_privileged.console_out index a49bb9b..25e791c 100644 --- a/tests/test_privileged.console_out +++ b/tests/test_privileged.console_out @@ -4,3 +4,5 @@ test 03:PASS test 04:PASS test 05:PASS test 06:PASS +test 07:PASS +test 08:PASS