#include "sysemu/runstate.h"
#include "sysemu/cpus.h"
#include "sysemu/device_tree.h"
+#include "sysemu/hw_accel.h"
#include "target/ppc/cpu.h"
#include "qemu/log.h"
#include "hw/ppc/fdt.h"
#include "hw/ppc/pnv.h"
#include "hw/ppc/pnv_core.h"
#include "hw/loader.h"
+#include "hw/nmi.h"
#include "exec/address-spaces.h"
#include "qapi/visitor.h"
#include "monitor/monitor.h"
}
}
+static void pnv_cpu_do_nmi_on_cpu(CPUState *cs, run_on_cpu_data arg)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+
+ cpu_synchronize_state(cs);
+ ppc_cpu_do_system_reset(cs);
+ /*
+ * SRR1[42:45] is set to 0100 which the ISA defines as implementation
+ * dependent. POWER processors use this for xscom triggered interrupts,
+ * which come from the BMC or NMI IPIs.
+ */
+ env->spr[SPR_SRR1] |= PPC_BIT(43);
+}
+
+static void pnv_nmi(NMIState *n, int cpu_index, Error **errp)
+{
+ CPUState *cs;
+
+ CPU_FOREACH(cs) {
+ async_run_on_cpu(cs, pnv_cpu_do_nmi_on_cpu, RUN_ON_CPU_NULL);
+ }
+}
+
static void pnv_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc);
+ NMIClass *nc = NMI_CLASS(oc);
mc->desc = "IBM PowerNV (Non-Virtualized)";
mc->init = pnv_init;
mc->default_ram_size = INITRD_LOAD_ADDR + INITRD_MAX_SIZE;
mc->default_ram_id = "pnv.ram";
ispc->print_info = pnv_pic_print_info;
+ nc->nmi_monitor_handler = pnv_nmi;
object_class_property_add_bool(oc, "hb-mode",
pnv_machine_get_hb, pnv_machine_set_hb,
.class_size = sizeof(PnvMachineClass),
.interfaces = (InterfaceInfo[]) {
{ TYPE_INTERRUPT_STATS_PROVIDER },
+ { TYPE_NMI },
{ },
},
},