Commit a524a188c0 for qemu.org
commit a524a188c0c01cc39d4af518ee7a39addcdc1091
Author: Helge Deller <deller@gmx.de>
Date: Tue Nov 3 21:43:01 2026 +0100
target/hppa: Move emulated power button into CPU I/O region
HP-UX 9.05 crashes when trying to access the emulated power button, which
currently is located by default at the end of the ROM area. It was hackish to
put the button there, so move the virtual power button into the I/O of the
monarch CPU instead.
Noticed-by: Keith Monahan <keith@techtravels.org>
Signed-off-by: Helge Deller <deller@gmx.de>
diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index f23936fc5b..8a3f673daf 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -50,7 +50,6 @@ struct HppaMachineState {
#define MIN_SEABIOS_HPPA_VERSION 26 /* require at least this fw version */
-#define HPA_POWER_BUTTON (FIRMWARE_END - 0x10)
static hwaddr soft_power_reg;
static void hppa_powerdown_req(Notifier *n, void *opaque)
@@ -123,6 +122,7 @@ static time_t rtc_ref;
static uint64_t io_cpu_read(void *opaque, hwaddr addr, unsigned size)
{
+ HPPACPU *cpu = opaque;
uint64_t val = 0;
switch (addr) {
@@ -132,6 +132,8 @@ static uint64_t io_cpu_read(void *opaque, hwaddr addr, unsigned size)
break;
case 8: /* DebugOutputPort */
return 0xe9; /* readback */
+ case 16: /* Power switch button */
+ return cpu->env.power_btn;
}
return val;
}
@@ -139,6 +141,7 @@ static uint64_t io_cpu_read(void *opaque, hwaddr addr, unsigned size)
static void io_cpu_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
+ HPPACPU *cpu = opaque;
unsigned char ch;
Chardev *debugout;
@@ -155,6 +158,9 @@ static void io_cpu_write(void *opaque, hwaddr addr,
fprintf(stderr, "%c", ch);
}
break;
+ case 16:
+ cpu->env.power_btn = val;
+ break;
}
}
@@ -312,8 +318,6 @@ static TranslateFn *machine_HP_common_init_cpus(MachineState *machine,
ram_max = FIRMWARE_START; /* 3.75 GB (32-bit CPU) */
}
- soft_power_reg = translate(NULL, HPA_POWER_BUTTON);
-
for (unsigned int i = 0; i < smp_cpus; i++) {
g_autofree char *name = g_strdup_printf("cpu%u-io-eir", i);
g_autofree char *cflush_name = NULL;
@@ -348,10 +352,11 @@ static TranslateFn *machine_HP_common_init_cpus(MachineState *machine,
/* RTC and DebugOutputPort on CPU #0 */
cpu_region = g_new(MemoryRegion, 1);
memory_region_init_io(cpu_region, OBJECT(cpu[0]), &hppa_io_helper_ops,
- cpu[0], "cpu0-io-rtc", 2 * sizeof(uint64_t));
+ cpu[0], "cpu0-io-rtc", 3 * sizeof(uint64_t));
memory_region_add_subregion(addr_space,
translate(NULL, cpu[0]->env.cpu_hpa + 16),
cpu_region);
+ soft_power_reg = translate(NULL, cpu[0]->env.cpu_hpa + 16 + 16);
/* Main memory region. */
if (machine->ram_size > ram_max) {
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 7b708a564b..22f8a1727d 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -269,6 +269,8 @@ typedef struct CPUArchState {
HPPATLBEntry tlb[HPPA_TLB_ENTRIES];
+ target_ulong power_btn; /* virtual power button (0 = reboot) */
+
/* Fields up to this point are cleared by a CPU reset */
struct {} end_reset_fields;