From 693f0501ce15d3bfd2ecc61b627db8888e640d0c Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Tue, 12 Dec 2023 13:19:17 +0100 Subject: [PATCH 01/18] 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 02/18] 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 03/18] 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) From a7040dbbef23f950e5b95be88349f044e058bba2 Mon Sep 17 00:00:00 2001 From: Marton Teilgard Date: Wed, 13 Dec 2023 11:28:28 +0100 Subject: [PATCH 04/18] added necessary overrides for clic Signed-off-by: Marton Teilgard --- cv32e40s/tests/cfg/pma_test_cfg_2.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cv32e40s/tests/cfg/pma_test_cfg_2.yaml b/cv32e40s/tests/cfg/pma_test_cfg_2.yaml index 185269bf16..5c2b0e7a7f 100644 --- a/cv32e40s/tests/cfg/pma_test_cfg_2.yaml +++ b/cv32e40s/tests/cfg/pma_test_cfg_2.yaml @@ -5,6 +5,7 @@ compile_flags: > +define+CLIC_EN +define+ZBA_ZBB_ZBC_ZBS plusargs: > + +enable_clic=1 +enable_pma=1 +enable_zca_extension=1 +enable_zcb_extension=1 @@ -17,6 +18,13 @@ plusargs: > +enable_zbc_extension=1 +enable_zbs_extension=1 ovpsim: > + --override cpu/CLICLEVELS=256 + --override cpu/CLICXCSW=T + --override cpu/CLICXNXTI=T + --override cpu/CLICSELHVEC=T + --override cpu/CLICINTCTLBITS=8 + --override cpu/CLIC_version=master + --override cpu/externalCLIC=T --override cpu/PMP_registers=64 --override cpu/PMP_undefined=T --override cpu/PMP_initialparams=T From 55beae5506f8560757e2fd3363c66e10479ee19a Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Thu, 14 Dec 2023 14:11:31 +0100 Subject: [PATCH 05/18] choose to do file substitution Signed-off-by: Kristine Dosvik --- bin/merge.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bin/merge.sh b/bin/merge.sh index e7e2e8bbdf..79e046e36e 100755 --- a/bin/merge.sh +++ b/bin/merge.sh @@ -90,6 +90,12 @@ substitute_file_content_40s_into_40x () { echo "=== Exchange 40x/X with 40s/S in file content ===" + read -p "Exchange 40x/X with 40s/S in file content? y/n " yn + case $yn in + [Yy]* ) ;; + * ) echo "Skip content substitution"; return;; + esac + find . -type f -exec grep -Il . {} + | egrep -iv '\/\.|40sx|40xs' | xargs -n1 sed -i 's/40s/40x/g' find . -type f -exec grep -Il . {} + | egrep -iv '\/\.|40sx|40xs' | xargs -n1 sed -i 's/40S/40X/g' From 6a1f2f717b31293c23f89d8638f9e66b8e1b3cf0 Mon Sep 17 00:00:00 2001 From: Robin Pedersen Date: Thu, 14 Dec 2023 16:49:10 +0100 Subject: [PATCH 06/18] detect pma load/store fault, use in assert Signed-off-by: Robin Pedersen --- cv32e40s/tb/uvmt/uvmt_cv32e40s_pma_assert.sv | 28 +++++++++++++++---- .../uvma_rvfi/uvma_rvfi_instr_if.sv | 25 +++++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/cv32e40s/tb/uvmt/uvmt_cv32e40s_pma_assert.sv b/cv32e40s/tb/uvmt/uvmt_cv32e40s_pma_assert.sv index a7a1afde4e..3a5c735087 100644 --- a/cv32e40s/tb/uvmt/uvmt_cv32e40s_pma_assert.sv +++ b/cv32e40s/tb/uvmt/uvmt_cv32e40s_pma_assert.sv @@ -146,12 +146,20 @@ module uvmt_cv32e40s_pma_assert // After PMA-deny, subsequent accesses are also suppressed (vplan:"Multi-memory operation instructions") - a_failure_denies_subsequents: assert property ( - rvfi_instr_if.is_pma_instr_fault + a_failure_denies_subsequents_loads: assert property ( + rvfi_instr_if.is_pma_data_fault |-> - (rvfi_instr_if.rvfi_mem_wmask == '0) - //TODO:ERROR:silabs-robin Zcmp should be able to break this. RVFI bug. - //TODO:ERROR:silabs-robin Also reads + (rvfi_instr_if.rvfi_mem_rmask != rvfi_instr_if.rvfi_mem_rmask_intended) + || + (rvfi_instr_if.rvfi_mem_rmask == 'd 0) + ) else `uvm_error(info_tag, "accesses aftmr pma fault should be suppressed"); + + a_failure_denies_subsequents_stores: assert property ( + rvfi_instr_if.is_pma_data_fault + |-> + (rvfi_instr_if.rvfi_mem_wmask != rvfi_instr_if.rvfi_mem_wmask_intended) + || + (rvfi_instr_if.rvfi_mem_wmask == 'd 0) ) else `uvm_error(info_tag, "accesses aftmr pma fault should be suppressed"); property p_partial_pma_allow (exc_cause); @@ -174,6 +182,16 @@ module uvmt_cv32e40s_pma_assert ); + // PMA-deny on instr, no mem op (vplan: Not a vplan item. Inspo from a_failure_denies_subsequents.) + + a_failure_denies_memops: assert property ( + rvfi_instr_if.is_pma_instr_fault + |-> + (rvfi_instr_if.rvfi_mem_wmask == '0) && + (rvfi_instr_if.rvfi_mem_rmask == '0) + ) else `uvm_error(info_tag, "pma-blocked instrs shouldn't access the bus"); + + // MPU-accepted transactions must reach OBI (vplan: not a vplan item) property p_eventually_mpu2obi; diff --git a/lib/uvm_agents/uvma_rvfi/uvma_rvfi_instr_if.sv b/lib/uvm_agents/uvma_rvfi/uvma_rvfi_instr_if.sv index 1a9f80f564..1459119fd8 100644 --- a/lib/uvm_agents/uvma_rvfi/uvma_rvfi_instr_if.sv +++ b/lib/uvm_agents/uvma_rvfi/uvma_rvfi_instr_if.sv @@ -242,6 +242,9 @@ interface uvma_rvfi_instr_if_t logic is_umode; logic is_not_umode; logic is_pma_instr_fault; + logic is_pma_data_fault; + logic is_pma_load_fault; + logic is_pma_store_fault; logic is_instr_acc_fault_pmp; logic is_instr_bus_valid; logic is_pushpop; @@ -411,6 +414,28 @@ interface uvma_rvfi_instr_if_t is_pma_instr_fault = is_pma_instr_fault_f(); end + always_comb begin + is_pma_data_fault = is_pma_load_fault || is_pma_store_fault; + end + + always_comb begin + is_pma_load_fault = + rvfi_valid && + rvfi_trap.trap && + rvfi_trap.exception && + (rvfi_trap.exception_cause == EXC_CAUSE_LOAD_ACC_FAULT) && + (rvfi_trap.cause_type == 'h 0); + end + + always_comb begin + is_pma_store_fault = + rvfi_valid && + rvfi_trap.trap && + rvfi_trap.exception && + (rvfi_trap.exception_cause == EXC_CAUSE_STORE_ACC_FAULT) && + (rvfi_trap.cause_type == 'h 0); + end + always_comb begin is_instr_bus_valid = is_instr_bus_valid_f(); end From 5c26c213393f870bdaf7bae4598f77c4290211d6 Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Sun, 17 Dec 2023 23:24:39 +0100 Subject: [PATCH 07/18] make pma 2 clic config, clock sequences, remove todos, add and remove comments Signed-off-by: Kristine Dosvik --- cv32e40s/regress/cv32e40s_full.yaml | 7 +- .../uvmt_cv32e40s_sl_trigger_match.sv | 4 +- .../uvmt/uvmt_cv32e40s_triggers_assert_cov.sv | 14 +- ..._xsecure_data_independent_timing_assert.sv | 4 +- ..._cv32e40s_xsecure_dummy_and_hint_assert.sv | 1 + ...vmt_cv32e40s_xsecure_hardened_pc_assert.sv | 1 + ...e40s_xsecure_interface_integrity_assert.sv | 1 + cv32e40s/tests/cfg/pma_test_cfg_2.yaml | 9 - cv32e40s/tests/cfg/pma_test_cfg_2_clic.yaml | 194 ++++++++++++++++++ .../custom/mhpmcounter_write_test/test.yaml | 2 +- 10 files changed, 219 insertions(+), 18 deletions(-) create mode 100644 cv32e40s/tests/cfg/pma_test_cfg_2_clic.yaml diff --git a/cv32e40s/regress/cv32e40s_full.yaml b/cv32e40s/regress/cv32e40s_full.yaml index 97184ca53b..926d0bfd51 100644 --- a/cv32e40s/regress/cv32e40s_full.yaml +++ b/cv32e40s/regress/cv32e40s_full.yaml @@ -54,6 +54,11 @@ builds: cfg: pma_test_cfg_2 dir: cv32e40s/sim/uvmt + uvmt_cv32e40s_pma_2_clic: + cmd: make comp_corev-dv comp + cfg: pma_test_cfg_2_clic + dir: cv32e40s/sim/uvmt + uvmt_cv32e40s_pma_3: cmd: make comp_corev-dv comp cfg: pma_test_cfg_3 @@ -585,7 +590,7 @@ tests: minhv_pma_block: description: test minhv=1 and pma block of mepc address - builds: [ uvmt_cv32e40s_pma_2 ] + builds: [ uvmt_cv32e40s_pma_2_clic ] dir: cv32e40s/sim/uvmt cmd: make test TEST=minhv_pma_block diff --git a/cv32e40s/tb/uvmt/support_logic/uvmt_cv32e40s_sl_trigger_match.sv b/cv32e40s/tb/uvmt/support_logic/uvmt_cv32e40s_sl_trigger_match.sv index a009b835b6..5dc8c19047 100644 --- a/cv32e40s/tb/uvmt/support_logic/uvmt_cv32e40s_sl_trigger_match.sv +++ b/cv32e40s/tb/uvmt/support_logic/uvmt_cv32e40s_sl_trigger_match.sv @@ -76,11 +76,11 @@ module uvmt_cv32e40s_sl_trigger_match (rvfi.is_umode && in_support_if.tdata1_array[t][TDATA1_ET_U_MODE])); - // Trigger match instruction: + // Trigger match instruction: assign trigger_match_execute[t] = csr_conditions_m2_m6[t] && in_support_if.tdata1_array[t][TDATA1_EXECUTE] && system_conditions - && !rvfi.rvfi_trap.clicptr //TODO: KD: burde finne ut hvorfor clicptr er et unntak. + && !rvfi.rvfi_trap.clicptr && (((rvfi.rvfi_pc_rdata == in_support_if.tdata2_array[t]) && in_support_if.tdata1_array[t][TDATA1_MSB_MATCH:TDATA1_LSB_MATCH] == TDATA1_MATCH_WHEN_EQUAL) || ((rvfi.rvfi_pc_rdata >= in_support_if.tdata2_array[t]) && in_support_if.tdata1_array[t][TDATA1_MSB_MATCH:TDATA1_LSB_MATCH] == TDATA1_MATCH_WHEN_GREATER_OR_EQUAL) || ((rvfi.rvfi_pc_rdata < in_support_if.tdata2_array[t]) && in_support_if.tdata1_array[t][TDATA1_MSB_MATCH:TDATA1_LSB_MATCH] == TDATA1_MATCH_WHEN_LESSER)); diff --git a/cv32e40s/tb/uvmt/uvmt_cv32e40s_triggers_assert_cov.sv b/cv32e40s/tb/uvmt/uvmt_cv32e40s_triggers_assert_cov.sv index dc4774fa84..e60d952cae 100644 --- a/cv32e40s/tb/uvmt/uvmt_cv32e40s_triggers_assert_cov.sv +++ b/cv32e40s/tb/uvmt/uvmt_cv32e40s_triggers_assert_cov.sv @@ -202,28 +202,33 @@ module uvmt_cv32e40s_triggers_assert_cov /////////// Sequences /////////// sequence seq_csr_read_mmode(csr_addr); + @(posedge clknrst_if.clk) valid_instr_in_mmode && rvfi_if.is_csr_read(csr_addr) && rvfi_if.rvfi_rd1_addr != 0; endsequence sequence seq_csr_write_mmode(csr_addr); + @(posedge clknrst_if.clk) valid_instr_in_mmode && rvfi_if.is_csr_write(csr_addr); endsequence sequence seq_csr_read_dmode(csr_addr); + @(posedge clknrst_if.clk) valid_instr_in_dmode && rvfi_if.is_csr_read(csr_addr) && rvfi_if.rvfi_rd1_addr != 0; endsequence sequence seq_csr_write_dmode(csr_addr); + @(posedge clknrst_if.clk) valid_instr_in_dmode && rvfi_if.is_csr_write(csr_addr); endsequence sequence seq_tdata1_m2_m6_or_disabled(t); + @(posedge clknrst_if.clk) valid_instr_in_dmode && tselect_pre_state == t && (tdata1_pre_state[MSB_TYPE:LSB_TYPE] == TTYPE_MCONTROL @@ -232,6 +237,7 @@ module uvmt_cv32e40s_triggers_assert_cov endsequence sequence seq_etrigger_hit(t, priv_lvl, exception); + @(posedge clknrst_if.clk) support_if.trigger_match_exception[t] && !rvfi_if.rvfi_dbg_mode && priv_lvl @@ -309,7 +315,7 @@ module uvmt_cv32e40s_triggers_assert_cov /////////// Assertions and Coverages /////////// - //Verify that it isonly possible to do 13 Memory transactions: + //Verify that it is only possible to do 13 Memory transactions: //TODO XIF: this might not be the case for xif, as it can potentionally do more: a_dt_max_memory_transaction: assert property ( @@ -453,9 +459,9 @@ module uvmt_cv32e40s_triggers_assert_cov //4) a_dt_tselect_higher_than_dbg_num_triggers: assert property( - rvfi_if.is_csr_instr(ADDR_TSELECT) + rvfi_if.rvfi_valid |-> - rvfi_if.rvfi_rd1_wdata < CORE_PARAM_DBG_NUM_TRIGGERS + tselect_post_state < CORE_PARAM_DBG_NUM_TRIGGERS ) else `uvm_error(info_tag, "The CSR tselect is set to equal or higher than the number of trigger.\n"); @@ -946,6 +952,7 @@ module uvmt_cv32e40s_triggers_assert_cov && rvfi_if.rvfi_dbg_mode && dcsr_if.rvfi_csr_wmask |-> + //If DCSR is written (wmask != 0) there must have been a csr write operation, and not due to a sideeffect of a trigger match rvfi_if.is_csr_write(ADDR_DCSR) ) else `uvm_error(info_tag, "Action is taken when there is a trigger match while in debug mode (dcsr is changed even though we dont do a dcsr write operation).\n"); @@ -954,6 +961,7 @@ module uvmt_cv32e40s_triggers_assert_cov && rvfi_if.rvfi_dbg_mode && dpc_if.rvfi_csr_wmask |-> + //If DPC is written (wmask != 0) there must have been a csr write operation, and not due to a sideeffect of a trigger match rvfi_if.is_csr_write(ADDR_DPC) ) else `uvm_error(info_tag, "Action is taken when there is a trigger match while in debug mode (dpc is changed even though we dont do a dpc write operation).\n"); diff --git a/cv32e40s/tb/uvmt/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_data_independent_timing_assert.sv b/cv32e40s/tb/uvmt/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_data_independent_timing_assert.sv index 37bfb46bd6..a52d66e68d 100644 --- a/cv32e40s/tb/uvmt/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_data_independent_timing_assert.sv +++ b/cv32e40s/tb/uvmt/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_data_independent_timing_assert.sv @@ -76,7 +76,7 @@ module uvmt_cv32e40s_xsecure_data_independent_timing_assert //There is therefor only 1 empty cycle after a branch instruction. sequence seq_no_mem_instr_for_cycles(x); - (!rvfi_if.is_mem_act)[*x]; + @(posedge clk_i) (!rvfi_if.is_mem_act)[*x]; endsequence a_xsecure_dataindtiming_branch_timing_pc_hardening_disabled: assert property ( @@ -114,7 +114,7 @@ module uvmt_cv32e40s_xsecure_data_independent_timing_assert //Verify that execution of division or (division)-remainder have non-varying timing when the data independent timing feature is enabled sequence seq_no_rvalid_for_past_34_cycles; - (!rvfi_if.rvfi_valid[*34] ##1 1); + @(posedge clk_i) (!rvfi_if.rvfi_valid[*34] ##1 1); endsequence a_xsecure_dataindtiming_div_rem_timing: assert property ( diff --git a/cv32e40s/tb/uvmt/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_dummy_and_hint_assert.sv b/cv32e40s/tb/uvmt/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_dummy_and_hint_assert.sv index a7097cbb04..e8f73c2c58 100644 --- a/cv32e40s/tb/uvmt/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_dummy_and_hint_assert.sv +++ b/cv32e40s/tb/uvmt/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_dummy_and_hint_assert.sv @@ -702,6 +702,7 @@ module uvmt_cv32e40s_xsecure_dummy_and_hint_assert //Verify that the LFSR's seeds are reset when lockups are detected sequence seq_xsecure_dummy_hint_instr_LFSRx_lockup_detection(logic get_new_lfsr_value, logic seed_we, logic [31:0] seed_w_value, logic [31:0] lfsr_n); + @(posedge clk_i) (rnddummy_enabled || rndhint_enabled) && get_new_lfsr_value diff --git a/cv32e40s/tb/uvmt/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_hardened_pc_assert.sv b/cv32e40s/tb/uvmt/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_hardened_pc_assert.sv index fdd75c571d..f7aaad17de 100644 --- a/cv32e40s/tb/uvmt/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_hardened_pc_assert.sv +++ b/cv32e40s/tb/uvmt/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_hardened_pc_assert.sv @@ -195,6 +195,7 @@ module uvmt_cv32e40s_xsecure_hardened_pc_assert //Verify that the major alert is set due to pc hardening fault when the PC target of a jump instruction or a branch decision is unstable, and the PC hardening feature is enabled sequence seq_non_hardened_jump(kill, halt, instr, first_op, jump_addr); + @(posedge clk_i) (!kill && !halt) throughout diff --git a/cv32e40s/tb/uvmt/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_interface_integrity_assert.sv b/cv32e40s/tb/uvmt/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_interface_integrity_assert.sv index 54b685ea37..a0a5930bf8 100644 --- a/cv32e40s/tb/uvmt/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_interface_integrity_assert.sv +++ b/cv32e40s/tb/uvmt/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_interface_integrity_assert.sv @@ -369,6 +369,7 @@ module uvmt_cv32e40s_xsecure_interface_integrity_assert //But only if integrity checking is enabled sequence seq_checksum_fault(rvalid, req_had_integrity, memory_op, rchk_input, rchk_calculated); + @(posedge clk_i) rvalid && req_had_integrity && memory_op diff --git a/cv32e40s/tests/cfg/pma_test_cfg_2.yaml b/cv32e40s/tests/cfg/pma_test_cfg_2.yaml index 5c2b0e7a7f..0edf69a0db 100644 --- a/cv32e40s/tests/cfg/pma_test_cfg_2.yaml +++ b/cv32e40s/tests/cfg/pma_test_cfg_2.yaml @@ -2,10 +2,8 @@ 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_clic=1 +enable_pma=1 +enable_zca_extension=1 +enable_zcb_extension=1 @@ -18,13 +16,6 @@ plusargs: > +enable_zbc_extension=1 +enable_zbs_extension=1 ovpsim: > - --override cpu/CLICLEVELS=256 - --override cpu/CLICXCSW=T - --override cpu/CLICXNXTI=T - --override cpu/CLICSELHVEC=T - --override cpu/CLICINTCTLBITS=8 - --override cpu/CLIC_version=master - --override cpu/externalCLIC=T --override cpu/PMP_registers=64 --override cpu/PMP_undefined=T --override cpu/PMP_initialparams=T diff --git a/cv32e40s/tests/cfg/pma_test_cfg_2_clic.yaml b/cv32e40s/tests/cfg/pma_test_cfg_2_clic.yaml new file mode 100644 index 0000000000..5c2b0e7a7f --- /dev/null +++ b/cv32e40s/tests/cfg/pma_test_cfg_2_clic.yaml @@ -0,0 +1,194 @@ +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_clic=1 + +enable_pma=1 + +enable_zca_extension=1 + +enable_zcb_extension=1 + +enable_zcmt_extension=1 + +enable_zcmp_extension=1 + +fix_ra=1 + +fix_sp=1 + +enable_zba_extension=1 + +enable_zbb_extension=1 + +enable_zbc_extension=1 + +enable_zbs_extension=1 +ovpsim: > + --override cpu/CLICLEVELS=256 + --override cpu/CLICXCSW=T + --override cpu/CLICXNXTI=T + --override cpu/CLICSELHVEC=T + --override cpu/CLICINTCTLBITS=8 + --override cpu/CLIC_version=master + --override cpu/externalCLIC=T + --override cpu/PMP_registers=64 + --override cpu/PMP_undefined=T + --override cpu/PMP_initialparams=T + --override cpu/PMP_maskparams=T + --override cpu/pmpaddr0=0 + --override cpu/pmpaddr1=0 + --override cpu/pmpaddr2=0 + --override cpu/pmpaddr3=0 + --override cpu/pmpaddr4=0 + --override cpu/pmpaddr5=0 + --override cpu/pmpaddr6=0 + --override cpu/pmpaddr7=0 + --override cpu/pmpaddr8=0 + --override cpu/pmpaddr9=0 + --override cpu/pmpaddr10=0 + --override cpu/pmpaddr11=0 + --override cpu/pmpaddr12=0 + --override cpu/pmpaddr13=0 + --override cpu/pmpaddr14=0 + --override cpu/pmpaddr15=0 + --override cpu/pmpaddr16=0 + --override cpu/pmpaddr17=0 + --override cpu/pmpaddr18=0 + --override cpu/pmpaddr19=0 + --override cpu/pmpaddr20=0 + --override cpu/pmpaddr21=0 + --override cpu/pmpaddr22=0 + --override cpu/pmpaddr23=0 + --override cpu/pmpaddr24=0 + --override cpu/pmpaddr25=0 + --override cpu/pmpaddr26=0 + --override cpu/pmpaddr27=0 + --override cpu/pmpaddr28=0 + --override cpu/pmpaddr29=0 + --override cpu/pmpaddr30=0 + --override cpu/pmpaddr31=0 + --override cpu/pmpaddr32=0 + --override cpu/pmpaddr33=0 + --override cpu/pmpaddr34=0 + --override cpu/pmpaddr35=0 + --override cpu/pmpaddr36=0 + --override cpu/pmpaddr37=0 + --override cpu/pmpaddr38=0 + --override cpu/pmpaddr39=0 + --override cpu/pmpaddr40=0 + --override cpu/pmpaddr41=0 + --override cpu/pmpaddr42=0 + --override cpu/pmpaddr43=0 + --override cpu/pmpaddr44=0 + --override cpu/pmpaddr45=0 + --override cpu/pmpaddr46=0 + --override cpu/pmpaddr47=0 + --override cpu/pmpaddr48=0 + --override cpu/pmpaddr49=0 + --override cpu/pmpaddr50=0 + --override cpu/pmpaddr51=0 + --override cpu/pmpaddr52=0 + --override cpu/pmpaddr53=0 + --override cpu/pmpaddr54=0 + --override cpu/pmpaddr55=0 + --override cpu/pmpaddr56=0 + --override cpu/pmpaddr57=0 + --override cpu/pmpaddr58=0 + --override cpu/pmpaddr59=0 + --override cpu/pmpaddr60=0 + --override cpu/pmpaddr61=0 + --override cpu/pmpaddr62=0 + --override cpu/pmpaddr63=0 + --override cpu/pmpcfg0=0 + --override cpu/pmpcfg1=0 + --override cpu/pmpcfg2=0 + --override cpu/pmpcfg3=0 + --override cpu/pmpcfg4=0 + --override cpu/pmpcfg5=0 + --override cpu/pmpcfg6=0 + --override cpu/pmpcfg7=0 + --override cpu/pmpcfg8=0 + --override cpu/pmpcfg9=0 + --override cpu/pmpcfg10=0 + --override cpu/pmpcfg11=0 + --override cpu/pmpcfg12=0 + --override cpu/pmpcfg13=0 + --override cpu/pmpcfg14=0 + --override cpu/pmpcfg15=0 + --override cpu/mask_pmpaddr0=0x00000000 + --override cpu/mask_pmpaddr1=0x00000000 + --override cpu/mask_pmpaddr2=0x00000000 + --override cpu/mask_pmpaddr3=0x00000000 + --override cpu/mask_pmpaddr4=0x00000000 + --override cpu/mask_pmpaddr5=0x00000000 + --override cpu/mask_pmpaddr6=0x00000000 + --override cpu/mask_pmpaddr7=0x00000000 + --override cpu/mask_pmpaddr8=0x00000000 + --override cpu/mask_pmpaddr9=0x00000000 + --override cpu/mask_pmpaddr10=0x00000000 + --override cpu/mask_pmpaddr11=0x00000000 + --override cpu/mask_pmpaddr12=0x00000000 + --override cpu/mask_pmpaddr13=0x00000000 + --override cpu/mask_pmpaddr14=0x00000000 + --override cpu/mask_pmpaddr15=0x00000000 + --override cpu/mask_pmpaddr16=0x00000000 + --override cpu/mask_pmpaddr17=0x00000000 + --override cpu/mask_pmpaddr18=0x00000000 + --override cpu/mask_pmpaddr19=0x00000000 + --override cpu/mask_pmpaddr20=0x00000000 + --override cpu/mask_pmpaddr21=0x00000000 + --override cpu/mask_pmpaddr22=0x00000000 + --override cpu/mask_pmpaddr23=0x00000000 + --override cpu/mask_pmpaddr24=0x00000000 + --override cpu/mask_pmpaddr25=0x00000000 + --override cpu/mask_pmpaddr26=0x00000000 + --override cpu/mask_pmpaddr27=0x00000000 + --override cpu/mask_pmpaddr28=0x00000000 + --override cpu/mask_pmpaddr29=0x00000000 + --override cpu/mask_pmpaddr30=0x00000000 + --override cpu/mask_pmpaddr31=0x00000000 + --override cpu/mask_pmpaddr32=0x00000000 + --override cpu/mask_pmpaddr33=0x00000000 + --override cpu/mask_pmpaddr34=0x00000000 + --override cpu/mask_pmpaddr35=0x00000000 + --override cpu/mask_pmpaddr36=0x00000000 + --override cpu/mask_pmpaddr37=0x00000000 + --override cpu/mask_pmpaddr38=0x00000000 + --override cpu/mask_pmpaddr39=0x00000000 + --override cpu/mask_pmpaddr40=0x00000000 + --override cpu/mask_pmpaddr41=0x00000000 + --override cpu/mask_pmpaddr42=0x00000000 + --override cpu/mask_pmpaddr43=0x00000000 + --override cpu/mask_pmpaddr44=0x00000000 + --override cpu/mask_pmpaddr45=0x00000000 + --override cpu/mask_pmpaddr46=0x00000000 + --override cpu/mask_pmpaddr47=0x00000000 + --override cpu/mask_pmpaddr48=0x00000000 + --override cpu/mask_pmpaddr49=0x00000000 + --override cpu/mask_pmpaddr50=0x00000000 + --override cpu/mask_pmpaddr51=0x00000000 + --override cpu/mask_pmpaddr52=0x00000000 + --override cpu/mask_pmpaddr53=0x00000000 + --override cpu/mask_pmpaddr54=0x00000000 + --override cpu/mask_pmpaddr55=0x00000000 + --override cpu/mask_pmpaddr56=0x00000000 + --override cpu/mask_pmpaddr57=0x00000000 + --override cpu/mask_pmpaddr58=0x00000000 + --override cpu/mask_pmpaddr59=0x00000000 + --override cpu/mask_pmpaddr60=0x00000000 + --override cpu/mask_pmpaddr61=0x00000000 + --override cpu/mask_pmpaddr62=0x00000000 + --override cpu/mask_pmpaddr63=0x00000000 + --override cpu/mask_pmpcfg0=0x00000000 + --override cpu/mask_pmpcfg1=0x00000000 + --override cpu/mask_pmpcfg2=0x00000000 + --override cpu/mask_pmpcfg3=0x00000000 + --override cpu/mask_pmpcfg4=0x00000000 + --override cpu/mask_pmpcfg5=0x00000000 + --override cpu/mask_pmpcfg6=0x00000000 + --override cpu/mask_pmpcfg7=0x00000000 + --override cpu/mask_pmpcfg8=0x00000000 + --override cpu/mask_pmpcfg9=0x00000000 + --override cpu/mask_pmpcfg10=0x00000000 + --override cpu/mask_pmpcfg11=0x00000000 + --override cpu/mask_pmpcfg12=0x00000000 + --override cpu/mask_pmpcfg13=0x00000000 + --override cpu/mask_pmpcfg14=0x00000000 + --override cpu/mask_pmpcfg15=0x00000000 +cflags: > + -Wl,--nmagic +cv_sw_march: rv32im_zba1p00_zbb1p00_zbc1p00_zbs1p00_zicsr_zca_zcb_zcmp_zcmt_zifencei diff --git a/cv32e40s/tests/programs/custom/mhpmcounter_write_test/test.yaml b/cv32e40s/tests/programs/custom/mhpmcounter_write_test/test.yaml index 9f061158d5..3e6c6ed99b 100644 --- a/cv32e40s/tests/programs/custom/mhpmcounter_write_test/test.yaml +++ b/cv32e40s/tests/programs/custom/mhpmcounter_write_test/test.yaml @@ -1,4 +1,4 @@ name: mhpmcounter_write_test uvm_test: uvmt_$(CV_CORE_LC)_firmware_test_c description: > - Write to mhpmcounters. Is only verifyed by ISS, should be verifyed that we get excpected behaviour? + Write to the mhpmcounters. From 6edd34da8baa165d6186ec214582a89d7c23d5a9 Mon Sep 17 00:00:00 2001 From: Henrik Fegran Date: Tue, 19 Dec 2023 13:28:40 +0100 Subject: [PATCH 08/18] Removed iss misa check disable code Signed-off-by: Henrik Fegran --- cv32e40s/env/uvme/uvme_cv32e40s_cfg.sv | 3 --- 1 file changed, 3 deletions(-) diff --git a/cv32e40s/env/uvme/uvme_cv32e40s_cfg.sv b/cv32e40s/env/uvme/uvme_cv32e40s_cfg.sv index e6172209ce..954857ea80 100644 --- a/cv32e40s/env/uvme/uvme_cv32e40s_cfg.sv +++ b/cv32e40s/env/uvme/uvme_cv32e40s_cfg.sv @@ -562,9 +562,6 @@ endfunction : is_csr_check_disabled function void uvme_cv32e40s_cfg_c::configure_disable_csr_checks(); - // TODO: remove when fixed in ISS - disable_csr_check("misa"); - // Need to check disable_csr_check("mcountinhibit"); From 32b8cb74be692b661bc77191b4a7fc6f2a2e33e5 Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Fri, 12 Jan 2024 08:20:52 +0100 Subject: [PATCH 09/18] added mepc minhv misalignement test Signed-off-by: Kristine Dosvik --- .../Simulation/interrupts/CV32E40SX_CLIC.csv | 2 + .../Simulation/interrupts/CV32E40SX_CLIC.json | 11 +++ .../Simulation/interrupts/CV32E40SX_CLIC.xlsx | Bin 38973 -> 39368 bytes cv32e40s/tests/programs/custom/clic/clic.c | 88 +++++++++++++++++- 4 files changed, 100 insertions(+), 1 deletion(-) diff --git a/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.csv b/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.csv index 5c9e6559a6..9d66f21808 100644 --- a/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.csv +++ b/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.csv @@ -305,6 +305,8 @@ Added assertion for formal coverage",Assertion Check,"ENV capability, not specif [clic_assert].a_mret_mie_mpie" CLIC 0.9-draft 4/11/2023,Return from handler,mret,"""If the hart is currently running at some privilege mode x, an MRET or SRET instruction that changes the privilege mode to a mode less privileged than x also sets xintthresh = 0.""","Use ""mret"" to enter U-mode. Check that ""mintthresh"" is written to zero upon executing the mret.",Assertion Check,"ENV capability, not specific test",Assertion Coverage,A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.clic_assert_i.gen_clic_assertions.a_mret_umode_clear_mintthresh +CLIC 0.9-draft 12/19/2023,Return from handler,mret minhv=1,"""If the xinhv bit is set, the hart resumes the trap handler memory access to retrieve the function pointer for vectoring with permissions corresponding to the previous privilege mode. The trap handler function address is obtained from the current privilege mode’s xepc with the low bits of the address cleared to force the access to be naturally aligned to an XLEN/8-byte table entry.""","Run mret when minhv is set. Check that the next instruction to be executed is the address pointed to by the mepc, and check that mepc gets naturally aligned to XLEN/8 byte.",Self Checking Test,Directed Self-Checking,Testcase,"DTC: clic :: mret_with_minhv +clic ::mret_with_minhv_and_unaligned_mepc" CLIC 0.9-draft 4/11/2023,Return from debug mode,dret,"""Likewise, if the RISC-V debug specification is implemented and the hart is currently running at some privilege mode x, a DRET instruction that changes the privilege mode to a mode less privileged than x also sets xintthresh = 0.""","Use ""dret"" to enter U-mode. Check that ""mintthresh"" is written to zero upon executing the dret.",Assertion Check,"ENV capability, not specific test",Assertion Coverage,Requirement removed CLIC 8675ec,WFI,Wakeup conditions,"A pending-and-enabled interrupt i causes the hart to resume execution if interrupt i diff --git a/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.json b/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.json index ed0491458a..2a1dc8b2e2 100644 --- a/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.json +++ b/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.json @@ -791,6 +791,17 @@ "Coverage Method": "Assertion Coverage", "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.clic_assert_i.gen_clic_assertions.a_mret_umode_clear_mintthresh" }, + { + "Requirement Location": "CLIC 0.9-draft 12/19/2023", + "Feature": "Return from handler", + "Sub Feature": "mret minhv=1", + "Feature Description": "\"If the xinhv bit is set, the hart resumes the trap handler memory access to retrieve the function pointer for vectoring with permissions corresponding to the previous privilege mode. The trap handler function address is obtained from the current privilege mode\u2019s xepc with the low bits of the address cleared to force the access to be naturally aligned to an XLEN/8-byte table entry.\"", + "Verification Goal": "Run mret when minhv is set. Check that the next instruction to be executed is the address pointed to by the mepc, and check that mepc gets naturally aligned to XLEN/8 byte.", + "Pass/Fail Criteria": "Self Checking Test", + "Test Type": "Directed Self-Checking", + "Coverage Method": "Testcase", + "Link to Coverage": "DTC: clic :: mret_with_minhv\nclic ::mret_with_minhv_and_unaligned_mepc" + }, { "Requirement Location": "CLIC 0.9-draft 4/11/2023", "Feature": "Return from debug mode", diff --git a/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.xlsx b/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.xlsx index 9af84b66045a780ba6fbe47cbbc0a8d4896cd9b4..433283b78d26ec29fe7d87b5bdab8e4699295ed1 100644 GIT binary patch delta 23809 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 diff --git a/cv32e40s/tests/programs/custom/clic/clic.c b/cv32e40s/tests/programs/custom/clic/clic.c index 2a8e908972..e3db475f68 100644 --- a/cv32e40s/tests/programs/custom/clic/clic.c +++ b/cv32e40s/tests/programs/custom/clic/clic.c @@ -35,7 +35,7 @@ // MUST be 31 or less (bit position-1 in result array determines test pass/fail // status, thus we are limited to 31 tests with this construct. -#define NUM_TESTS 24 +#define NUM_TESTS 25 // Set which test index to start testing at (for quickly running specific tests during development) #define START_TEST_IDX 0 // Abort test at first self-check fail, useful for debugging. @@ -220,6 +220,8 @@ volatile uint32_t * volatile g_asserted_irq_lvl; volatile uint32_t * volatile g_irq_handler_reported_error; volatile uint32_t * volatile g_mepc_triggered; volatile uint32_t * volatile g_recovery_enable; +volatile uint32_t * volatile g_checker; + // --------------------------------------------------------------- // Test prototypes - should match // uint32_t (uint32_t index, uint8_t report_name) @@ -250,6 +252,7 @@ uint32_t mret_with_minhv(uint32_t index, uint8_t report_name); uint32_t mintthresh_higher(uint32_t index, uint8_t report_name); uint32_t mintthresh_lower(uint32_t index, uint8_t report_name); uint32_t mintthresh_equal(uint32_t index, uint8_t report_name); +uint32_t mret_with_minhv_and_unaligned_mepc(uint32_t index, uint8_t report_name); // --------------------------------------------------------------- // Generic test template: @@ -377,6 +380,7 @@ int main(int argc, char **argv){ g_irq_handler_reported_error = calloc(1, sizeof(uint32_t)); g_mepc_triggered = calloc(1, sizeof(uint32_t)); g_recovery_enable = calloc(1, sizeof(uint32_t)); + g_checker = calloc(1, sizeof(uint32_t)); // Add function pointers to new tests here tests[0] = mcause_mstatus_mirror_init; @@ -403,6 +407,7 @@ int main(int argc, char **argv){ tests[21] = mintthresh_lower; tests[22] = mintthresh_higher; tests[23] = mintthresh_equal; + tests[24] = mret_with_minhv_and_unaligned_mepc; // Run all tests in list above cvprintf(V_LOW, "\nCLIC Test start\n\n"); @@ -420,6 +425,7 @@ int main(int argc, char **argv){ free((void *)g_irq_handler_reported_error); free((void *)g_mepc_triggered ); free((void *)g_recovery_enable ); + free((void *)g_checker ); return retval; // Nonzero for failing tests } @@ -3052,6 +3058,7 @@ uint32_t mret_with_minhv(uint32_t index, uint8_t report_name) { mret addi %[check_val], zero, 42 jal zero, 2f + .align 4 1: .word(2f) .space 0x100, 0x0 2: addi %[result], %[check_val], 0 @@ -3326,6 +3333,75 @@ uint32_t mintthresh_equal(uint32_t index, uint8_t report_name) { return 0; } +// This function should cover corner cases encountered by broken code during +// test development that made the ISS and RTL deviate. After resolving issues, +// leave this function in place to ensure that these issues do not return. +uint32_t mret_with_minhv_and_unaligned_mepc(uint32_t index, uint8_t report_name) { + volatile uint8_t test_fail = 0; + volatile mcause_t mcause = { 0 }; + volatile uint32_t result = 0; + volatile uint32_t all_set = 0xFFFFFFFF; + + SET_FUNC_INFO + if (report_name) { + cvprintf(V_LOW, "\"%s\"", name); + return 0; + } + + *g_special_handler_idx = 7; + + __asm__ volatile ( R"( + csrrs %[rd1], mcause, zero + )":[rd1] "=r"(mcause.raw) + ::); + + mcause.clic.minhv = 1; + mcause.clic.mpp = 0x3; + mcause.clic.mpie = 0; + + *g_checker = 0; + + __asm__ volatile (R"( + csrrw zero, mcause, %[mcause] + la t0, 1f + lw t1, (t0) + csrrw zero, mepc, t0 + # Store instruction mepc aims to execute in mscratch register. + csrrw zero, mscratch, t1 + mret + + # Write 0xFFFF_FFFF to where g_checker points. + lw t2, g_checker + sw %[all_set], 0(t2) + + jal zero, 2f + .align 4 + .byte(0xFF) + .byte(0xFF) + 1: .word(2f) + .space 0x100, 0x0 + + 2: + # Fetch the value g_checker points to. + lw t2, g_checker + lw t2, 0(t2) + + addi %[result], t2, 0 + + )":[result] "=r"(result) + :[mcause] "r"(mcause.raw), [all_set] "r"(all_set) + :"t0", "t1", "t2"); + + test_fail += (result != 0); + + if (test_fail) { + cvprintf(V_LOW, "\nTest: \"%s\" FAIL!\n", name); + return index + 1; + } + cvprintf(V_MEDIUM, "\nTest: \"%s\" OK!\n", name); + return 0; +} + // ----------------------------------------------------------------------------- // Note that the following interrupt/exception handler is not generic and specific // to this test. @@ -3408,6 +3484,16 @@ __attribute__((interrupt("machine"))) void u_sw_irq_handler(void) { case 6: *g_irq_handler_reported_error = 1; vp_assert_irq(0, 0); + *g_special_handler_idx = 0; + return; + break; + case 7: + *g_special_handler_idx = 0; + //Write mscratch value to mepc + __asm__ volatile ( R"( + csrrw t0, mscratch, zero + csrrw zero, mepc, t0 + )"::: "t0"); return; break; } From abc843bc4bc88f917bf559574a92eb93e53901ae Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Fri, 12 Jan 2024 08:25:31 +0100 Subject: [PATCH 10/18] remove unnecessary comment Signed-off-by: Kristine Dosvik --- cv32e40s/tests/programs/custom/clic/clic.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cv32e40s/tests/programs/custom/clic/clic.c b/cv32e40s/tests/programs/custom/clic/clic.c index e3db475f68..3873b4c864 100644 --- a/cv32e40s/tests/programs/custom/clic/clic.c +++ b/cv32e40s/tests/programs/custom/clic/clic.c @@ -3333,9 +3333,7 @@ uint32_t mintthresh_equal(uint32_t index, uint8_t report_name) { return 0; } -// This function should cover corner cases encountered by broken code during -// test development that made the ISS and RTL deviate. After resolving issues, -// leave this function in place to ensure that these issues do not return. + uint32_t mret_with_minhv_and_unaligned_mepc(uint32_t index, uint8_t report_name) { volatile uint8_t test_fail = 0; volatile mcause_t mcause = { 0 }; From 4feff72978e3df1764ea71ab3753c2087e5e6480 Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Fri, 12 Jan 2024 10:32:45 +0100 Subject: [PATCH 11/18] Correct indent Signed-off-by: Kristine Dosvik --- cv32e40s/tests/programs/custom/clic/clic.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cv32e40s/tests/programs/custom/clic/clic.c b/cv32e40s/tests/programs/custom/clic/clic.c index 3873b4c864..3659b23e86 100644 --- a/cv32e40s/tests/programs/custom/clic/clic.c +++ b/cv32e40s/tests/programs/custom/clic/clic.c @@ -3486,14 +3486,14 @@ __attribute__((interrupt("machine"))) void u_sw_irq_handler(void) { return; break; case 7: - *g_special_handler_idx = 0; - //Write mscratch value to mepc - __asm__ volatile ( R"( - csrrw t0, mscratch, zero - csrrw zero, mepc, t0 - )"::: "t0"); - return; - break; + *g_special_handler_idx = 0; + //Write mscratch value to mepc + __asm__ volatile ( R"( + csrrw t0, mscratch, zero + csrrw zero, mepc, t0 + )"::: "t0"); + return; + break; } if (mcause.clic.interrupt == 0 && mcause.clic.exccode == 2) { From 4a672547e8cd735a05ca417cbdae751887adbaca Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Fri, 12 Jan 2024 10:38:09 +0100 Subject: [PATCH 12/18] correct indent again Signed-off-by: Kristine Dosvik --- cv32e40s/tests/programs/custom/clic/clic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cv32e40s/tests/programs/custom/clic/clic.c b/cv32e40s/tests/programs/custom/clic/clic.c index 3659b23e86..543dccf2cf 100644 --- a/cv32e40s/tests/programs/custom/clic/clic.c +++ b/cv32e40s/tests/programs/custom/clic/clic.c @@ -3492,8 +3492,8 @@ __attribute__((interrupt("machine"))) void u_sw_irq_handler(void) { csrrw t0, mscratch, zero csrrw zero, mepc, t0 )"::: "t0"); - return; - break; + return; + break; } if (mcause.clic.interrupt == 0 && mcause.clic.exccode == 2) { From cfb00abfe2548daab101fcdf28c874a67e333e0c Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Mon, 15 Jan 2024 13:15:15 +0100 Subject: [PATCH 13/18] address issue 2134:add check if merge is up to date, better branch names, add checks for operations. And remove unused option Signed-off-by: Kristine Dosvik --- bin/merge.sh | 145 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 116 insertions(+), 29 deletions(-) diff --git a/bin/merge.sh b/bin/merge.sh index 79e046e36e..7a7cc44c32 100755 --- a/bin/merge.sh +++ b/bin/merge.sh @@ -19,18 +19,14 @@ # limitations under the License. -#TODO: -#List up the PRs these changes are from (so it is easy to see what to include in the cv32e40s/dev to cv32e40x/dev merge) - #Variables: date_time=$(date +%Y.%m.%d-%H.%M) usage() { - echo "usage: $0 --[s_into_x-dv|x-dv_into_s|sdev_into_xdev|xdev_into_sdev]" + echo "usage: $0 --[s_into_x-dv|sdev_into_xdev|xdev_into_sdev|rejection-diff]" echo "--s_into_x-dv Do a merge of core-v-verif cv32e40s/dev cv32e40s directory into cv32e40x-dv main (make sure the clonetb script has run)" - echo "--x-dv_into_s Do a merge of cv32e40x-dv main into core-v-verif cv32e40s/dev cv32e40s (not yet developed)" echo "--sdev_into_xdev Do a merge of core-v-verif cv32e40s/dev into core-v-verif cv32e40x/dev" echo "--xdev_into_sdev Do a merge of core-v-verif cv32e40x/dev into core-v-verif cv32e40s/dev" echo "--rejection-diff Merge s/dev to x-dv, using 'theirs'" @@ -63,11 +59,13 @@ merge_cv32e40s_into_cv32e40x-dv () { git checkout -b cvv_$date_time ohw_cvv/cv32e40s/dev git subtree split --prefix cv32e40s -b cv32e40s_$date_time + echo "=== Make a branch based on the latest cv32e40x-dv content ===" git remote add ohw_x-dv git@github.com:openhwgroup/cv32e40x-dv.git git fetch ohw_x-dv git checkout -b merge_cv32e40s_$date_time ohw_x-dv/main + echo "=== Merge ===" git merge -X find-renames --no-ff --no-commit cv32e40s_$date_time @@ -76,28 +74,45 @@ merge_cv32e40s_into_cv32e40x-dv () { move_files_40s_into_40x () { - echo "=== Replace 40s/S with 40x/X in file names ===" + echo "======= Replace 40s/S with 40x/X in file names? (recommended) =======" + read -p "(default: y, n)?" yn + + case $yn in + [Nn]) + echo "=== Skip file renaming ==="; + return + ;; - find . -type d | egrep -iv '\/\.|40sx|40xs' | grep -i 40s | xargs -n1 dirname | awk '{gsub(/40s/, "40x"); gsub(/40S/, "40X"); print}' | xargs -n2 mkdir -p - find . -type d | egrep -iv '\/\.|40sx|40xs' | grep -i 40s | awk '{printf $1; printf " "; gsub(/40s/, "40x"); gsub(/40S/, "40X"); print}' | xargs -n2 git mv -f - find . -type f | egrep -iv '\/\.|40sx|40xs' | grep -i 40s | xargs -n1 dirname | awk '{gsub(/40s/, "40x"); gsub(/40S/, "40X"); print}' | xargs -n2 mkdir -p - find . -type f | egrep -iv '\/\.|40sx|40xs' | grep -i 40s | awk '{printf $1; printf " "; gsub(/40s/, "40x"); gsub(/40S/, "40X"); print}' | xargs -n2 git mv -f + *) + echo "=== Rename files ===" + find . -type d | egrep -iv '\/\.|40sx|40xs' | grep -i 40s | xargs -n1 dirname | awk '{gsub(/40s/, "40x"); gsub(/40S/, "40X"); print}' | xargs -n2 mkdir -p + find . -type d | egrep -iv '\/\.|40sx|40xs' | grep -i 40s | awk '{printf $1; printf " "; gsub(/40s/, "40x"); gsub(/40S/, "40X"); print}' | xargs -n2 git mv -f + find . -type f | egrep -iv '\/\.|40sx|40xs' | grep -i 40s | xargs -n1 dirname | awk '{gsub(/40s/, "40x"); gsub(/40S/, "40X"); print}' | xargs -n2 mkdir -p + find . -type f | egrep -iv '\/\.|40sx|40xs' | grep -i 40s | awk '{printf $1; printf " "; gsub(/40s/, "40x"); gsub(/40S/, "40X"); print}' | xargs -n2 git mv -f + ;; + esac } substitute_file_content_40s_into_40x () { - echo "=== Exchange 40x/X with 40s/S in file content ===" - - read -p "Exchange 40x/X with 40s/S in file content? y/n " yn + echo "======= Exchange 40x/X with 40s/S in file content? (not recommended) =======" + read -p "(y, default: n)?" yn case $yn in - [Yy]* ) ;; - * ) echo "Skip content substitution"; return;; - esac + [Yy]) + echo "=== Content substitution ==="; - find . -type f -exec grep -Il . {} + | egrep -iv '\/\.|40sx|40xs' | xargs -n1 sed -i 's/40s/40x/g' - find . -type f -exec grep -Il . {} + | egrep -iv '\/\.|40sx|40xs' | xargs -n1 sed -i 's/40S/40X/g' + find . -type f -exec grep -Il . {} + | egrep -iv '\/\.|40sx|40xs' | xargs -n1 sed -i 's/40s/40x/g' + find . -type f -exec grep -Il . {} + | egrep -iv '\/\.|40sx|40xs' | xargs -n1 sed -i 's/40S/40X/g' + + return + ;; + + *) + echo "=== Skip content substitution ==="; + ;; + esac } @@ -113,12 +128,15 @@ merge_sdev_into_xdev () { echo "=== Make a core-v-verif/cv32e40s/dev branch ===" git checkout -b cvv_sdev_$date_time ohw_cvv/cv32e40s/dev + echo "=== Make a core-v-verif/cv32e40x/dev branch ===" - git checkout -b cvv_xdev_$date_time ohw_cvv/cv32e40x/dev + git checkout -b merge_sdev_into_xdev_$date_time ohw_cvv/cv32e40x/dev + echo "=== Merge ===" git merge --no-commit --no-ff cvv_sdev_$date_time + } @@ -133,12 +151,15 @@ merge_xdev_into_sdev () { echo "=== Make a core-v-verif/cv32e40s/dev branch ===" git checkout -b cvv_xdev_$date_time ohw_cvv/cv32e40x/dev + echo "=== Make a core-v-verif/cv32e40s/dev branch ===" - git checkout -b cvv_sdev_$date_time ohw_cvv/cv32e40s/dev + git checkout -b merge_xdev_into_sdev_$date_time ohw_cvv/cv32e40s/dev + echo "=== Merge ===" git merge --no-commit --no-ff cvv_xdev_$date_time + } @@ -146,14 +167,12 @@ clone_x_dv() { echo "=== Cloning x-dv ===" - read -p "This overwrites 'cv32e40x/'. Continue? y/n " yn - case $yn in - [Yy]* ) ;; - * ) echo "aborting"; exit;; - esac + read -p "This overwrites 'cv32e40x/'. Continue? (default: y, n) " yn + continue_check $yn ./bin/clonetb --x-main + } @@ -183,20 +202,88 @@ rejection_diff() { } +need_40s_40x-dv_merge(){ + echo -e "\n=== Check if there are new commits i cv32e40s to merge to cv32e40x-dv ===" + + missing_commits=() + nr_commits=10 + nr_commits_to_check=10 + + # Get commit shas from cv32e40s: + cv32e40s_commits_shas=$(git log --pretty=format:'%H' -$nr_commits -- cv32e40s) + for sha in $cv32e40s_commits_shas; do + commit_message=$(git show -s --format=%s%b $sha) + + # If the commit is signed off search for the commit's -m message in cv32e40x-dv + # to check if the commit is merged or not. + if [[ $commit_message =~ "Signed-off-by" ]]; then + commit_m_message=${commit_message%Signed-off-by*} + + cd cv32e40x + search_commit=$(git log -$nr_commits_to_check --grep="$commit_m_message" --format=oneline) + cd .. + + if [[ -z $search_commit ]]; then + missing_commit="$sha: $commit_message" + missing_commits+=("$missing_commit") + fi + fi + done + + # Print commits needed to be merged, + if [[ -n $missing_commits ]]; then + echo -e "\n== Commits needed to be merged: ==" + echo "There is a chance more commits need merge" + echo "The commits with similar name to another commit in cv32e40x-dv is not listed" + for ((i=0; i <= ${#missing_commits[@]} ; i++)); do + echo ${missing_commits[$i]} + done + + else + echo -e "\n== No commits needs to be merged ==" + echo "(Unless there is a commit without -m message that needs to be merged)" + fi + + # Ask to continue merge + read -p "Merge commits into cv32e40x-dv? (default: y, n) " yn + continue_check $yn -main() { +} + +get_branch_cv32e40s_dev() { + + echo -e "\n== Enter an updated cv32e40s/dev branch ==" + git remote add ohw_cvv git@github.com:openhwgroup/core-v-verif.git + git fetch ohw_cvv + git checkout ohw_cvv/cv32e40s/dev +} + +continue_check() { + case $1 in + [Nn]) + echo "Exit merge!" + exit 1 + ;; + *) + echo "Continue merge process!" + return + ;; + esac +} + + +main() { case $1 in "--s_into_x-dv") clone_x_dv + get_branch_cv32e40s_dev + need_40s_40x-dv_merge merge_cv32e40s_into_cv32e40x-dv move_files_40s_into_40x substitute_file_content_40s_into_40x check_merge_status ;; - "--x-dv_into_s") - echo "This merge method is not yet developed" - ;; "--sdev_into_xdev") merge_sdev_into_xdev check_merge_status From c731f2868bf4dd288fc226f9f5df646e35dafa06 Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Mon, 15 Jan 2024 13:32:44 +0100 Subject: [PATCH 14/18] Add warnings to commit check, change function name Signed-off-by: Kristine Dosvik --- bin/merge.sh | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/bin/merge.sh b/bin/merge.sh index 7a7cc44c32..4d75674c97 100755 --- a/bin/merge.sh +++ b/bin/merge.sh @@ -206,8 +206,8 @@ need_40s_40x-dv_merge(){ echo -e "\n=== Check if there are new commits i cv32e40s to merge to cv32e40x-dv ===" missing_commits=() - nr_commits=10 - nr_commits_to_check=10 + nr_commits=100 + nr_commits_to_check=100 # Get commit shas from cv32e40s: cv32e40s_commits_shas=$(git log --pretty=format:'%H' -$nr_commits -- cv32e40s) @@ -233,26 +233,33 @@ need_40s_40x-dv_merge(){ # Print commits needed to be merged, if [[ -n $missing_commits ]]; then echo -e "\n== Commits needed to be merged: ==" - echo "There is a chance more commits need merge" - echo "The commits with similar name to another commit in cv32e40x-dv is not listed" for ((i=0; i <= ${#missing_commits[@]} ; i++)); do echo ${missing_commits[$i]} done else echo -e "\n== No commits needs to be merged ==" - echo "(Unless there is a commit without -m message that needs to be merged)" fi + echo "== WARNING 1: ==" + echo "The script use commit message to identify merged commits" + echo "If a new commit in cv32e40s has the same commit message as a commit in cv32e40x-dv or no -m at all," + echo -e "the commit is not in the list of commits that need to be merged.\n" + + echo "== WARNING 2: ==" + echo "The script compares only the 100 latest commits in cv32e40s and cv32e40x-dv" + echo -e "If there has been a lot of activity in the reposetories, the result of the above check can be faulty.\n" + + # Ask to continue merge read -p "Merge commits into cv32e40x-dv? (default: y, n) " yn continue_check $yn } -get_branch_cv32e40s_dev() { +checkout_update_cv32e40s_dev_branch() { - echo -e "\n== Enter an updated cv32e40s/dev branch ==" + echo -e "\n== Checkout an updated cv32e40s/dev branch ==" git remote add ohw_cvv git@github.com:openhwgroup/core-v-verif.git git fetch ohw_cvv git checkout ohw_cvv/cv32e40s/dev @@ -277,7 +284,7 @@ main() { case $1 in "--s_into_x-dv") clone_x_dv - get_branch_cv32e40s_dev + checkout_update_cv32e40s_dev_branch need_40s_40x-dv_merge merge_cv32e40s_into_cv32e40x-dv move_files_40s_into_40x From b30a0ea7be1d0bec784c110e81bdbf718551e41f Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Mon, 15 Jan 2024 14:11:25 +0100 Subject: [PATCH 15/18] Add recommended_way_forward and checkout_your_ccv_branch Signed-off-by: Kristine Dosvik --- bin/merge.sh | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/bin/merge.sh b/bin/merge.sh index 4d75674c97..e42b3a1583 100755 --- a/bin/merge.sh +++ b/bin/merge.sh @@ -21,6 +21,7 @@ #Variables: date_time=$(date +%Y.%m.%d-%H.%M) +your_cvv_branch=$(git rev-parse --abbrev-ref HEAD) usage() { @@ -165,7 +166,7 @@ merge_xdev_into_sdev () { clone_x_dv() { - echo "=== Cloning x-dv ===" + echo "======= Cloning x-dv =======" read -p "This overwrites 'cv32e40x/'. Continue? (default: y, n) " yn continue_check $yn @@ -185,7 +186,7 @@ check_merge_status() { rejection_diff() { - echo "=== Merging s/dev to x-dv, using 'theirs' ===" + echo "======= Merging s/dev to x-dv, using 'theirs' =======" echo "WARNING, this function is crude and makes assumptions." cd cv32e40x @@ -203,7 +204,7 @@ rejection_diff() { } need_40s_40x-dv_merge(){ - echo -e "\n=== Check if there are new commits i cv32e40s to merge to cv32e40x-dv ===" + echo -e "\n======= Check if there are new commits i cv32e40s to merge to cv32e40x-dv =======" missing_commits=() nr_commits=100 @@ -259,13 +260,18 @@ need_40s_40x-dv_merge(){ checkout_update_cv32e40s_dev_branch() { - echo -e "\n== Checkout an updated cv32e40s/dev branch ==" + echo -e "\n======= Checkout an updated cv32e40s/dev branch =======" git remote add ohw_cvv git@github.com:openhwgroup/core-v-verif.git git fetch ohw_cvv git checkout ohw_cvv/cv32e40s/dev } +checkout_your_ccv_branch() { + echo -e "\n======= Go back to your ccv branch =======" + git checkout your_cvv_branch +} + continue_check() { case $1 in [Nn]) @@ -279,6 +285,16 @@ continue_check() { esac } +recommended_way_forward() { + echo "======= Recommended way forward =======" + + echo "1) Evaluate all git conflict" + echo "2) Run git diff HEAD on all files (red and green files) to see all merge changes" + echo "3) If some files are not renamed from 40s to 40x, the file content is too different to be recognized as the same file." + echo " Compare the 40s and 40x version of the same file and know there are new changes in the 40s version" + echo " that must manualy be merged to the 40x version. Delete the 40s version of the file after the manual merge is finished." + +} main() { case $1 in @@ -286,10 +302,12 @@ main() { clone_x_dv checkout_update_cv32e40s_dev_branch need_40s_40x-dv_merge + checkout_your_ccv_branch merge_cv32e40s_into_cv32e40x-dv move_files_40s_into_40x substitute_file_content_40s_into_40x check_merge_status + recommended_way_forward ;; "--sdev_into_xdev") merge_sdev_into_xdev From a0dede15c4abad49e8b6b5cc69641718c5108f04 Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Mon, 15 Jan 2024 14:13:55 +0100 Subject: [PATCH 16/18] fix bash variabel bug Signed-off-by: Kristine Dosvik --- bin/merge.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/merge.sh b/bin/merge.sh index e42b3a1583..977eeea7bd 100755 --- a/bin/merge.sh +++ b/bin/merge.sh @@ -269,7 +269,7 @@ checkout_update_cv32e40s_dev_branch() { checkout_your_ccv_branch() { echo -e "\n======= Go back to your ccv branch =======" - git checkout your_cvv_branch + git checkout $your_cvv_branch } continue_check() { From 0473a3936e8f19629531d8e810e00c27065b26dc Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Mon, 15 Jan 2024 14:17:14 +0100 Subject: [PATCH 17/18] Add checkout_your_ccv_branch if exit Signed-off-by: Kristine Dosvik --- bin/merge.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/merge.sh b/bin/merge.sh index 977eeea7bd..effb58df7f 100755 --- a/bin/merge.sh +++ b/bin/merge.sh @@ -276,6 +276,7 @@ continue_check() { case $1 in [Nn]) echo "Exit merge!" + checkout_your_ccv_branch exit 1 ;; *) From d21d056b373fc0e0117ab418f4702d0783a1f946 Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Tue, 16 Jan 2024 11:53:36 +0100 Subject: [PATCH 18/18] remove unnecessary function, reduce complexity, change naming, use more commen y/n question Signed-off-by: Kristine Dosvik --- bin/merge.sh | 78 +++++++++++++++++++++------------------------------- 1 file changed, 32 insertions(+), 46 deletions(-) diff --git a/bin/merge.sh b/bin/merge.sh index effb58df7f..e0ebeef09a 100755 --- a/bin/merge.sh +++ b/bin/merge.sh @@ -76,7 +76,7 @@ merge_cv32e40s_into_cv32e40x-dv () { move_files_40s_into_40x () { echo "======= Replace 40s/S with 40x/X in file names? (recommended) =======" - read -p "(default: y, n)?" yn + read -p "y/n? [default: y] " yn case $yn in [Nn]) @@ -99,7 +99,7 @@ move_files_40s_into_40x () { substitute_file_content_40s_into_40x () { echo "======= Exchange 40x/X with 40s/S in file content? (not recommended) =======" - read -p "(y, default: n)?" yn + read -p "y/n? [default: n] " yn case $yn in [Yy]) echo "=== Content substitution ==="; @@ -168,7 +168,7 @@ clone_x_dv() { echo "======= Cloning x-dv =======" - read -p "This overwrites 'cv32e40x/'. Continue? (default: y, n) " yn + read -p "This overwrites 'cv32e40x/'. Continue? y/n [default: y] " yn continue_check $yn ./bin/clonetb --x-main @@ -206,42 +206,47 @@ rejection_diff() { need_40s_40x-dv_merge(){ echo -e "\n======= Check if there are new commits i cv32e40s to merge to cv32e40x-dv =======" - missing_commits=() - nr_commits=100 - nr_commits_to_check=100 + new_40s_commits=() + num_40s_commits_to_check=100 + num_40x_commits_to_check=100 - # Get commit shas from cv32e40s: - cv32e40s_commits_shas=$(git log --pretty=format:'%H' -$nr_commits -- cv32e40s) - for sha in $cv32e40s_commits_shas; do - commit_message=$(git show -s --format=%s%b $sha) + # Get the updated commit messages from cv32e40s + echo -e "\n== Checkout an updated cv32e40s/dev branch ==" + git remote add ohw_cvv git@github.com:openhwgroup/core-v-verif.git + git fetch ohw_cvv + git checkout ohw_cvv/cv32e40s/dev + commit_messages_40s=$(git log --format=%s -$num_40s_commits_to_check -- cv32e40s) - # If the commit is signed off search for the commit's -m message in cv32e40x-dv - # to check if the commit is merged or not. - if [[ $commit_message =~ "Signed-off-by" ]]; then - commit_m_message=${commit_message%Signed-off-by*} + for commit_message in $commit_messages_40s; do - cd cv32e40x - search_commit=$(git log -$nr_commits_to_check --grep="$commit_m_message" --format=oneline) - cd .. + # Check if the commit message exist in cv32e40x (checks only the last commits of 40x) + cd cv32e40x + is_commit_message_in_40x=$(git log -$num_40x_commits_to_check --grep="$commit_message" --format=oneline) + cd .. - if [[ -z $search_commit ]]; then - missing_commit="$sha: $commit_message" - missing_commits+=("$missing_commit") - fi + if [[ -z $is_commit_message_in_40x ]]; then + # Add new 40s commit to list. Display the new item with sha and commit message + new_40s_commit_wit_both_sha_and_message=$(git log -$num_40s_commits_to_check --grep="$commit_message" --format=oneline) + new_40s_commits+=("$new_40s_commit_wit_both_sha_and_message") fi + done + echo -e "\n== Restore your cvv branch ==" + git checkout $your_cvv_branch + # Print commits needed to be merged, - if [[ -n $missing_commits ]]; then - echo -e "\n== Commits needed to be merged: ==" - for ((i=0; i <= ${#missing_commits[@]} ; i++)); do - echo ${missing_commits[$i]} + if [[ -n $new_40s_commits ]]; then + echo -e "\n== New commits in cv32e40s that need to be merged: ==" + for ((i=0; i <= ${#new_40s_commits[@]} ; i++)); do + echo ${new_40s_commits[$i]} done else - echo -e "\n== No commits needs to be merged ==" + echo -e "\n== No new commits in cv32e40s that need to be merged ==" fi + # List warnings and ask to continue merge echo "== WARNING 1: ==" echo "The script use commit message to identify merged commits" echo "If a new commit in cv32e40s has the same commit message as a commit in cv32e40x-dv or no -m at all," @@ -251,32 +256,15 @@ need_40s_40x-dv_merge(){ echo "The script compares only the 100 latest commits in cv32e40s and cv32e40x-dv" echo -e "If there has been a lot of activity in the reposetories, the result of the above check can be faulty.\n" - - # Ask to continue merge - read -p "Merge commits into cv32e40x-dv? (default: y, n) " yn + read -p "Merge the commits into cv32e40x-dv? y/n [default: y] " yn continue_check $yn } -checkout_update_cv32e40s_dev_branch() { - - echo -e "\n======= Checkout an updated cv32e40s/dev branch =======" - git remote add ohw_cvv git@github.com:openhwgroup/core-v-verif.git - git fetch ohw_cvv - git checkout ohw_cvv/cv32e40s/dev - -} - -checkout_your_ccv_branch() { - echo -e "\n======= Go back to your ccv branch =======" - git checkout $your_cvv_branch -} - continue_check() { case $1 in [Nn]) echo "Exit merge!" - checkout_your_ccv_branch exit 1 ;; *) @@ -301,9 +289,7 @@ main() { case $1 in "--s_into_x-dv") clone_x_dv - checkout_update_cv32e40s_dev_branch need_40s_40x-dv_merge - checkout_your_ccv_branch merge_cv32e40s_into_cv32e40x-dv move_files_40s_into_40x substitute_file_content_40s_into_40x