hppa 64-bit mfdiag improvements

The 64-bit hppa qemu emulation still fails to boot 64-bit HP-UX.
 This patch series improves the emulation a lot, since it enables us to boot
 64-bit HP-UX installer silently up until an endless loop where the machine
 reports that it's up an running (it crashed before). This still needs further
 analysis, but it's a big step forward.
 
 Main changes to archieve this includes:
 - Implementing diagnose registers (especially %dr2 for space-register hashing)
 - a new SeaBIOS-hppa version 18, which includes those fixes and enhancements:
   - Fix IRT table entries to use slot number
   - Increase PCI alignment for memory bars to 64k
   - Fix PDC_CACHE/PDC_CACHE_RET_SPID return value
   - Allow up to 256 GB RAM on 64-bit machines
 
 V2:
 - fix linux-user build by adding missing "#ifndef CONFIG_USER_ONLY ... #endif"
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQS86RI+GtKfB8BJu973ErUQojoPXwUCZ5yWTwAKCRD3ErUQojoP
 X1p5AP4iSfKlBsUZrww2/M1ArqB9jZuJBO1kdZ7OcCN2Jn0yxgEAx0CPUof7NnZV
 EY7u3Qq4E8ZnOk4XgHt06bsdNcJN+gc=
 =RoAh
 -----END PGP SIGNATURE-----

Merge tag 'hppa-system-mfdiag-for-v10-pull-request' of https://github.com/hdeller/qemu-hppa into staging

hppa 64-bit mfdiag improvements

The 64-bit hppa qemu emulation still fails to boot 64-bit HP-UX.
This patch series improves the emulation a lot, since it enables us to boot
64-bit HP-UX installer silently up until an endless loop where the machine
reports that it's up an running (it crashed before). This still needs further
analysis, but it's a big step forward.

Main changes to archieve this includes:
- Implementing diagnose registers (especially %dr2 for space-register hashing)
- a new SeaBIOS-hppa version 18, which includes those fixes and enhancements:
  - Fix IRT table entries to use slot number
  - Increase PCI alignment for memory bars to 64k
  - Fix PDC_CACHE/PDC_CACHE_RET_SPID return value
  - Allow up to 256 GB RAM on 64-bit machines

V2:
- fix linux-user build by adding missing "#ifndef CONFIG_USER_ONLY ... #endif"

# -----BEGIN PGP SIGNATURE-----
#
# iHUEABYKAB0WIQS86RI+GtKfB8BJu973ErUQojoPXwUCZ5yWTwAKCRD3ErUQojoP
# X1p5AP4iSfKlBsUZrww2/M1ArqB9jZuJBO1kdZ7OcCN2Jn0yxgEAx0CPUof7NnZV
# EY7u3Qq4E8ZnOk4XgHt06bsdNcJN+gc=
# =RoAh
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 31 Jan 2025 04:22:23 EST
# gpg:                using EDDSA key BCE9123E1AD29F07C049BBDEF712B510A23A0F5F
# gpg: Good signature from "Helge Deller <deller@gmx.de>" [unknown]
# gpg:                 aka "Helge Deller <deller@kernel.org>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 4544 8228 2CD9 10DB EF3D  25F8 3E5F 3D04 A7A2 4603
#      Subkey fingerprint: BCE9 123E 1AD2 9F07 C049  BBDE F712 B510 A23A 0F5F

* tag 'hppa-system-mfdiag-for-v10-pull-request' of https://github.com/hdeller/qemu-hppa:
  target/hppa: Update SeaBIOS-hppa to version 18
  target/hppa: Implement space register hashing for 64-bit HP-UX
  target/hppa: 64-bit CPUs start with space register hashing enabled
  target/hppa: Add instruction decoding for mfdiag and mtdiag
  target/hppa: Drop diag_getshadowregs_pa2 and diag_putshadowregs_pa2
  target/hppa: Add CPU diagnose registers
  disas/hppa: implement mfdiag/mtdiag disassembly
  hppa: Sync contents of hppa_hardware.h header file with SeaBIOS-hppa
  MAINTAINERS: Add myself as HPPA maintainer

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi 2025-02-02 11:08:48 -05:00
commit 4d93b13910
16 changed files with 150 additions and 43 deletions

View File

@ -251,6 +251,7 @@ F: target/hexagon/gen_idef_parser_funcs.py
HPPA (PA-RISC) TCG CPUs
M: Richard Henderson <richard.henderson@linaro.org>
M: Helge Deller <deller@gmx.de>
S: Maintained
F: target/hppa/
F: disas/hppa.c
@ -1189,8 +1190,8 @@ HP-PARISC Machines
------------------
HP B160L, HP C3700
M: Richard Henderson <richard.henderson@linaro.org>
R: Helge Deller <deller@gmx.de>
S: Odd Fixes
M: Helge Deller <deller@gmx.de>
S: Maintained
F: configs/devices/hppa-softmmu/default.mak
F: hw/display/artist.c
F: hw/hppa/

View File

@ -606,7 +606,7 @@ struct pa_opcode
In the args field, the following characters are unused:
' " - / 34 6789:; '
' " - / 34 678 :; '
'@ C M [\] '
'` e g } '
@ -650,6 +650,7 @@ Also these:
| 6 bit field length at 19,27:31 (fixed extract/deposit)
A 13 bit immediate at 18 (to support the BREAK instruction)
^ like b, but describes a control register
9 like b, but describes a diagnose register
! sar (cr11) register
D 26 bit immediate at 31 (to support the DIAG instruction)
$ 9 bit immediate at 28 (to support POPBTS)
@ -1322,13 +1323,19 @@ static const struct pa_opcode pa_opcodes[] =
{ "fdce", 0x040012c0, 0xfc00ffdf, "cZx(b)", pa10, 0},
{ "fdce", 0x040012c0, 0xfc003fdf, "cZx(s,b)", pa10, 0},
{ "fice", 0x040002c0, 0xfc001fdf, "cZx(S,b)", pa10, 0},
{ "diag", 0x14000000, 0xfc000000, "D", pa10, 0},
{ "idtlbt", 0x04001800, 0xfc00ffff, "x,b", pa20, FLAG_STRICT},
{ "iitlbt", 0x04000800, 0xfc00ffff, "x,b", pa20, FLAG_STRICT},
/* completely undocumented, but used by ODE, HP-UX and Linux: */
{ "mfcpu_pcxu", 0x140008a0, 0xfc9fffe0, "9,t", pa20, 0}, /* PCXU: mfdiag */
{ "mtcpu_pcxu", 0x14001840, 0xfc00ffff, "x,9", pa20, 0},
/* These may be specific to certain versions of the PA. Joel claimed
they were 72000 (7200?) specific. However, I'm almost certain the
mtcpu/mfcpu were undocumented, but available in the older 700 machines. */
{ "mfcpu_c", 0x14000600, 0xfc00ffff, "9,x", pa10, 0}, /* PCXL: for dr0 and dr8 only */
{ "mfcpu_t", 0x14001400, 0xfc9fffe0, "9,t", pa10, 0}, /* PCXL: all dr except dr0 and dr8 */
{ "mtcpu_pcxl", 0x14000240, 0xfc00ffff, "x,9", pa11, 0}, /* PCXL: mtcpu for dr0 and dr8 */
{ "mtcpu", 0x14001600, 0xfc00ffff, "x,^", pa10, 0},
{ "mfcpu", 0x14001A00, 0xfc00ffff, "^,x", pa10, 0},
{ "tocen", 0x14403600, 0xffffffff, "", pa10, 0},
@ -1336,6 +1343,9 @@ static const struct pa_opcode pa_opcodes[] =
{ "shdwgr", 0x14402600, 0xffffffff, "", pa10, 0},
{ "grshdw", 0x14400620, 0xffffffff, "", pa10, 0},
/* instead of showing D only, show all other registers too */
{ "diag", 0x14000000, 0xfc000000, "D x,9,t", pa10, 0},
/* gfw and gfr are not in the HP PA 1.1 manual, but they are in either
the Timex FPU or the Mustang ERS (not sure which) manual. */
{ "gfw", 0x04001680, 0xfc00ffdf, "cZx(b)", pa11, 0},
@ -1801,6 +1811,12 @@ fput_creg (unsigned reg, disassemble_info *info)
(*info->fprintf_func) (info->stream, "%s", control_reg[reg]);
}
static void
fput_dreg (unsigned reg, disassemble_info *info)
{
(*info->fprintf_func) (info->stream, "dr%d", reg);
}
/* Print constants with sign. */
static void
@ -2007,6 +2023,9 @@ print_insn_hppa (bfd_vma memaddr, disassemble_info *info)
case '^':
fput_creg (GET_FIELD (insn, 6, 10), info);
break;
case '9':
fput_dreg (GET_FIELD (insn, 6, 10), info);
break;
case 't':
fput_reg (GET_FIELD (insn, 27, 31), info);
break;

