-
Notifications
You must be signed in to change notification settings - Fork 55
Support for coverage of Privilged Architecture #80
Support for coverage of Privilged Architecture #80
Conversation
Update to check the registers only of interest for read_csr() function:Previously, if we used any coverpoint in the following pattern to compare the old_value of the register with the current value, it used to compare the register values with every instruction which was not required and we had no way to detect that whether the coverpoint of interest hit because of the required instruction or not. Now, if the user uses the coverpoints of the following pattern, then the isac will only check the instructions of interest for the coverpoint. (pmpcfg0 & 0x80 == 0x80) and (old("pmpcfg0") & 0xFF) ^ (pmpcfg0 & 0xFF) == 0x00 and old("pmpcfg0") != 0: 0 Explanation of the coverpoint patternThe above coverpoint will check whether the value of the register mem[X,0x800003B0] -> 0x9073
mem[X,0x800003B2] -> 0x3A03
[176] [M]: 0x800003B0 (0x3A039073) csrrw zero, pmpcfg0, t2
CSR pmpcfg0 -> 0x00000000
CSR pmpcfg0 <- 0x9F9F9F9F (input: 0xFFFFFFFF)
mem[X,0x800003B4] -> 0xB073
mem[X,0x800003B6] -> 0x3A03
[177] [M]: 0x800003B4 (0x3A03B073) csrrc zero, pmpcfg0, t2
CSR pmpcfg0 -> 0x9F9F9F9F
CSR pmpcfg0 <- 0x9F9F9F9F (input: 0x00000000) As, we try to change the value of the pmpcfg0 but it is not changed because of the lock bit, therefore, the value in the old_csr_regfile will not change which we can check using the coverpoint: old("pmpcfg0") & 0xFF) ^ (pmpcfg0 & 0xFF) == 0x00 |
Mode Check Support:In this commit, I have added the support for checking the Mode in which the hart is currently executed. Consider the following part of the log: mem[X,0x80000A84] -> 0x2403
mem[X,0x80000A86] -> 0x1E41
[205] [M]: 0x80000A84 (0x1E412403) lw fp, 484(sp)
mem[R,0x800031E4] -> 0x5BFDDB7D
x8 <- 0x5BFDDB7D Previously, there was no mechanism to determine the execution mode of the instruction. SolutionNow, users can easily check the mode in which the hart executed the instruction using the following coverpoint: "mode == 'M' and ((pmpaddr2) >= 0x00000000) and ((pmpaddr2) <= 0xFFFFFFFF)": 0 This coverpoint ensures that the current instruction of interest is executed in the required mode. Check address of Label defined in the test:Earlier, there was no support for checking the address of labels defined in the test. Now, users can employ the following coverpoint pattern to find the address of any labeled point in the test: "get_addr('rvtest_data') == 0x80000388": 0 UsageThe |
Without going into implementation details, this looks really good, and are necessary for many tests. |
…ssue 57 implemented
Virtual Memory ImplementationIn this commit, I have implemented the requested variables for the Physical address, virtual address, page table walk addresses for the instructions and data accesses in the issue # 57 by Mr. Pawan in the RISC-V ISAC. ImplementationConsider the following log which will be used as a reference to explain the implementation: mem[X,0x800007D4] -> 0x0073
mem[X,0x800007D6] -> 0x3020
[444] [M]: 0x800007D4 (0x30200073) mret
CSR mstatus <- 0x00000080
ret-ing from M to S
mem[R,0x82002900] -> 0x20800401
mem[R,0x82001000] -> 0x200000CF
mem[X,0x800007D8] -> 0xE737
mem[X,0x800007DA] -> 0x0000
[445] [S]: 0x900007D8 (0x0000E737) lui a4, 14
x14 <- 0x0000E000
mem[X,0x800007DC] -> 0x0713
mem[X,0x800007DE] -> 0xEAD7
[446] [S]: 0x900007DC (0xEAD70713) addi a4, a4, 3757
x14 <- 0x0000DEAD
mem[X,0x800007E0] -> 0xA423
mem[X,0x800007E2] -> 0x00ED
[447] [S]: 0x900007E0 (0x00EDA423) sw a4, 8(s11)
mem[R,0x82002930] -> 0x20800401
mem[R,0x8200100C] -> 0x20800CCF
mem[0x8200311C] <- 0x0000DEAD
Previously, there was no way to access any of the page table walks, virtual address and physical address in case of virtual memory implementation. Solution and ExplanationNow, consider the following coverpoint for understanding: check_virtual_memory:
config:
- check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; option VM = SV32;'
mnemonics:
sw: 0
val_comb:
'len_dptw == 2 and dptw1a == 0x82002930 and dptw0a == 0x8200100C and ieva == 0x900007E0 and iepa == 0x800007E0 and len_iptw == 2 and iptw1a == 0x82002900 and iptw0a == 0x82001000': 0
whose purpose is to target the following instruction in the above log file: mem[X,0x800007E0] -> 0xA423
mem[X,0x800007E2] -> 0x00ED
[447] [S]: 0x900007E0 (0x00EDA423) sw a4, 8(s11)
mem[R,0x82002930] -> 0x20800401
mem[R,0x8200100C] -> 0x20800CCF
mem[0x8200311C] <- 0x0000DEAD First of all, if you want to enable the following variables you need to add a flag option VM = SV(addressing scheme) where addressing scheme in this case was SV-32. You need to add this flag under the config node. config:
- check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; option VM = SV32;' As, you may see in the coverpoint, there are multiple variables being used, I will write the purpose of every variable one by one:
Instruction access page table walksNow, for the page table walks for the address access of the instructions: These variables are used for the page table walks for the instruction. To check how many were done in your case, you may use the following variable: Data access page table walksNow, for the page table walks for the address access of the data: State for data access variables is not stored as these walks will be tracked on every data access. Their purpose is same as the instruction ones expect they are used for the data access page table walks. ImportantState of the variables for the page table walks of instruction access has also been stored which you may verify from the above sw a4, 8(s11) coverpoint. When the first page table walk is done, the state of these instruction page table walk address variables is not changed untill the mode is switched back to M - mode or the page table is accessed again making it easy for the user to track. |
Value at Memory LocationIn this commit, I have added the support for reading the value stored at a specific address. Consider the following coverpoint: 'mem_val(get_addr("rvtest_data"),4) == 0xBEEDCAFE': 0 As, you may see that get_addr() that is added in previous commit was used to extract the address using the label is used in this coverpoint to get the address of rvtest_data and then the 4 written after the comma represents the size of memory we want to extract from the memory location. In this case, I wanted to get 4 Bytes, therefore, 4 is written. This is a function defined in the csr_comb. User may also write a specific address of his/her interest to check the value stored at that address. '(mem_val(0x80000388, 2) == 0xBEEDCAFE)': 0 |
PTE Permission Access FunctionIn this commit, I have added a function named as The python function is given as: def get_pte_per(pa, pte_addr, pgtb_addr):
for match in matches_for_options:
if match[0] == 'VM' and match[1] in ['SV39', 'SV48', 'SV57']:
pte_size = 8
elif match[0] == 'VM' and match[1] in ['SV32']:
pte_size = 4
if (pgtb_addr >> 12) == (pte_addr >> 12):
if ((pa >> 12) == (get_mem_val(pte_addr, pte_size) >> 10)):
return get_mem_val(pte_addr, pte_size) & 0x3FF
else:
return None
else:
return None The coverpoint for this functionality is given as: check_for_the_isac:
config:
- check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; option VM = SV32;
mnemonics:
sw: 0
csrrw: 0
csrrs: 0
csrrc: 0
lw: 0
val_comb:
'get_pte_per(get_addr("rvtest_data"),rs1_val + imm_val,get_addr("rvtest_slvl1_pg_tbl")) == 0xCF': 0 So, using this coverpoint we are sure that the pte is set for the rvtest_data |
This happened quite a bit faster than I expected.
|
Also note that the level variable start value is dependent on the SATP mode
Also note that tests for VM should make sure that TLBs are turned off in whichever model is the reference model (for these tests only) so they don't skip any access. |
… content for iptw and dptw added, pte_prop_name check added
VIrtual Memory Implementation:Now, the coverpoints don't need a special lablel for the virtual memory else the track of all the virtual memory registers is kept by the isac itself using the satp register.
get_mem_val(2181042244,4) == 545259727: 0 #dptw0
get_mem_val(2181048576,4) == 545260545: 0 #dptw1 PTE Permissions function updated to GET_PTEThe function to get the pte permissions has been updated to val_comb:
'get_pte(get_addr("rvtest_data"),rs1_val + imm_val,get_addr("rvtest_slvl1_pg_tbl")) == 0x800000CF': 0 Function to check the specific permission addedNow, the function to check the specific permission of the pte using the get_pte_prop('U',get_addr("begin_signature"), rs1_val + imm_val, get_addr("rvtest_slvl1_pg_tbl")) == 1: 0
|
Macros file Support AddedIn this commit, I have added support for using a macro in the coverpoints. common:
shift_bit: 0x001
self:
final_value: 0x012 The header file is written in the -h -> header file flag
-cm -> cgf macro flag
riscv_isac --verbose info coverage -d -t /home/hammad/riscv-arch-test/riscof_work/torr_tests.S/torr_tests.log --parser-name c_sail -o coverage.rpt --sig-label begin_signature end_signature -e /home/hammad/riscv-arch-test/riscof_work/torr_tests.S/ref.elf -c /home/hammad/riscv-ctg/sample_cgfs/dataset.cgf -c /home/hammad/PMP_Coverpoints/checkcover_1.cgf -x32 -l virtual_memory_functions_test -h /home/hammad/header_file.yaml -cm self Consider the following coverpoint: val_comb:
${shift_bit} == 1: 0
${final_value} == 0x012: 0 So, when user may run the above command, the coverpoints will be replaced by the values assigned in the headerfile written in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation should also be updated to indicate the added variables for the coverpoints.
@allenjbaum, |
@pawks, |
…and update the unsgn_rs2 dict and evaluators for rd_val
@pawks All the required changes have been made, can you please review it again for any further changes |
@allenjbaum I am mentioning you again, can you merge it now? It has been stalled for quite a few weeks |
Introducing Translator SupportWe've incorporated a script for translating CGF files to reduce redundancy at the user-end while writing the coverpoints. This script was developed in collaboration with Mr. @allenjbaum. To illustrate its functionality, let's examine a specific coverpoint:
The above will be processed by the translator_cgf.py and will result in the following coverpoint after the macros are resolved as well:
|
Signed-off-by: Umer Shahid <[email protected]>
Dismissing this one, as this review was on the older version, and the changes have been addressed by the contributor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a great addition to the functionality of creating coverpoints
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
mnemonic flag support:
The
mnemonic
can be used to write a coverpoint that should target a instruction of interest only. For instance, lr or sc. Coverpoint can be written in the following pattern: