target/hppa: Fix load/store offset assembly for wide mode

target/hppa: Fix LDCW,S shift
 target/hppa: Fix SHRPD conditions
 target/hppa: Fix access_id checks
 target/hppa: Exit TB after Flush Instruction Cache
 target/hppa: Fix MFIA result
 target hppa: Fix STDBY,E
 -----BEGIN PGP SIGNATURE-----
 
 iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmX6LjYdHHJpY2hhcmQu
 aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV8uoAgAtEGgWqZNRNa/neD7
 0Dix2sTz85hqob2/4ajmEhy5XlF8V+5gCz15vHDCr+J0VIbAZj90HAolhplViBn2
 twwEbf8CjJ7g/rDF2L2rwCv4cG72yKyMWTTXXCQGuzo977ObfRgmguCsFSoRlkdD
 YuiAUEt/jziGmv4wYv/9zymQUEydeMGFnmCgIwRxg6IT4krI7C5g8198wA0Eu59Y
 SZMWquzKv3+gezETHs/PSco4ZM5EeoKzsIWA+hhUP/hbBdEW4w+AtPB2ZSlywluX
 ALU97bZRgncCAeNENgTNoVQ8WTg1p5t3opP4vQR2afzhqLkMPMX4RCo8BaHhDzmm
 srvqpw==
 =DpgT
 -----END PGP SIGNATURE-----

Merge tag 'pull-pa-20240319' of https://gitlab.com/rth7680/qemu into staging

target/hppa: Fix load/store offset assembly for wide mode
target/hppa: Fix LDCW,S shift
target/hppa: Fix SHRPD conditions
target/hppa: Fix access_id checks
target/hppa: Exit TB after Flush Instruction Cache
target/hppa: Fix MFIA result
target hppa: Fix STDBY,E

# -----BEGIN PGP SIGNATURE-----
#
# iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmX6LjYdHHJpY2hhcmQu
# aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV8uoAgAtEGgWqZNRNa/neD7
# 0Dix2sTz85hqob2/4ajmEhy5XlF8V+5gCz15vHDCr+J0VIbAZj90HAolhplViBn2
# twwEbf8CjJ7g/rDF2L2rwCv4cG72yKyMWTTXXCQGuzo977ObfRgmguCsFSoRlkdD
# YuiAUEt/jziGmv4wYv/9zymQUEydeMGFnmCgIwRxg6IT4krI7C5g8198wA0Eu59Y
# SZMWquzKv3+gezETHs/PSco4ZM5EeoKzsIWA+hhUP/hbBdEW4w+AtPB2ZSlywluX
# ALU97bZRgncCAeNENgTNoVQ8WTg1p5t3opP4vQR2afzhqLkMPMX4RCo8BaHhDzmm
# srvqpw==
# =DpgT
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 20 Mar 2024 00:30:46 GMT
# gpg:                using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg:                issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full]
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A  05C0 64DF 38E8 AF7E 215F

* tag 'pull-pa-20240319' of https://gitlab.com/rth7680/qemu:
  target/hppa: fix do_stdby_e()
  target/hppa: mask privilege bits in mfia
  target/hppa: exit tb on flush cache instructions
  target/hppa: fix access_id check
  target/hppa: fix shrp for wide mode
  target/hppa: ldcw,s uses static shift of 3
  target/hppa: Fix assemble_12a insns for wide mode
  target/hppa: Fix assemble_11a insns for wide mode
  target/hppa: Fix assemble_16 insns for wide mode

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2024-03-20 12:01:32 +00:00
commit bc36f12e64
4 changed files with 166 additions and 56 deletions

View File

@ -24,16 +24,17 @@
%assemble_sr3 13:1 14:2
%assemble_sr3x 13:1 14:2 !function=expand_sr3x
%assemble_11a 0:s1 4:10 !function=expand_shl3
%assemble_11a 4:12 0:1 !function=expand_11a
%assemble_12 0:s1 2:1 3:10 !function=expand_shl2
%assemble_12a 0:s1 3:11 !function=expand_shl2
%assemble_12a 3:13 0:1 !function=expand_12a
%assemble_16 0:16 !function=expand_16
%assemble_17 0:s1 16:5 2:1 3:10 !function=expand_shl2
%assemble_22 0:s1 16:10 2:1 3:10 !function=expand_shl2
%assemble_sp 14:2 !function=sp0_if_wide
%assemble_21 0:s1 1:11 14:2 16:5 12:2 !function=expand_shl11
%lowsign_11 0:s1 1:10
%lowsign_14 0:s1 1:13
%sm_imm 16:10 !function=expand_sm_imm
@ -143,9 +144,9 @@ getshadowregs 1111 1111 1111 1101 1110 1010 1101 0010
nop 000001 ----- ----- -- 11001010 0 ----- # fdc, disp
nop_addrx 000001 ..... ..... -- 01001010 . ----- @addrx # fdc, index
nop_addrx 000001 ..... ..... -- 01001011 . ----- @addrx # fdce
nop_addrx 000001 ..... ..... --- 0001010 . ----- @addrx # fic 0x0a
nop_addrx 000001 ..... ..... -- 01001111 . 00000 @addrx # fic 0x4f
nop_addrx 000001 ..... ..... --- 0001011 . ----- @addrx # fice
fic 000001 ..... ..... --- 0001010 . ----- @addrx # fic 0x0a
fic 000001 ..... ..... -- 01001111 . 00000 @addrx # fic 0x4f
fic 000001 ..... ..... --- 0001011 . ----- @addrx # fice
nop_addrx 000001 ..... ..... -- 01001110 . 00000 @addrx # pdc
probe 000001 b:5 ri:5 sp:2 imm:1 100011 write:1 0 t:5
@ -221,7 +222,7 @@ sub_b_tsv 000010 ..... ..... .... 110100 . ..... @rrr_cf_d
ldil 001000 t:5 ..................... i=%assemble_21
addil 001010 r:5 ..................... i=%assemble_21
ldo 001101 b:5 t:5 -- .............. i=%lowsign_14
ldo 001101 b:5 t:5 ................ i=%assemble_16
addi 101101 ..... ..... .... 0 ........... @rri_cf
addi_tsv 101101 ..... ..... .... 1 ........... @rri_cf
@ -304,14 +305,18 @@ fstd 001011 ..... ..... .. . 1 -- 100 0 . ..... @fldstdi
# Offset Mem
####
@ldstim11 ...... b:5 t:5 sp:2 .............. \
&ldst disp=%assemble_11a m=%ma2_to_m x=0 scale=0 size=3
@ldstim14 ...... b:5 t:5 sp:2 .............. \
&ldst disp=%lowsign_14 x=0 scale=0 m=0
@ldstim14m ...... b:5 t:5 sp:2 .............. \
&ldst disp=%lowsign_14 x=0 scale=0 m=%neg_to_m
@ldstim12m ...... b:5 t:5 sp:2 .............. \
&ldst disp=%assemble_12a x=0 scale=0 m=%pos_to_m
@ldstim11 ...... b:5 t:5 ................ \
&ldst sp=%assemble_sp disp=%assemble_11a \
m=%ma2_to_m x=0 scale=0 size=3
@ldstim14 ...... b:5 t:5 ................ \
&ldst sp=%assemble_sp disp=%assemble_16 \
x=0 scale=0 m=0
@ldstim14m ...... b:5 t:5 ................ \
&ldst sp=%assemble_sp disp=%assemble_16 \
x=0 scale=0 m=%neg_to_m
@ldstim12m ...... b:5 t:5 ................ \
&ldst sp=%assemble_sp disp=%assemble_12a \
x=0 scale=0 m=%pos_to_m
# LDB, LDH, LDW, LDWM
ld 010000 ..... ..... .. .............. @ldstim14 size=0
@ -327,15 +332,19 @@ st 011010 ..... ..... .. .............. @ldstim14 size=2
st 011011 ..... ..... .. .............. @ldstim14m size=2
st 011111 ..... ..... .. ...........10. @ldstim12m size=2
fldw 010110 b:5 ..... sp:2 .............. \
&ldst disp=%assemble_12a t=%rm64 m=%a_to_m x=0 scale=0 size=2
fldw 010111 b:5 ..... sp:2 ...........0.. \
&ldst disp=%assemble_12a t=%rm64 m=0 x=0 scale=0 size=2
fldw 010110 b:5 ..... ................ \
&ldst disp=%assemble_12a sp=%assemble_sp \
t=%rm64 m=%a_to_m x=0 scale=0 size=2
fldw 010111 b:5 ..... .............0.. \
&ldst disp=%assemble_12a sp=%assemble_sp \
t=%rm64 m=0 x=0 scale=0 size=2
fstw 011110 b:5 ..... sp:2 .............. \
&ldst disp=%assemble_12a t=%rm64 m=%a_to_m x=0 scale=0 size=2
fstw 011111 b:5 ..... sp:2 ...........0.. \
&ldst disp=%assemble_12a t=%rm64 m=0 x=0 scale=0 size=2
fstw 011110 b:5 ..... ................ \
&ldst disp=%assemble_12a sp=%assemble_sp \
t=%rm64 m=%a_to_m x=0 scale=0 size=2
fstw 011111 b:5 ..... .............0.. \
&ldst disp=%assemble_12a sp=%assemble_sp \
t=%rm64 m=0 x=0 scale=0 size=2
ld 010100 ..... ..... .. ............0. @ldstim11
fldd 010100 ..... ..... .. ............1. @ldstim11