View File

@ -6,6 +6,11 @@
#define FIRMWARE_START 0xf0000000
#define FIRMWARE_END 0xf0800000
#define FIRMWARE_HIGH 0xfffffff0 /* upper 32-bits of 64-bit firmware address */
#define RAM_MAP_HIGH 0x0100000000 /* memory above 3.75 GB is mapped here */
#define MEM_PDC_ENTRY 0x4800 /* PDC entry address */
#define DEVICE_HPA_LEN 0x00100000
@ -18,6 +23,7 @@
#define LASI_UART_HPA 0xffd05000
#define LASI_SCSI_HPA 0xffd06000
#define LASI_LAN_HPA 0xffd07000
#define LASI_RTC_HPA 0xffd09000
#define LASI_LPT_HPA 0xffd02000
#define LASI_AUDIO_HPA 0xffd04000
#define LASI_PS2KBD_HPA 0xffd08000
@ -27,16 +33,23 @@
#define CPU_HPA 0xfffb0000
#define MEMORY_HPA 0xfffff000
#define PCI_HPA DINO_HPA /* PCI bus */
#define IDE_HPA 0xf9000000 /* Boot disc controller */
#define ASTRO_HPA 0xfed00000
#define ELROY0_HPA 0xfed30000
#define ELROY2_HPA 0xfed32000
#define ELROY8_HPA 0xfed38000
#define ELROYc_HPA 0xfed3c000
#define ASTRO_MEMORY_HPA 0xfed10200
#define SCSI_HPA 0xf1040000 /* emulated SCSI, needs to be in f region */
/* offsets to DINO HPA: */
#define DINO_PCI_ADDR 0x064
#define DINO_CONFIG_DATA 0x068
#define DINO_IO_DATA 0x06c
#define PORT_PCI_CMD (PCI_HPA + DINO_PCI_ADDR)
#define PORT_PCI_DATA (PCI_HPA + DINO_CONFIG_DATA)
#define PORT_PCI_CMD hppa_port_pci_cmd
#define PORT_PCI_DATA hppa_port_pci_data
#define FW_CFG_IO_BASE 0xfffa0000
@ -46,9 +59,24 @@
#define HPPA_MAX_CPUS 16 /* max. number of SMP CPUs */
#define CPU_CLOCK_MHZ 250 /* emulate a 250 MHz CPU */
#define CR_PSW_DEFAULT 6 /* used by SeaBIOS & QEMU for default PSW */
#define CPU_HPA_CR_REG 7 /* store CPU HPA in cr7 (SeaBIOS internal) */
#define PIM_STORAGE_SIZE 600 /* storage size of pdc_pim_toc_struct (64bit) */
#define RAM_MAP_HIGH 0x0100000000 /* memory above 3.75 GB is mapped here */
#define ASTRO_BUS_MODULE 0x0a /* C3700: 0x0a, others maybe 0 ? */
/* ASTRO Memory and I/O regions */
#define ASTRO_BASE_HPA 0xfffed00000
#define ELROY0_BASE_HPA 0xfffed30000 /* ELROY0_HPA */
#define ROPES_PER_IOC 8 /* per Ike half or Pluto/Astro */
#define LMMIO_DIRECT0_BASE 0x300
#define LMMIO_DIRECT0_MASK 0x308
#define LMMIO_DIRECT0_ROUTE 0x310
/* space register hashing */
#define HPPA64_DIAG_SPHASH_ENABLE 0x200 /* DIAG_SPHASH_ENAB (bit 54) */
#define HPPA64_PDC_CACHE_RET_SPID_VAL 0xfe0 /* PDC return value on 64-bit CPU */
#endif

