aboutsummaryrefslogtreecommitdiff
path: root/hw/ppc
diff options
context:
space:
mode:
Diffstat (limited to 'hw/ppc')
-rw-r--r--hw/ppc/amigaone.c16
-rw-r--r--hw/ppc/pnv.c2
-rw-r--r--hw/ppc/pnv_bmc.c4
-rw-r--r--hw/ppc/pnv_core.c6
-rw-r--r--hw/ppc/pnv_occ.c201
-rw-r--r--hw/ppc/pnv_pnor.c2
-rw-r--r--hw/ppc/spapr.c2
-rw-r--r--hw/ppc/spapr_cpu_core.c6
-rw-r--r--hw/ppc/spapr_rtas.c5
9 files changed, 127 insertions, 117 deletions
diff --git a/hw/ppc/amigaone.c b/hw/ppc/amigaone.c
index 4835121..e9407a5 100644
--- a/hw/ppc/amigaone.c
+++ b/hw/ppc/amigaone.c
@@ -63,7 +63,7 @@ static const char dummy_fw[] = {
#define NVRAM_ADDR 0xfd0e0000
#define NVRAM_SIZE (4 * KiB)
-static char default_env[] =
+static const char default_env[] =
"baudrate=115200\0"
"stdout=vga\0"
"stdin=ps2kbd\0"
@@ -108,8 +108,8 @@ static void nvram_write(void *opaque, hwaddr addr, uint64_t val,
uint8_t *p = memory_region_get_ram_ptr(&s->mr);
p[addr] = val;
- if (s->blk) {
- blk_pwrite(s->blk, addr, 1, &val, 0);
+ if (s->blk && blk_pwrite(s->blk, addr, 1, &val, 0) < 0) {
+ error_report("%s: could not write %s", __func__, blk_name(s->blk));
}
}
@@ -151,15 +151,17 @@ static void nvram_realize(DeviceState *dev, Error **errp)
*c = cpu_to_be32(CRC32_DEFAULT_ENV);
/* Also copies terminating \0 as env is terminated by \0\0 */
memcpy(p + 4, default_env, sizeof(default_env));
- if (s->blk) {
- blk_pwrite(s->blk, 0, sizeof(crc) + sizeof(default_env), p, 0);
+ if (s->blk &&
+ blk_pwrite(s->blk, 0, sizeof(crc) + sizeof(default_env), p, 0) < 0
+ ) {
+ error_report("%s: could not write %s", __func__, blk_name(s->blk));
}
return;
}
if (*c == 0) {
*c = cpu_to_be32(crc32(0, p + 4, NVRAM_SIZE - 4));
- if (s->blk) {
- blk_pwrite(s->blk, 0, 4, p, 0);
+ if (s->blk && blk_pwrite(s->blk, 0, 4, p, 0) < 0) {
+ error_report("%s: could not write %s", __func__, blk_name(s->blk));
}
}
if (be32_to_cpu(*c) != crc) {
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 5936537..63f2232 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1191,7 +1191,7 @@ static void pnv_init(MachineState *machine)
* Since we can not reach the remote BMC machine with LPC memops,
* map it always for now.
*/
- memory_region_add_subregion(pnv->chips[0]->fw_mr, PNOR_SPI_OFFSET,
+ memory_region_add_subregion(pnv->chips[0]->fw_mr, pnv->pnor->lpc_address,
&pnv->pnor->mmio);
/*
diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c
index 811ba3d..fb70a8c 100644
--- a/hw/ppc/pnv_bmc.c
+++ b/hw/ppc/pnv_bmc.c
@@ -174,8 +174,8 @@ static void hiomap_cmd(IPMIBmcSim *ibs, uint8_t *cmd, unsigned int cmd_len,
{
PnvPnor *pnor = PNV_PNOR(object_property_get_link(OBJECT(ibs), "pnor",
&error_abort));
+ uint32_t pnor_addr = pnor->lpc_address;
uint32_t pnor_size = pnor->size;
- uint32_t pnor_addr = PNOR_SPI_OFFSET;
bool readonly = false;
rsp_buffer_push(rsp, cmd[2]);
@@ -251,8 +251,8 @@ static const IPMINetfn hiomap_netfn = {
void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor)
{
+ uint32_t pnor_addr = pnor->lpc_address;
uint32_t pnor_size = pnor->size;
- uint32_t pnor_addr = PNOR_SPI_OFFSET;
if (!pnv_bmc_is_simulator(bmc)) {
return;
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 99d9644..a33977d 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -248,21 +248,25 @@ static void pnv_core_power10_xscom_write(void *opaque, hwaddr addr,
if (val & PPC_BIT(7 + 8 * i)) { /* stop */
val &= ~PPC_BIT(7 + 8 * i);
- cpu_pause(cs);
env->quiesced = true;
+ ppc_maybe_interrupt(env);
+ cpu_pause(cs);
}
if (val & PPC_BIT(6 + 8 * i)) { /* start */
val &= ~PPC_BIT(6 + 8 * i);
env->quiesced = false;
+ ppc_maybe_interrupt(env);
cpu_resume(cs);
}
if (val & PPC_BIT(4 + 8 * i)) { /* sreset */
val &= ~PPC_BIT(4 + 8 * i);
env->quiesced = false;
+ ppc_maybe_interrupt(env);
pnv_cpu_do_nmi_resume(cs);
}
if (val & PPC_BIT(3 + 8 * i)) { /* clear maint */
env->quiesced = false;
+ ppc_maybe_interrupt(env);
/*
* Hardware has very particular cases for where clear maint
* must be used and where start must be used to resume a
diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c
index bda6b23..177c5e5 100644
--- a/hw/ppc/pnv_occ.c
+++ b/hw/ppc/pnv_occ.c
@@ -364,7 +364,12 @@ static void pnv_occ_register_types(void)
type_init(pnv_occ_register_types);
-/* From skiboot/hw/occ.c with tab to space conversion */
+/*
+ * From skiboot/hw/occ.c with following changes:
+ * - tab to space conversion
+ * - Type conversions u8->uint8_t s8->int8_t __be16->uint16_t etc
+ * - __packed -> QEMU_PACKED
+ */
/* OCC Communication Area for PStates */
#define OPAL_DYNAMIC_DATA_OFFSET 0x0B80
@@ -384,20 +389,6 @@ type_init(pnv_occ_register_types);
#define FREQ_MAX_IN_DOMAIN 0
#define FREQ_MOST_RECENTLY_SET 1
-#define u8 uint8_t
-#define s8 int8_t
-#define u16 uint16_t
-#define s16 int16_t
-#define u32 uint32_t
-#define s32 int32_t
-#define u64 uint64_t
-#define s64 int64_t
-#define __be16 uint16_t
-#define __be32 uint32_t
-#ifndef __packed
-#define __packed QEMU_PACKED
-#endif /* !__packed */
-
/**
* OCC-OPAL Shared Memory Region
*
@@ -434,69 +425,69 @@ type_init(pnv_occ_register_types);
* @spare/reserved/pad: Unused data
*/
struct occ_pstate_table {
- u8 valid;
- u8 version;
- union __packed {
- struct __packed { /* Version 0x01 and 0x02 */
- u8 throttle;
- s8 pstate_min;
- s8 pstate_nom;
- s8 pstate_turbo;
- s8 pstate_ultra_turbo;
- u8 spare;
- u64 reserved;
- struct __packed {
- s8 id;
- u8 flags;
- u8 vdd;
- u8 vcs;
- __be32 freq_khz;
+ uint8_t valid;
+ uint8_t version;
+ union QEMU_PACKED {
+ struct QEMU_PACKED { /* Version 0x01 and 0x02 */
+ uint8_t throttle;
+ int8_t pstate_min;
+ int8_t pstate_nom;
+ int8_t pstate_turbo;
+ int8_t pstate_ultra_turbo;
+ uint8_t spare;
+ uint64_t reserved;
+ struct QEMU_PACKED {
+ int8_t id;
+ uint8_t flags;
+ uint8_t vdd;
+ uint8_t vcs;
+ uint32_t freq_khz;
} pstates[MAX_PSTATES];
- s8 core_max[MAX_P8_CORES];
- u8 pad[100];
+ int8_t core_max[MAX_P8_CORES];
+ uint8_t pad[100];
} v2;
- struct __packed { /* Version 0x90 */
- u8 occ_role;
- u8 pstate_min;
- u8 pstate_nom;
- u8 pstate_turbo;
- u8 pstate_ultra_turbo;
- u8 spare;
- u64 reserved1;
- u64 reserved2;
- struct __packed {
- u8 id;
- u8 flags;
- u16 reserved;
- __be32 freq_khz;
+ struct QEMU_PACKED { /* Version 0x90 */
+ uint8_t occ_role;
+ uint8_t pstate_min;
+ uint8_t pstate_nom;
+ uint8_t pstate_turbo;
+ uint8_t pstate_ultra_turbo;
+ uint8_t spare;
+ uint64_t reserved1;
+ uint64_t reserved2;
+ struct QEMU_PACKED {
+ uint8_t id;
+ uint8_t flags;
+ uint16_t reserved;
+ uint32_t freq_khz;
} pstates[MAX_PSTATES];
- u8 core_max[MAX_P9_CORES];
- u8 pad[56];
+ uint8_t core_max[MAX_P9_CORES];
+ uint8_t pad[56];
} v9;
- struct __packed { /* Version 0xA0 */
- u8 occ_role;
- u8 pstate_min;
- u8 pstate_fixed_freq;
- u8 pstate_base;
- u8 pstate_ultra_turbo;
- u8 pstate_fmax;
- u8 minor;
- u8 pstate_bottom_throttle;
- u8 spare;
- u8 spare1;
- u32 reserved_32;
- u64 reserved_64;
- struct __packed {
- u8 id;
- u8 valid;
- u16 reserved;
- __be32 freq_khz;
+ struct QEMU_PACKED { /* Version 0xA0 */
+ uint8_t occ_role;
+ uint8_t pstate_min;
+ uint8_t pstate_fixed_freq;
+ uint8_t pstate_base;
+ uint8_t pstate_ultra_turbo;
+ uint8_t pstate_fmax;
+ uint8_t minor;
+ uint8_t pstate_bottom_throttle;
+ uint8_t spare;
+ uint8_t spare1;
+ uint32_t reserved_32;
+ uint64_t reserved_64;
+ struct QEMU_PACKED {
+ uint8_t id;
+ uint8_t valid;
+ uint16_t reserved;
+ uint32_t freq_khz;
} pstates[MAX_PSTATES];
- u8 core_max[MAX_P10_CORES];
- u8 pad[48];
+ uint8_t core_max[MAX_P10_CORES];
+ uint8_t pad[48];
} v10;
};
-} __packed;
+} QEMU_PACKED;
/**
* OPAL-OCC Command Response Interface
@@ -531,13 +522,13 @@ struct occ_pstate_table {
* @spare: Unused byte
*/
struct opal_command_buffer {
- u8 flag;
- u8 request_id;
- u8 cmd;
- u8 spare;
- __be16 data_size;
- u8 data[MAX_OPAL_CMD_DATA_LENGTH];
-} __packed;
+ uint8_t flag;
+ uint8_t request_id;
+ uint8_t cmd;
+ uint8_t spare;
+ uint16_t data_size;
+ uint8_t data[MAX_OPAL_CMD_DATA_LENGTH];
+} QEMU_PACKED;
/**
* OPAL-OCC Response Buffer
@@ -571,13 +562,13 @@ struct opal_command_buffer {
* @data: Response specific data
*/
struct occ_response_buffer {
- u8 flag;
- u8 request_id;
- u8 cmd;
- u8 status;
- __be16 data_size;
- u8 data[MAX_OCC_RSP_DATA_LENGTH];
-} __packed;
+ uint8_t flag;
+ uint8_t request_id;
+ uint8_t cmd;
+ uint8_t status;
+ uint16_t data_size;
+ uint8_t data[MAX_OCC_RSP_DATA_LENGTH];
+} QEMU_PACKED;
/**
* OCC-OPAL Shared Memory Interface Dynamic Data Vx90
@@ -608,31 +599,31 @@ struct occ_response_buffer {
* @rsp: OCC Response Buffer
*/
struct occ_dynamic_data {
- u8 occ_state;
- u8 major_version;
- u8 minor_version;
- u8 gpus_present;
- union __packed {
- struct __packed { /* Version 0x90 */
- u8 spare1;
+ uint8_t occ_state;
+ uint8_t major_version;
+ uint8_t minor_version;
+ uint8_t gpus_present;
+ union QEMU_PACKED {
+ struct QEMU_PACKED { /* Version 0x90 */
+ uint8_t spare1;
} v9;
- struct __packed { /* Version 0xA0 */
- u8 wof_enabled;
+ struct QEMU_PACKED { /* Version 0xA0 */
+ uint8_t wof_enabled;
} v10;
};
- u8 cpu_throttle;
- u8 mem_throttle;
- u8 quick_pwr_drop;
- u8 pwr_shifting_ratio;
- u8 pwr_cap_type;
- __be16 hard_min_pwr_cap;
- __be16 max_pwr_cap;
- __be16 cur_pwr_cap;
- __be16 soft_min_pwr_cap;
- u8 pad[110];
+ uint8_t cpu_throttle;
+ uint8_t mem_throttle;
+ uint8_t quick_pwr_drop;
+ uint8_t pwr_shifting_ratio;
+ uint8_t pwr_cap_type;
+ uint16_t hard_min_pwr_cap;
+ uint16_t max_pwr_cap;
+ uint16_t cur_pwr_cap;
+ uint16_t soft_min_pwr_cap;
+ uint8_t pad[110];
struct opal_command_buffer cmd;
struct occ_response_buffer rsp;
-} __packed;
+} QEMU_PACKED;
enum occ_response_status {
OCC_RSP_SUCCESS = 0x00,
diff --git a/hw/ppc/pnv_pnor.c b/hw/ppc/pnv_pnor.c
index 863e2e7..9db44ca 100644
--- a/hw/ppc/pnv_pnor.c
+++ b/hw/ppc/pnv_pnor.c
@@ -108,6 +108,8 @@ static void pnv_pnor_realize(DeviceState *dev, Error **errp)
memset(s->storage, 0xFF, s->size);
}
+ s->lpc_address = PNOR_SPI_OFFSET;
+
memory_region_init_io(&s->mmio, OBJECT(s), &pnv_pnor_ops, s,
TYPE_PNV_PNOR, s->size);
}
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index a415e51..b0a0f8c 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -296,6 +296,7 @@ static void spapr_dt_pa_features(SpaprMachineState *spapr,
pa_features[40 + 2] &= ~0x80; /* Radix MMU */
}
if (spapr_get_cap(spapr, SPAPR_CAP_DAWR1)) {
+ g_assert(pa_size > 66);
pa_features[66] |= 0x80;
}
@@ -4815,6 +4816,7 @@ static void spapr_machine_8_2_class_options(MachineClass *mc)
{
spapr_machine_9_0_class_options(mc);
compat_props_add(mc->compat_props, hw_compat_8_2, hw_compat_8_2_len);
+ mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power9_v2.2");
}
DEFINE_SPAPR_MACHINE(8, 2);
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 0671d9e..faf9170 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -37,6 +37,9 @@ static void spapr_reset_vcpu(PowerPCCPU *cpu)
cpu_reset(cs);
+ env->quiesced = true; /* set "RTAS stopped" state. */
+ ppc_maybe_interrupt(env);
+
/*
* "PowerPC Processor binding to IEEE 1275" defines the initial MSR state
* as 32bit (MSR_SF=0) with MSR_ME=1 and MSR_FP=1 in "8.2.1. Initial
@@ -98,6 +101,9 @@ void spapr_cpu_set_entry_state(PowerPCCPU *cpu, target_ulong nip,
CPU(cpu)->halted = 0;
/* Enable Power-saving mode Exit Cause exceptions */
ppc_store_lpcr(cpu, env->spr[SPR_LPCR] | pcc->lpcr_pm);
+
+ env->quiesced = false; /* clear "RTAS stopped" state. */
+ ppc_maybe_interrupt(env);
}
/*
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 503d441..78309db 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -110,7 +110,8 @@ static void rtas_query_cpu_stopped_state(PowerPCCPU *cpu_,
id = rtas_ld(args, 0);
cpu = spapr_find_cpu(id);
if (cpu != NULL) {
- if (CPU(cpu)->halted) {
+ CPUPPCState *env = &cpu->env;
+ if (env->quiesced) {
rtas_st(rets, 1, 0);
} else {
rtas_st(rets, 1, 2);
@@ -215,6 +216,8 @@ static void rtas_stop_self(PowerPCCPU *cpu, SpaprMachineState *spapr,
* For the same reason, set PSSCR_EC.
*/
env->spr[SPR_PSSCR] |= PSSCR_EC;
+ env->quiesced = true; /* set "RTAS stopped" state. */
+ ppc_maybe_interrupt(env);
cs->halted = 1;
ppc_store_lpcr(cpu, env->spr[SPR_LPCR] & ~pcc->lpcr_pm);
kvmppc_set_reg_ppc_online(cpu, 0);