View File

@ -152,6 +152,49 @@ static HPPATLBEntry *hppa_alloc_tlb_ent(CPUHPPAState *env)
return ent;
}
#define ACCESS_ID_MASK 0xffff
/* Return the set of protections allowed by a PID match. */
static int match_prot_id_1(uint32_t access_id, uint32_t prot_id)
{
if (((access_id ^ (prot_id >> 1)) & ACCESS_ID_MASK) == 0) {
return (prot_id & 1
? PAGE_EXEC | PAGE_READ
: PAGE_EXEC | PAGE_READ | PAGE_WRITE);
}
return 0;
}
static int match_prot_id32(CPUHPPAState *env, uint32_t access_id)
{
int r, i;
for (i = CR_PID1; i <= CR_PID4; ++i) {
r = match_prot_id_1(access_id, env->cr[i]);
if (r) {
return r;
}
}
return 0;
}
static int match_prot_id64(CPUHPPAState *env, uint32_t access_id)
{
int r, i;
for (i = CR_PID1; i <= CR_PID4; ++i) {
r = match_prot_id_1(access_id, env->cr[i]);
if (r) {
return r;
}
r = match_prot_id_1(access_id, env->cr[i] >> 32);
if (r) {
return r;
}
}
return 0;
}
int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
int type, hwaddr *pphys, int *pprot,
HPPATLBEntry **tlb_entry)
@ -224,29 +267,30 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
break;
}
/* access_id == 0 means public page and no check is performed */
if (ent->access_id && MMU_IDX_TO_P(mmu_idx)) {
/* If bits [31:1] match, and bit 0 is set, suppress write. */
int match = ent->access_id * 2 + 1;
if (match == env->cr[CR_PID1] || match == env->cr[CR_PID2] ||
match == env->cr[CR_PID3] || match == env->cr[CR_PID4]) {
prot &= PAGE_READ | PAGE_EXEC;
if (type == PAGE_WRITE) {
ret = EXCP_DMPI;
goto egress;
}
}
}
/* No guest access type indicates a non-architectural access from
within QEMU. Bypass checks for access, D, B and T bits. */
/*
* No guest access type indicates a non-architectural access from
* within QEMU. Bypass checks for access, D, B, P and T bits.
*/
if (type == 0) {
goto egress;
}
/* access_id == 0 means public page and no check is performed */
if (ent->access_id && MMU_IDX_TO_P(mmu_idx)) {
int access_prot = (hppa_is_pa20(env)
? match_prot_id64(env, ent->access_id)
: match_prot_id32(env, ent->access_id));
if (unlikely(!(type & access_prot))) {
/* Not allowed -- Inst/Data Memory Protection Id Fault. */
ret = type & PAGE_EXEC ? EXCP_IMP : EXCP_DMPI;
goto egress;
}
/* Otherwise exclude permissions not allowed (i.e WD). */
prot &= access_prot;
}
if (unlikely(!(prot & type))) {
/* The access isn't allowed -- Inst/Data Memory Protection Fault. */
/* Not allowed -- Inst/Data Memory Access Rights Fault. */
ret = (type & PAGE_EXEC) ? EXCP_IMP : EXCP_DMAR;
goto egress;
}

View File

