diff options
Diffstat (limited to 'target/hppa/op_helper.c')
-rw-r--r-- | target/hppa/op_helper.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c index 0daa7511f4..4ee936bf86 100644 --- a/target/hppa/op_helper.c +++ b/target/hppa/op_helper.c @@ -160,21 +160,33 @@ void HELPER(stby_e_parallel)(CPUHPPAState *env, target_ulong addr, do_stby_e(env, addr, val, true); } -target_ureg HELPER(probe_r)(target_ulong addr) +target_ureg HELPER(probe)(CPUHPPAState *env, target_ulong addr, + uint32_t level, uint32_t want) { #ifdef CONFIG_USER_ONLY - return page_check_range(addr, 1, PAGE_READ); + return page_check_range(addr, 1, want); #else - return 1; /* FIXME */ -#endif -} + int prot, excp; + hwaddr phys; -target_ureg HELPER(probe_w)(target_ulong addr) -{ -#ifdef CONFIG_USER_ONLY - return page_check_range(addr, 1, PAGE_WRITE); -#else - return 1; /* FIXME */ + /* Fail if the requested privilege level is higher than current. */ + if (level < (env->iaoq_f & 3)) { + return 0; + } + + excp = hppa_get_physical_address(env, addr, level, 0, &phys, &prot); + if (excp >= 0) { + if (env->psw & PSW_Q) { + /* ??? Needs tweaking for hppa64. */ + env->cr[CR_IOR] = addr; + env->cr[CR_ISR] = addr >> 32; + } + if (excp == EXCP_DTLB_MISS) { + excp = EXCP_NA_DTLB_MISS; + } + hppa_dynamic_excp(env, excp, GETPC()); + } + return (want & prot) != 0; #endif } |