From 693f0501ce15d3bfd2ecc61b627db8888e640d0c Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Tue, 12 Dec 2023 13:19:17 +0100 Subject: [PATCH 1/3] minhv pma block test Signed-off-by: Kristine Dosvik --- cv32e40s/regress/cv32e40s_full.yaml | 6 + cv32e40s/tests/cfg/pma_test_cfg_2.yaml | 1 + .../custom/minhv_pma_block/minhv_pma_block.c | 174 ++++++++++++++++++ .../programs/custom/minhv_pma_block/test.yaml | 8 + 4 files changed, 189 insertions(+) create mode 100644 cv32e40s/tests/programs/custom/minhv_pma_block/minhv_pma_block.c create mode 100644 cv32e40s/tests/programs/custom/minhv_pma_block/test.yaml diff --git a/cv32e40s/regress/cv32e40s_full.yaml b/cv32e40s/regress/cv32e40s_full.yaml index 4ce0a40bd0..97184ca53b 100644 --- a/cv32e40s/regress/cv32e40s_full.yaml +++ b/cv32e40s/regress/cv32e40s_full.yaml @@ -583,3 +583,9 @@ tests: dir: cv32e40s/sim/uvmt cmd: make test TEST=mhpmcounter_write_test + minhv_pma_block: + description: test minhv=1 and pma block of mepc address + builds: [ uvmt_cv32e40s_pma_2 ] + dir: cv32e40s/sim/uvmt + cmd: make test TEST=minhv_pma_block + diff --git a/cv32e40s/tests/cfg/pma_test_cfg_2.yaml b/cv32e40s/tests/cfg/pma_test_cfg_2.yaml index 0edf69a0db..185269bf16 100644 --- a/cv32e40s/tests/cfg/pma_test_cfg_2.yaml +++ b/cv32e40s/tests/cfg/pma_test_cfg_2.yaml @@ -2,6 +2,7 @@ name: pma_test_cfg_2 description: PMA configuration for the PMA_TEST_CFG_2 test case compile_flags: > +define+PMA_TEST_CFG_2 + +define+CLIC_EN +define+ZBA_ZBB_ZBC_ZBS plusargs: > +enable_pma=1 diff --git a/cv32e40s/tests/programs/custom/minhv_pma_block/minhv_pma_block.c b/cv32e40s/tests/programs/custom/minhv_pma_block/minhv_pma_block.c new file mode 100644 index 0000000000..3ce0a9c16e --- /dev/null +++ b/cv32e40s/tests/programs/custom/minhv_pma_block/minhv_pma_block.c @@ -0,0 +1,174 @@ +// +// Copyright 2023 Silicon Labs, Inc. +// +// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://solderpad.org/licenses/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Author: Kristine Døsvik +// +// Test minhv=1 and pma block of mepc address. +// +///////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include + + +extern volatile uint32_t recovery_pt_mret; +volatile uint32_t g_entered_trap_handler; +volatile uint32_t g_trapped_mcause; + +int execute_from_io_region(); +__attribute__((interrupt ("machine"))) void u_sw_irq_handler(void); +void trap_handler(void); + + +int main(int argc, char **argv){ + + int is_failure = 0; + + is_failure += execute_from_io_region(); + + if(is_failure){ + return EXIT_FAILURE; + } else { + return EXIT_SUCCESS; + } +} + + +int execute_from_io_region() { + + volatile uint32_t io_addr = 0xFFFFEFFF << 2; + volatile uint32_t mcause_excode = 0x0; + volatile uint32_t mcause_excode_expected = 0x1; //Execution attempt from I/O region. + volatile uint32_t mret_dont_trap = 0; + volatile uint32_t test_fail = 0; + g_entered_trap_handler = 0; + + // Load an IO memory address into mepc + __asm__ volatile ( R"( + csrrw zero, mepc, %[io_addr] + )" :: [io_addr] "r"(io_addr)); + + // Set minhv and mpp = M + __asm__ volatile ( R"( + lui t0, 0x70000 + csrrs zero, mcause, t0 + )"::: "t0"); + + __asm__ volatile ( R"( + mret + )":::); + + // Mret traps. + + // This should never execute (deliberate dead code), as the mret make the pc take a jump + mret_dont_trap += 1; + + // Execution should continue here + __asm__ volatile ( R"( + .global recovery_pt_mret + recovery_pt_mret: add x0, x0, x0 + )":::); + + + mcause_excode = g_trapped_mcause & 0x7ff; + + printf("Mret traps: %08lx, expected: 1\n", g_entered_trap_handler); + printf("Mret dont trap: %08lx, expected: 0\n", mret_dont_trap); + printf("mcause excode: %08lx, expected: %08lx (execution attempt from I/O region).\n", mcause_excode, mcause_excode_expected); + test_fail += (g_entered_trap_handler != 1) || mret_dont_trap || (mcause_excode != mcause_excode_expected); + + printf("g_trapped_mcause: %08lx", g_trapped_mcause); + + return test_fail; +} + + +__attribute__((interrupt ("machine"))) +void u_sw_irq_handler(void) { + __asm__ volatile (R"( + # Backup "sp", use debug's own stack + # csrw dscratch0, sp + # la sp, __debugger_stack_start + + # Backup all GPRs + sw a0, -4(sp) + sw a1, -8(sp) + sw a2, -12(sp) + sw a3, -16(sp) + sw a4, -20(sp) + sw a5, -24(sp) + sw a6, -28(sp) + sw a7, -32(sp) + sw t0, -36(sp) + sw t1, -40(sp) + sw t2, -44(sp) + sw t3, -48(sp) + sw t4, -52(sp) + sw t5, -56(sp) + sw t6, -60(sp) + addi sp, sp, -64 + cm.push {ra, s0-s11}, -64 + + # Call the handler actual + call ra, trap_handler + + # Restore all GPRs + cm.pop {ra, s0-s11}, 64 + addi sp, sp, 64 + lw a0, -4(sp) + lw a1, -8(sp) + lw a2, -12(sp) + lw a3, -16(sp) + lw a4, -20(sp) + lw a5, -24(sp) + lw a6, -28(sp) + lw a7, -32(sp) + lw t0, -36(sp) + lw t1, -40(sp) + lw t2, -44(sp) + lw t3, -48(sp) + lw t4, -52(sp) + lw t5, -56(sp) + lw t6, -60(sp) + + # Restore "sp" + # csrr sp, dscratch0 + + # Done + mret + )"); +} + +void trap_handler(void) { + + g_entered_trap_handler += 1; + + __asm__ volatile ( R"( + # Get recovery mepc and replace mepc + la t0, recovery_pt_mret + csrrw zero, mepc, t0 + + # read and clear mcause except mpp, which is set + 4: lui t0, 0x30000 + csrrw %[g_trapped_mcause], mcause, t0 + + )" : [g_trapped_mcause]"=r"(g_trapped_mcause) :: "t0"); + + return; +} + diff --git a/cv32e40s/tests/programs/custom/minhv_pma_block/test.yaml b/cv32e40s/tests/programs/custom/minhv_pma_block/test.yaml new file mode 100644 index 0000000000..4f43e93d63 --- /dev/null +++ b/cv32e40s/tests/programs/custom/minhv_pma_block/test.yaml @@ -0,0 +1,8 @@ +name: minhv_pma_block +uvm_test: uvmt_$(CV_CORE_LC)_firmware_test_c +description: > + Use CFG=p,a_test_cfg_2. Test minhv=1 and pma block of mepc address +plusargs: > + +clic_irq_clear_on_ack=0 +cflags: > + -mno-relax From 4283aa4ca619463a9925d3c4c673b5894751b918 Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Tue, 12 Dec 2023 13:36:59 +0100 Subject: [PATCH 2/3] add minhv_pma_block to vplan Signed-off-by: Kristine Dosvik --- .../Simulation/interrupts/CV32E40SX_CLIC.csv | 2 +- .../Simulation/interrupts/CV32E40SX_CLIC.json | 2 +- .../Simulation/interrupts/CV32E40SX_CLIC.xlsx | Bin 38990 -> 38973 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.csv b/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.csv index aa233dbbfb..5c9e6559a6 100644 --- a/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.csv +++ b/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.csv @@ -58,7 +58,7 @@ CLIC 8675ec,Interrupt CSR,mtvt,"Function ptr reads treated as instruction fetch, Note, instruction fetch is treated as an implicit read, thus do not require PMP read permissions, but execute permission is required. -Both the pointer fetch and the fetch of the actual instruction located at the pointer address should be covered by the above restrictions. ",Assertion Check,"ENV capability, not specific test",Functional Coverage,clic::invalid_mtvt_ptr_exec_mret +Both the pointer fetch and the fetch of the actual instruction located at the pointer address should be covered by the above restrictions. ",Assertion Check,"ENV capability, not specific test",Functional Coverage,"clic::invalid_mtvt_ptr_exec_mret, minhv_pma_block.c" UM v0.3.0 Common,Interrupt CSR,mtvt,"Always aligned to 2^(max(6, 2+SMCLIC_ID_WIDTH)","Assert that mtvt [max(6, 2+SMCLIC_ID_WIDTH)-1:0] = 0",Assertion Check,"ENV capability, not specific test",Functional Coverage,a_mtvt_alignment_correct CLIC 8675ec,Interrupt CSR,mtvt,"Determine alignment by software access, Write ones to lower order bits and read back",Test that correct alignment can be inferred by writing to these fields and read back.,Self Checking Test,Directed Self-Checking,Testcase,clic :: w_mtvt_rd_alignment diff --git a/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.json b/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.json index 3f639822ff..ed0491458a 100644 --- a/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.json +++ b/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.json @@ -338,7 +338,7 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "ENV capability, not specific test", "Coverage Method": "Functional Coverage", - "Link to Coverage": "clic::invalid_mtvt_ptr_exec_mret" + "Link to Coverage": "clic::invalid_mtvt_ptr_exec_mret, minhv_pma_block.c" }, { "Requirement Location": "UM v0.3.0 Common", diff --git a/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.xlsx b/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.xlsx index fed058066c2573899d4036afd5ca50347c7c11d6..9af84b66045a780ba6fbe47cbbc0a8d4896cd9b4 100644 GIT binary patch delta 2212 zcmYjSS6Gt^5=}x6y-6rir7k5X9T5;hPe5tHMWrbMp$4y_KoBBg1cdwq#70+Xfh8pL zqV(QW1nE_Jhg|Aq-S6AI=Vi`!9?m?>nVFsvNNowE1i{48`G_$CP6q;M04OFwY`_~h zUwC@iY2*>=^MyouBI+i@IhRy$@Yi+k;0AezxNbDSX@9t09Yc`mwk*$VYH>NFjV@z~ zt?SVWYlWW%tnlrLhmWI4#xkBOEhewMcO5cK&=LW!_ zOkO)7+t&9Vw+Rl$>20r}C5k!N{MaX%kM=@}4j$PRIQwc=;Ns@h8 zBYwQ0p25owmJx%zKQGGr1Zf`M0MDZ9@E(V3!8W&LuG^Cnb7Ju8H1Te7=2$rF=tSp2jLp(VL^!7r0n4cDl5 zFznW($A=K}E%Nmw;Cn%AV>m6qG_bNgsU>3B=!p7aSg$hB3PN^Qs_KxA<>IUMu++42xIb)KclMzaqfH!{UIU@;_R0L zRZ&L!%dW60r`LBpE~oW;033w&4xU%iM`mYz8Fo?ZCmm2Vxn{5Fs>ZYrCg3!nB%Q#? zKmQeHkE&{y*AK{^{;byb*t&bUxQ46`NGS6IZvYN*FVqRb;Et)`8UmEqWwB=~)H)%% zs(T|s#T8O1U$*3I|3VG^an~f*NIBZQs0V3|Mo?vk8f{R4= z3$_Vh@okPOM}SvdIhM8Vl9z|)V(@3n9>r%)%qGPa?F`xeo6P3DJ@wVy*Qt(UjDINX zP6uMl;#}unJBVP{>*(lu+QM^Ax*I7PgYgpTmmOxpM(yX@>tXNJJ3aU$iM}=w^<^uRzUiD{iy_a)Y}LhDxsBo(K`vdvAUJB!Q){irW8k7VHLgEr zC<|BD2|1x74{%zjv#jX8^cRGKK(1tIgaBONs(#4k#cnS{&OD3g2RE(Phr3F{)=%jG zRVF^N(|r?u2K85Wmr}?%co{JEnzfV!S492nNn^~uQm21m3R?AJOX^_LtWOOs2JWC( zLVwTqv{vya$*;%d3*Dvd?pDo-zFQHno9G6nZ^PP>0F>VqAxpg3(?2s!tua8vj#`j( zSuthNk;=opVnu;=A)=yT3k{|WnPyfRHdFJzluS%jIi}g!I00Nq9t}GZ+UNm2=FwGl z2xF-r<;!buRn8{Oye|onk{YqKP`zG78A>yNvI(*MfWgzaj-JL(B570!$Am(!9Jfqn;wd{UGeo#UFP0-1N*Uc;7IkentP7Y zS2(2qJtg1xZH9mRYcBvrp9}?ofPScuqKzdOq6FdtF@l&uAdm#;_c;;=f!tR>AlRAm ze;l#_r+_hpS^2E+1J21R5R&R|nvtvmRs{Nz4ZsBeH&I;VfBE?ZIy3$!){Frp(EzLs zBoNIYA`gN1P+?%3s0O(mdPb!IREh#v9|%p+gCHY-#}Nv^d@>iXl_CW81K3mT&fMKo j<^G#C;AJX57z^a4UIAMHv#EMuT|n}c3}YkVKi&QYG&Lah delta 2224 zcmYjSX*kr28=V;q31i8WG49PWwsA4G6b578-O5399j^dbbD)(8DjV|>J z$#T0ka}x^HFI96vjaF1w`gLC};rHqnt<40^k9W0KHeC;^6p;_@&SAu(!%4F*<21wd z&Bmi}UQSn^d(*CI_`iUZASWa$?G^$*Rnz>x^Ytzf(`T(eBA6zpHFK41*&00e< zde7gSMC+NL;cZ8Lv~pSFR*zJ)R9&{AkJYPlK~@lDJ9|6$i5<6icjl>EI}*m#o(ez! zE2!T>`k)v4+EZHDy>(~WSJ$j^!s6J|UDJl}e#Lg#9_f>xcEw$d*k2SFE9TrOM~1yg zL7mCGwll=)*OmPD{8?H`?V=b{LfjNsb-P9w>u9d!5kTmb((y8Zsgbph#|2|~FYu{Q zuxJjg=r7BF#st|`f%};0#3zRyByg(>b|a={NGOk1-YQvPP#}c*k*h?>A}+(}$!8U~ zMsl*RXWTg%isXEOIA*>L^X%$ZAc(d+dKaeY)gQ|d2G77n)=6EeFVX}gybZ3zxf~sy zd4{8+mDWwlOWkWy3~;(duI?$hE9gpHvE2sbML~42~$y!4OpORxsH!+lD=sJBxK8Crs)<*4EyT zUfy7Z>0@F-OXYb9sCx~JyVZ^&H@+VRH=nSz^4JU&FHVh(5)^wBK}kUlMjPgySt*_E zP*2}A8~A0d2h;^)re#;O9jUT^7;gQz!RxuA>h@q*$VNe))? zC2X&+i)qcnyi#O8`sjJ0PN!+W`uNB9iSwi-S?2s3NpU-wPG|pRV-eAZ^Rztu@h7p` z@gp?g;+gUMp|QNtH?n=IDW$$b7Fg^XffJEO4UzHgd-in&bM!0XdD&yJR3`Gll5b+P zfbv8rKS>+!BNUjgjZedz{9fjM5k-7;Qyz7CM9Foq^P55ujZX#3pt8rMAQSEZiWVMe zZkx`&OH^H*vzO1YLRe=Od@dB$uvFbRM>V`CD zGiQ%e_H162B|g5o)NM0|`hk8>Bxp2?7+xBh+D&xmcWGybRHrW(C)D)K7M7_X94y-& z0^F^dK4h<@?-|**oe)fc6jCNFEv0EekXBd#gyfe~YMS^S+JEeOw<@6$o9llu7zmBN z@1YV-BW^p8UZF__FEw(>M!87V9<;E3{i0K4SycO)2T%5~DpL4-d8F~65jcX=jnUca znT#zC8Pi)>pbqHR?up&XI6aywq4B9QSa%g0vgpRkFFOC^ujY}rcQ+e*S58D*2VdW4 zW&`g$nPCBVkRb#KGCKcg2T9=sBG-ebF+G?hA9-_GQX2ldB)RJvr^T@K%-A-sqfH^S zj%*ZosU5q?o1{p#g3*jRi5Nwwr={8Srz2W3M12aXFCPVFK{xD%<^NcC&+uPQk2TnR za>$N-5sR_8qo(>ue!b>BN(E0*=9M z9Lrr{!+CeD=@%4slKbNh^C_Brw8bEs$M zbYqag8G=fhrxF2oP~JteZGk{uzzJBWPyn>?O?M~KA17)td_1n6^2Qxh}6!U z?+PVspidKOH;OpQLlPRaeu;j&B)44^^j|Tl z!HB=b_R(xO!~dM_5bK`m3{3aKvdjZ|A(DJCdX^sh93sF4PTTPeTS6vbH`7)l)lGPl zkdow=AGmXua6@;!>Zo53k&FFV^6rTPJ`_u2#yD+pu`&&=y7+Ct^EHOgj&AJ^Ub-`w zHoua+ir7dPTF$$F`RdfLM(HU>Lu%@Gg>5r^9fY|GS#_S5L%V*hu<2M9#?XBh-x4C>JJp_bqcx*1F< z9E^%UgR^vXSa8H4lm_uxSm-&>HwzDQqk?`^EI6Ji07k_K@cefK0Qa)&pe^9JY&rD5 mzJfv^+b{@3@IT5S$^bL7b)l}{Xg2=vF~J-e&N13Qguel~g!2dh From 8be0b2cec8db57325b63303574b073e857528384 Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Tue, 12 Dec 2023 14:39:27 +0100 Subject: [PATCH 3/3] remove uncomment code, fix io address, include bsp Signed-off-by: Kristine Dosvik --- .../programs/custom/minhv_pma_block/minhv_pma_block.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/cv32e40s/tests/programs/custom/minhv_pma_block/minhv_pma_block.c b/cv32e40s/tests/programs/custom/minhv_pma_block/minhv_pma_block.c index 3ce0a9c16e..cafc28a3ff 100644 --- a/cv32e40s/tests/programs/custom/minhv_pma_block/minhv_pma_block.c +++ b/cv32e40s/tests/programs/custom/minhv_pma_block/minhv_pma_block.c @@ -24,7 +24,9 @@ #include #include #include +#include "bsp.h" +#define RND_ADDRS_IN_PMA_CFG_2_IO_REGION 0xE0100010 extern volatile uint32_t recovery_pt_mret; volatile uint32_t g_entered_trap_handler; @@ -51,9 +53,9 @@ int main(int argc, char **argv){ int execute_from_io_region() { - volatile uint32_t io_addr = 0xFFFFEFFF << 2; + volatile uint32_t io_addr = RND_ADDRS_IN_PMA_CFG_2_IO_REGION; volatile uint32_t mcause_excode = 0x0; - volatile uint32_t mcause_excode_expected = 0x1; //Execution attempt from I/O region. + volatile uint32_t mcause_excode_expected = EXC_CAUSE_INSTR_ACC_FAULT; //Execution attempt from I/O region. volatile uint32_t mret_dont_trap = 0; volatile uint32_t test_fail = 0; g_entered_trap_handler = 0; @@ -101,10 +103,6 @@ int execute_from_io_region() { __attribute__((interrupt ("machine"))) void u_sw_irq_handler(void) { __asm__ volatile (R"( - # Backup "sp", use debug's own stack - # csrw dscratch0, sp - # la sp, __debugger_stack_start - # Backup all GPRs sw a0, -4(sp) sw a1, -8(sp)