@ -281,17 +281,17 @@ static void do_stdby_e(CPUHPPAState *env, target_ulong addr, uint64_t val,
case 3:
/* The 3 byte store must appear atomic. */
if (parallel) {
atomic_store_mask32(env, addr - 3, val, 0xffffff00u, ra);
atomic_store_mask32(env, addr - 3, val >> 32, 0xffffff00u, ra);
} else {
cpu_stw_data_ra(env, addr - 3, val >> 16, ra);
cpu_stb_data_ra(env, addr - 1, val >> 8, ra);
cpu_stw_data_ra(env, addr - 3, val >> 48, ra);
cpu_stb_data_ra(env, addr - 1, val >> 40, ra);
}
break;
case 2:
cpu_stw_data_ra(env, addr - 2, val >> 16, ra);
cpu_stw_data_ra(env, addr - 2, val >> 48, ra);
break;
case 1:
cpu_stb_data_ra(env, addr - 1, val >> 24, ra);
cpu_stb_data_ra(env, addr - 1, val >> 56, ra);
break;
default:
/* Nothing is stored, but protection is checked and the

View File

@ -121,12 +121,6 @@ static int expand_shl2(DisasContext *ctx, int val)
return val << 2;
}
/* Used for fp memory ops. */
static int expand_shl3(DisasContext *ctx, int val)
{
return val << 3;
}
/* Used for assemble_21. */
static int expand_shl11(DisasContext *ctx, int val)
{
@ -144,6 +138,62 @@ static int assemble_6(DisasContext *ctx, int val)
return (val ^ 31) + 1;
}
/* Expander for assemble_16a(s,cat(im10a,0),i). */
static int expand_11a(DisasContext *ctx, int val)
{
/*
* @val is bit 0 and bits [4:15].
* Swizzle thing around depending on PSW.W.
*/
int im10a = extract32(val, 1, 10);
int s = extract32(val, 11, 2);
int i = (-(val & 1) << 13) | (im10a << 3);
if (ctx->tb_flags & PSW_W) {
i ^= s << 13;
}
return i;
}
/* Expander for assemble_16a(s,im11a,i). */
static int expand_12a(DisasContext *ctx, int val)
{
/*
* @val is bit 0 and bits [3:15].
* Swizzle thing around depending on PSW.W.
*/
int im11a = extract32(val, 1, 11);
int s = extract32(val, 12, 2);
int i = (-(val & 1) << 13) | (im11a << 2);
if (ctx->tb_flags & PSW_W) {
i ^= s << 13;
}
return i;
}
/* Expander for assemble_16(s,im14). */
static int expand_16(DisasContext *ctx, int val)
{
/*
* @val is bits [0:15], containing both im14 and s.
* Swizzle thing around depending on PSW.W.
*/
int s = extract32(val, 14, 2);
int i = (-(val & 1) << 13) | extract32(val, 1, 13);
if (ctx->tb_flags & PSW_W) {
i ^= s << 13;
}
return i;
}
/* The sp field is only present with !PSW_W. */
static int sp0_if_wide(DisasContext *ctx, int sp)
{
return ctx->tb_flags & PSW_W ? 0 : sp;
}
/* Translate CMPI doubleword conditions to standard. */
static int cmpbid_c(DisasContext *ctx, int val)
{
@ -1961,7 +2011,7 @@ static bool trans_mfia(DisasContext *ctx, arg_mfia *a)
{
unsigned rt = a->t;
TCGv_i64 tmp = dest_gpr(ctx, rt);
tcg_gen_movi_i64(tmp, ctx->iaoq_f);
tcg_gen_movi_i64(tmp, ctx->iaoq_f & ~3ULL);
save_gpr(ctx, rt, tmp);
cond_free(&ctx->null_cond);
@ -2293,6 +2343,13 @@ static bool trans_nop_addrx(DisasContext *ctx, arg_ldst *a)
return true;
}
static bool trans_fic(DisasContext *ctx, arg_ldst *a)
{
/* End TB for flush instruction cache, so we pick up new insns. */
ctx->base.is_jmp = DISAS_IAQ_N_STALE;
return trans_nop_addrx(ctx, a);
}
static bool trans_probe(DisasContext *ctx, arg_probe *a)
{
TCGv_i64 dest, ofs;
@ -3085,7 +3142,7 @@ static bool trans_ldc(DisasContext *ctx, arg_ldst *a)
dest = dest_gpr(ctx, a->t);
}
form_gva(ctx, &addr, &ofs, a->b, a->x, a->scale ? a->size : 0,
form_gva(ctx, &addr, &ofs, a->b, a->x, a->scale ? 3 : 0,
a->disp, a->sp, a->m, MMU_DISABLED(ctx));
/*
@ -3462,7 +3519,7 @@ static bool trans_shrp_sar(DisasContext *ctx, arg_shrp_sar *a)
/* Install the new nullification. */
cond_free(&ctx->null_cond);
if (a->c) {
ctx->null_cond = do_sed_cond(ctx, a->c, false, dest);
ctx->null_cond = do_sed_cond(ctx, a->c, a->d, dest);
}
return nullify_end(ctx);
}
@ -3505,7 +3562,7 @@ static bool trans_shrp_imm(DisasContext *ctx, arg_shrp_imm *a)
/* Install the new nullification. */
cond_free(&ctx->null_cond);
if (a->c) {
ctx->null_cond = do_sed_cond(ctx, a->c, false, dest);
ctx->null_cond = do_sed_cond(ctx, a->c, a->d, dest);
}
return nullify_end(ctx);
}