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:
commit
4d93b13910
@ -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/
|
||||
|
23
disas/hppa.c
23
disas/hppa.c
@ -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;
|
||||
|
@ -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
BIN
pc-bios/hppa-firmware.img
Normal file → Executable file
Binary file not shown.
BIN
pc-bios/hppa-firmware64.img
Normal file → Executable file
BIN
pc-bios/hppa-firmware64.img
Normal file → Executable file
Binary file not shown.
@ -1 +1 @@
|
||||
Subproject commit a528f01d7abd511d3cc71b7acaab6e036ee524bd
|
||||
Subproject commit 1c516b481339f511d83a4afba9a48d1ac904e93e
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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' : '-');
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user