Loading target/hppa/helper.h +1 −2 Original line number Diff line number Diff line Loading @@ -17,8 +17,7 @@ DEF_HELPER_FLAGS_3(stby_b_parallel, TCG_CALL_NO_WG, void, env, tl, tr) DEF_HELPER_FLAGS_3(stby_e, TCG_CALL_NO_WG, void, env, tl, tr) DEF_HELPER_FLAGS_3(stby_e_parallel, TCG_CALL_NO_WG, void, env, tl, tr) DEF_HELPER_FLAGS_1(probe_r, TCG_CALL_NO_RWG_SE, tr, tl) DEF_HELPER_FLAGS_1(probe_w, TCG_CALL_NO_RWG_SE, tr, tl) DEF_HELPER_FLAGS_4(probe, TCG_CALL_NO_WG, tr, env, tl, i32, i32) DEF_HELPER_FLAGS_1(loaded_fr0, TCG_CALL_NO_RWG, void, env) Loading target/hppa/op_helper.c +23 −11 Original line number Diff line number Diff line Loading @@ -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; /* Fail if the requested privilege level is higher than current. */ if (level < (env->iaoq_f & 3)) { return 0; } target_ureg HELPER(probe_w)(target_ulong addr) { #ifdef CONFIG_USER_ONLY return page_check_range(addr, 1, PAGE_WRITE); #else return 1; /* FIXME */ 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 } Loading target/hppa/translate.c +16 −4 Original line number Diff line number Diff line Loading @@ -2380,21 +2380,33 @@ static DisasJumpType trans_probe(DisasContext *ctx, uint32_t insn, { unsigned rt = extract32(insn, 0, 5); unsigned sp = extract32(insn, 14, 2); unsigned rr = extract32(insn, 16, 5); unsigned rb = extract32(insn, 21, 5); unsigned is_write = extract32(insn, 6, 1); unsigned is_imm = extract32(insn, 13, 1); TCGv_reg dest, ofs; TCGv_i32 level, want; TCGv_tl addr; nullify_over(ctx); /* ??? Do something with priv level operand. */ dest = dest_gpr(ctx, rt); form_gva(ctx, &addr, &ofs, rb, 0, 0, 0, sp, 0, false); if (is_write) { gen_helper_probe_w(dest, addr); if (is_imm) { level = tcg_const_i32(extract32(insn, 16, 2)); } else { gen_helper_probe_r(dest, addr); level = tcg_temp_new_i32(); tcg_gen_trunc_reg_i32(level, load_gpr(ctx, rr)); tcg_gen_andi_i32(level, level, 3); } want = tcg_const_i32(is_write ? PAGE_WRITE : PAGE_READ); gen_helper_probe(dest, cpu_env, addr, level, want); tcg_temp_free_i32(want); tcg_temp_free_i32(level); save_gpr(ctx, rt, dest); return nullify_end(ctx, DISAS_NEXT); } Loading Loading
target/hppa/helper.h +1 −2 Original line number Diff line number Diff line Loading @@ -17,8 +17,7 @@ DEF_HELPER_FLAGS_3(stby_b_parallel, TCG_CALL_NO_WG, void, env, tl, tr) DEF_HELPER_FLAGS_3(stby_e, TCG_CALL_NO_WG, void, env, tl, tr) DEF_HELPER_FLAGS_3(stby_e_parallel, TCG_CALL_NO_WG, void, env, tl, tr) DEF_HELPER_FLAGS_1(probe_r, TCG_CALL_NO_RWG_SE, tr, tl) DEF_HELPER_FLAGS_1(probe_w, TCG_CALL_NO_RWG_SE, tr, tl) DEF_HELPER_FLAGS_4(probe, TCG_CALL_NO_WG, tr, env, tl, i32, i32) DEF_HELPER_FLAGS_1(loaded_fr0, TCG_CALL_NO_RWG, void, env) Loading
target/hppa/op_helper.c +23 −11 Original line number Diff line number Diff line Loading @@ -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; /* Fail if the requested privilege level is higher than current. */ if (level < (env->iaoq_f & 3)) { return 0; } target_ureg HELPER(probe_w)(target_ulong addr) { #ifdef CONFIG_USER_ONLY return page_check_range(addr, 1, PAGE_WRITE); #else return 1; /* FIXME */ 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 } Loading
target/hppa/translate.c +16 −4 Original line number Diff line number Diff line Loading @@ -2380,21 +2380,33 @@ static DisasJumpType trans_probe(DisasContext *ctx, uint32_t insn, { unsigned rt = extract32(insn, 0, 5); unsigned sp = extract32(insn, 14, 2); unsigned rr = extract32(insn, 16, 5); unsigned rb = extract32(insn, 21, 5); unsigned is_write = extract32(insn, 6, 1); unsigned is_imm = extract32(insn, 13, 1); TCGv_reg dest, ofs; TCGv_i32 level, want; TCGv_tl addr; nullify_over(ctx); /* ??? Do something with priv level operand. */ dest = dest_gpr(ctx, rt); form_gva(ctx, &addr, &ofs, rb, 0, 0, 0, sp, 0, false); if (is_write) { gen_helper_probe_w(dest, addr); if (is_imm) { level = tcg_const_i32(extract32(insn, 16, 2)); } else { gen_helper_probe_r(dest, addr); level = tcg_temp_new_i32(); tcg_gen_trunc_reg_i32(level, load_gpr(ctx, rr)); tcg_gen_andi_i32(level, level, 3); } want = tcg_const_i32(is_write ? PAGE_WRITE : PAGE_READ); gen_helper_probe(dest, cpu_env, addr, level, want); tcg_temp_free_i32(want); tcg_temp_free_i32(level); save_gpr(ctx, rt, dest); return nullify_end(ctx, DISAS_NEXT); } Loading