BIN
pc-bios/hppa-firmware.img Normal file → Executable file

Binary file not shown.

BIN
pc-bios/hppa-firmware64.img Normal file → Executable file

Binary file not shown.

@ -1 +1 @@
Subproject commit a528f01d7abd511d3cc71b7acaab6e036ee524bd
Subproject commit 1c516b481339f511d83a4afba9a48d1ac904e93e

View File

@ -28,6 +28,7 @@
#include "exec/translation-block.h"
#include "fpu/softfloat.h"
#include "tcg/tcg.h"
#include "hw/hppa/hppa_hardware.h"
static void hppa_cpu_set_pc(CPUState *cs, vaddr value)
{
@ -44,8 +45,9 @@ static vaddr hppa_cpu_get_pc(CPUState *cs)
{
CPUHPPAState *env = cpu_env(cs);
return hppa_form_gva_psw(env->psw, (env->psw & PSW_C ? env->iasq_f : 0),
env->iaoq_f & -4);
return hppa_form_gva_mask(env->gva_offset_mask,
(env->psw & PSW_C ? env->iasq_f : 0),
env->iaoq_f & -4);
}
void cpu_get_tb_cpu_state(CPUHPPAState *env, vaddr *pc,
@ -90,6 +92,10 @@ void cpu_get_tb_cpu_state(CPUHPPAState *env, vaddr *pc,
& (env->sr[4] == env->sr[7])) {
flags |= TB_FLAG_SR_SAME;
}
if ((env->psw & PSW_W) &&
(env->dr[2] & HPPA64_DIAG_SPHASH_ENABLE)) {
flags |= TB_FLAG_SPHASH;
}
#endif
*pcsbase = cs_base;
@ -217,6 +223,10 @@ static void hppa_cpu_reset_hold(Object *obj, ResetType type)
memset(env, 0, offsetof(CPUHPPAState, end_reset_fields));
cpu_hppa_loaded_fr0(env);
/* 64-bit machines start with space-register hashing enabled in %dr2 */
env->dr[2] = hppa_is_pa20(env) ? HPPA64_DIAG_SPHASH_ENABLE : 0;
cpu_hppa_put_psw(env, PSW_M);
}

View File

@ -223,6 +223,7 @@ typedef struct CPUArchState {
target_ulong psw_cb; /* in least significant bit of next nibble */
target_ulong psw_cb_msb; /* boolean */
uint64_t gva_offset_mask; /* cached address mask based on PSW and %dr2 */
uint64_t iasq_f;
uint64_t iasq_b;
@ -232,6 +233,7 @@ typedef struct CPUArchState {
target_ulong cr[32]; /* control registers */
target_ulong cr_back[2]; /* back of cr17/cr18 */
target_ulong shadow[7]; /* shadow registers */
target_ulong dr[32]; /* diagnose registers */
/*
* During unwind of a memory insn, the base register of the address.
@ -319,27 +321,20 @@ void hppa_translate_code(CPUState *cs, TranslationBlock *tb,
#define CPU_RESOLVING_TYPE TYPE_HPPA_CPU
static inline uint64_t gva_offset_mask(target_ulong psw)
{
return (psw & PSW_W
? MAKE_64BIT_MASK(0, 62)
: MAKE_64BIT_MASK(0, 32));
}
static inline target_ulong hppa_form_gva_psw(target_ulong psw, uint64_t spc,
target_ulong off)
static inline target_ulong hppa_form_gva_mask(uint64_t gva_offset_mask,
uint64_t spc, target_ulong off)
{
#ifdef CONFIG_USER_ONLY
return off & gva_offset_mask(psw);
return off & gva_offset_mask;
#else
return spc | (off & gva_offset_mask(psw));
return spc | (off & gva_offset_mask);
#endif
}
static inline target_ulong hppa_form_gva(CPUHPPAState *env, uint64_t spc,
target_ulong off)
{
return hppa_form_gva_psw(env->psw, spc, off);
return hppa_form_gva_mask(env->gva_offset_mask, spc, off);
}
hwaddr hppa_abs_to_phys_pa2_w0(vaddr addr);
@ -353,6 +348,7 @@ hwaddr hppa_abs_to_phys_pa2_w1(vaddr addr);
#define TB_FLAG_SR_SAME PSW_I
#define TB_FLAG_PRIV_SHIFT 8
#define TB_FLAG_UNALIGN 0x400
#define TB_FLAG_SPHASH 0x800
#define CS_BASE_DIFFPAGE (1 << 12)
#define CS_BASE_DIFFSPACE (1 << 13)
@ -361,6 +357,7 @@ void cpu_get_tb_cpu_state(CPUHPPAState *env, vaddr *pc,
target_ulong cpu_hppa_get_psw(CPUHPPAState *env);
void cpu_hppa_put_psw(CPUHPPAState *env, target_ulong);
void update_gva_offset_mask(CPUHPPAState *env);
void cpu_hppa_loaded_fr0(CPUHPPAState *env);
#ifdef CONFIG_USER_ONLY

View File

@ -24,6 +24,7 @@
#include "exec/exec-all.h"
#include "exec/helper-proto.h"
#include "qemu/qemu-print.h"
#include "hw/hppa/hppa_hardware.h"
target_ulong cpu_hppa_get_psw(CPUHPPAState *env)
{
@ -59,6 +60,22 @@ target_ulong cpu_hppa_get_psw(CPUHPPAState *env)
return psw;
}
void update_gva_offset_mask(CPUHPPAState *env)
{
uint64_t gom;
if (env->psw & PSW_W) {
gom = (env->dr[2] & HPPA64_DIAG_SPHASH_ENABLE)
? MAKE_64BIT_MASK(0, 62) &
~((uint64_t)HPPA64_PDC_CACHE_RET_SPID_VAL << 48)
: MAKE_64BIT_MASK(0, 62);
} else {
gom = MAKE_64BIT_MASK(0, 32);
}
env->gva_offset_mask = gom;
}
void cpu_hppa_put_psw(CPUHPPAState *env, target_ulong psw)
{
uint64_t reserved;
@ -98,6 +115,8 @@ void cpu_hppa_put_psw(CPUHPPAState *env, target_ulong psw)
cb |= ((psw >> 9) & 1) << 8;
cb |= ((psw >> 8) & 1) << 4;
env->psw_cb = cb;
update_gva_offset_mask(env);
}
void hppa_cpu_dump_state(CPUState *cs, FILE *f, int flags)
@ -133,9 +152,11 @@ void hppa_cpu_dump_state(CPUState *cs, FILE *f, int flags)
qemu_fprintf(f, "IA_F %08" PRIx64 ":%0*" PRIx64 " (" TARGET_FMT_lx ")\n"
"IA_B %08" PRIx64 ":%0*" PRIx64 " (" TARGET_FMT_lx ")\n",
env->iasq_f >> 32, w, m & env->iaoq_f,
hppa_form_gva_psw(psw, env->iasq_f, env->iaoq_f),
hppa_form_gva_mask(env->gva_offset_mask, env->iasq_f,
env->iaoq_f),
env->iasq_b >> 32, w, m & env->iaoq_b,
hppa_form_gva_psw(psw, env->iasq_b, env->iaoq_b));
hppa_form_gva_mask(env->gva_offset_mask, env->iasq_b,
env->iaoq_b));
psw_c[0] = (psw & PSW_W ? 'W' : '-');
psw_c[1] = (psw & PSW_E ? 'E' : '-');

View File

@ -99,6 +99,7 @@ DEF_HELPER_FLAGS_2(ptlb_l, TCG_CALL_NO_RWG, void, env, tl)
DEF_HELPER_FLAGS_1(ptlbe, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_FLAGS_2(lpa, TCG_CALL_NO_WG, tl, env, tl)
DEF_HELPER_FLAGS_1(change_prot_id, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_FLAGS_1(update_gva_offset_mask, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_1(diag_btlb, void, env)
DEF_HELPER_1(diag_console_output, void, env)
#endif

View File

@ -644,10 +644,12 @@ xmpyu 001110 ..... ..... 010 .0111 .00 t:5 r1=%ra64 r2=%rb64
# For 32-bit PA-7300LC (PCX-L2)
diag_getshadowregs_pa1 000101 00 0000 0000 0001 1010 0000 0000
diag_putshadowregs_pa1 000101 00 0000 0000 0001 1010 0100 0000
diag_mfdiag 000101 dr:5 rt:5 0000 0110 0000 0000
diag_mtdiag 000101 dr:5 r1:5 0001 0110 0000 0000
# For 64-bit PA8700 (PCX-W2)
diag_getshadowregs_pa2 000101 00 0111 1000 0001 1000 0100 0000
diag_putshadowregs_pa2 000101 00 0111 0000 0001 1000 0100 0000
diag_mfdiag 000101 dr:5 0 0000 0000 1000 101 rt:5
diag_mtdiag 000101 dr:5 r1:5 0001 1000 0100 0000
]
diag_unimp 000101 i:26
}

View File

@ -94,11 +94,12 @@ void hppa_cpu_do_interrupt(CPUState *cs)
HPPACPU *cpu = HPPA_CPU(cs);
CPUHPPAState *env = &cpu->env;
int i = cs->exception_index;
uint64_t old_psw;
uint64_t old_psw, old_gva_offset_mask;
/* As documented in pa2.0 -- interruption handling. */
/* step 1 */
env->cr[CR_IPSW] = old_psw = cpu_hppa_get_psw(env);
old_gva_offset_mask = env->gva_offset_mask;
/* step 2 -- Note PSW_W is masked out again for pa1.x */
cpu_hppa_put_psw(env,
@ -112,9 +113,9 @@ void hppa_cpu_do_interrupt(CPUState *cs)
*/
if (old_psw & PSW_C) {
env->cr[CR_IIASQ] =
hppa_form_gva_psw(old_psw, env->iasq_f, env->iaoq_f) >> 32;
hppa_form_gva_mask(old_gva_offset_mask, env->iasq_f, env->iaoq_f) >> 32;
env->cr_back[0] =
hppa_form_gva_psw(old_psw, env->iasq_b, env->iaoq_b) >> 32;
hppa_form_gva_mask(old_gva_offset_mask, env->iasq_b, env->iaoq_b) >> 32;
} else {
env->cr[CR_IIASQ] = 0;
env->cr_back[0] = 0;
@ -165,7 +166,8 @@ void hppa_cpu_do_interrupt(CPUState *cs)
if (old_psw & PSW_C) {
int prot, t;
vaddr = hppa_form_gva_psw(old_psw, env->iasq_f, vaddr);
vaddr = hppa_form_gva_mask(old_gva_offset_mask,
env->iasq_f, vaddr);
t = hppa_get_physical_address(env, vaddr, MMU_KERNEL_IDX,
0, 0, &paddr, &prot);
if (t >= 0) {

View File

@ -198,6 +198,7 @@ static const VMStateField vmstate_env_fields[] = {
VMSTATE_UINT64(iasq_b, CPUHPPAState),
VMSTATE_UINT32(fr0_shadow, CPUHPPAState),
VMSTATE_UINT64_ARRAY(dr, CPUHPPAState, 32),
VMSTATE_END_OF_LIST()
};
@ -208,8 +209,8 @@ static const VMStateDescription * const vmstate_env_subsections[] = {
static const VMStateDescription vmstate_env = {
.name = "env",
.version_id = 3,
.minimum_version_id = 3,
.version_id = 4,
.minimum_version_id = 4,
.fields = vmstate_env_fields,
.subsections = vmstate_env_subsections,
};

View File

@ -824,3 +824,8 @@ uint64_t HELPER(b_gate_priv)(CPUHPPAState *env, uint64_t iaoq_f)
}
return iaoq_f;
}
void HELPER(update_gva_offset_mask)(CPUHPPAState *env)
{
update_gva_offset_mask(env);
}

View File

@ -73,7 +73,7 @@ target_ulong HELPER(swap_system_mask)(CPUHPPAState *env, target_ulong nsm)
* machines set the Q bit from 0 to 1 without an exception,
* so let this go without comment.
*/
env->psw = (psw & ~PSW_SM) | (nsm & PSW_SM);
cpu_hppa_put_psw(env, (psw & ~PSW_SM) | (nsm & PSW_SM));
return psw & PSW_SM;
}
@ -88,7 +88,7 @@ void HELPER(rfi)(CPUHPPAState *env)
* To recreate the space identifier, remove the offset bits.
* For pa1.x, the mask reduces to no change to space.
*/
mask = gva_offset_mask(env->psw);
mask = env->gva_offset_mask;
env->iaoq_f = env->cr[CR_IIAOQ];
env->iaoq_b = env->cr_back[1];

View File

@ -73,6 +73,7 @@ typedef struct DisasContext {
/* IAOQ_Front at entry to TB. */
uint64_t iaoq_first;
uint64_t gva_offset_mask;
DisasCond null_cond;
TCGLabel *null_lab;
@ -1577,7 +1578,7 @@ static void form_gva(DisasContext *ctx, TCGv_i64 *pgva, TCGv_i64 *pofs,
*pofs = ofs;
*pgva = addr = tcg_temp_new_i64();
tcg_gen_andi_i64(addr, modify <= 0 ? ofs : base,
gva_offset_mask(ctx->tb_flags));
ctx->gva_offset_mask);
#ifndef CONFIG_USER_ONLY
if (!is_phys) {
tcg_gen_or_i64(addr, addr, space_select(ctx, sp, base));
@ -4593,19 +4594,37 @@ static bool trans_diag_getshadowregs_pa1(DisasContext *ctx, arg_empty *a)
return !ctx->is_pa20 && do_getshadowregs(ctx);
}
static bool trans_diag_getshadowregs_pa2(DisasContext *ctx, arg_empty *a)
{
return ctx->is_pa20 && do_getshadowregs(ctx);
}
static bool trans_diag_putshadowregs_pa1(DisasContext *ctx, arg_empty *a)
{
return !ctx->is_pa20 && do_putshadowregs(ctx);
}
static bool trans_diag_putshadowregs_pa2(DisasContext *ctx, arg_empty *a)
static bool trans_diag_mfdiag(DisasContext *ctx, arg_diag_mfdiag *a)
{
return ctx->is_pa20 && do_putshadowregs(ctx);
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
nullify_over(ctx);
TCGv_i64 dest = dest_gpr(ctx, a->rt);
tcg_gen_ld_i64(dest, tcg_env,
offsetof(CPUHPPAState, dr[a->dr]));
save_gpr(ctx, a->rt, dest);
return nullify_end(ctx);
}
static bool trans_diag_mtdiag(DisasContext *ctx, arg_diag_mtdiag *a)
{
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
nullify_over(ctx);
tcg_gen_st_i64(load_gpr(ctx, a->r1), tcg_env,
offsetof(CPUHPPAState, dr[a->dr]));
#ifndef CONFIG_USER_ONLY
if (ctx->is_pa20 && (a->dr == 2)) {
/* Update gva_offset_mask from the new value of %dr2 */
gen_helper_update_gva_offset_mask(tcg_env);
/* Exit to capture the new value for the next TB. */
ctx->base.is_jmp = DISAS_IAQ_N_STALE_EXIT;
}
#endif
return nullify_end(ctx);
}
static bool trans_diag_unimp(DisasContext *ctx, arg_diag_unimp *a)
@ -4625,6 +4644,7 @@ static void hppa_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
ctx->tb_flags = ctx->base.tb->flags;
ctx->is_pa20 = hppa_is_pa20(cpu_env(cs));
ctx->psw_xb = ctx->tb_flags & (PSW_X | PSW_B);
ctx->gva_offset_mask = cpu_env(cs)->gva_offset_mask;
#ifdef CONFIG_USER_ONLY
ctx->privilege = PRIV_USER;