Skip to content
This repository was archived by the owner on Apr 13, 2019. It is now read-only.

Commit f6cbc72

Browse files
Michael Clarkwxjstz
Michael Clark
andcommitted
target/riscv/pmp: Fix address matching, granularity and debug
- Rename pmp_hart_has_priv to pmp_has_access as this is a more appropriate name for tracing - Add tracing for CSR reads and writes to pmpcfg and pmpaddr using -d trace:pmpcfg_csr_read,trace:pmpcfg_csr_write, trace:pmpaddr_csr_read,trace:pmpaddr_csr_write - Add tracing for PMP access and rule matching using -d trace:pmp_has_access,trace:pmp_rule_match - Add early out if not all rules are present; short-circuit optimization bug for discontiguous rules fixed (reported by wxjstz <[email protected]>) - Fix bug where TLB entries were created for rules smaller than the page size (4096), which caused results of rules with small spans to be erroneously used in subsequent accesses - Fix integer promotion bug in pmpcfg_csr_read (also reported by wxjstz <[email protected]>) - Fix bug where PMP allowed non M-mode accesses when no rules have been configured (default behaviour is to deny access to other modes until PMP has been configured. (also reported by wxjstz <[email protected]>) - Fix illegal offsets for pmpcfg CSR accesses on rv64 (reported by wxjstz <[email protected]>) - Use size_t for PMP CSR address offsets (unsigned int can result in sign extension on some 64-bit architectures) - Add granularity parameter and mask addresss writes so that granularity can be detected. - Use NA4 bit to represent terminal granule size where G > 0 (this is implied by the specification) - Remove redundant debugging statements (unnecessar with the new tracing support). - Simplify rule matching loop and use a ternary expression that contains the entire rule match result in a similar condensed style to spike (riscv-isa-sim). Co-authored-by: wxjstz <[email protected]> Signed-off-by: Michael Clark <[email protected]>
1 parent 6b6f93c commit f6cbc72

File tree

5 files changed

+180
-258
lines changed

5 files changed

+180
-258
lines changed

target/riscv/cpu_bits

1.99 MB
Binary file not shown.

target/riscv/cpu_helper.c

+9-5
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ int riscv_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size,
414414
#if !defined(CONFIG_USER_ONLY)
415415
hwaddr pa = 0;
416416
int prot;
417+
target_ulong tlb_size = TARGET_PAGE_SIZE;
417418
#endif
418419
int ret = TRANSLATE_FAIL;
419420

@@ -423,17 +424,20 @@ int riscv_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size,
423424

424425
#if !defined(CONFIG_USER_ONLY)
425426
ret = get_physical_address(env, &pa, &prot, address, rw, mmu_idx);
427+
426428
qemu_log_mask(CPU_LOG_MMU,
427429
"%s address=%" VADDR_PRIx " ret %d physical " TARGET_FMT_plx
428430
" prot %d\n", __func__, address, ret, pa, prot);
429-
if (riscv_feature(env, RISCV_FEATURE_PMP) &&
430-
!pmp_hart_has_privs(env, pa, TARGET_PAGE_SIZE, 1 << rw)) {
431-
ret = TRANSLATE_FAIL;
431+
432+
if (ret == TRANSLATE_SUCCESS && riscv_feature(env, RISCV_FEATURE_PMP)) {
433+
ret = pmp_has_access(env, pa, size, rw, &tlb_size) ?
434+
TRANSLATE_SUCCESS : TRANSLATE_FAIL;
432435
}
436+
433437
if (ret == TRANSLATE_SUCCESS) {
434438
tlb_set_page(cs, address & TARGET_PAGE_MASK, pa & TARGET_PAGE_MASK,
435-
prot, mmu_idx, TARGET_PAGE_SIZE);
436-
} else if (ret == TRANSLATE_FAIL) {
439+
prot, mmu_idx, tlb_size);
440+
} else {
437441
raise_mmu_exception(env, address, rw);
438442
}
439443
#else

0 commit comments

Comments
 (0)