[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 1/2] spapr: Add NMI interface
From: |
Alexey Kardashevskiy |
Subject: |
[Qemu-devel] [PATCH 1/2] spapr: Add NMI interface |
Date: |
Thu, 27 Mar 2014 13:21:19 +1100 |
This introduces an NMI (non maskable interrupt) interface which
QMP's "nmi" command may use to issue NMI on a CPU. A machine class
is expected to implement it.
This adds a helper to obtain the interface pointer and call
the deliver_nmi handler.
Signed-off-by: Alexey Kardashevskiy <address@hidden>
---
cpus.c | 7 ++++++-
hmp-commands.hx | 4 +---
hw/core/Makefile.objs | 1 +
hw/core/nmi.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
include/hw/nmi.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 106 insertions(+), 4 deletions(-)
create mode 100644 hw/core/nmi.c
create mode 100644 include/hw/nmi.h
diff --git a/cpus.c b/cpus.c
index 1104d61..c5cab31 100644
--- a/cpus.c
+++ b/cpus.c
@@ -38,6 +38,7 @@
#include "qemu/main-loop.h"
#include "qemu/bitmap.h"
#include "qemu/seqlock.h"
+#include "hw/nmi.h"
#ifndef _WIN32
#include "qemu/compatfd.h"
@@ -1496,6 +1497,10 @@ void qmp_inject_nmi(Error **errp)
}
}
#else
- error_set(errp, QERR_UNSUPPORTED);
+ CPUState *cs = qemu_get_cpu(monitor_get_cpu_index());
+
+ if (cs && nmi_try_deliver(cs)) {
+ error_set(errp, QERR_UNSUPPORTED);
+ }
#endif
}
diff --git a/hmp-commands.hx b/hmp-commands.hx
index f3fc514..c25a0f4 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -827,7 +827,6 @@ The values that can be specified here depend on the machine
type, but are
the same that can be specified in the @code{-boot} command line option.
ETEXI
-#if defined(TARGET_I386) || defined(TARGET_S390X)
{
.name = "nmi",
.args_type = "",
@@ -835,11 +834,10 @@ ETEXI
.help = "inject an NMI on all guest's CPUs",
.mhandler.cmd = hmp_inject_nmi,
},
-#endif
STEXI
@item nmi @var{cpu}
@findex nmi
-Inject an NMI (x86) or RESTART (s390x) on the given CPU.
+Inject an NMI (x86), RESTART (s390x) or platform-defined NMI on the given CPU.
ETEXI
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index 5377d05..d2a7be1 100644
--- a/hw/core/Makefile.objs
+++ b/hw/core/Makefile.objs
@@ -1,6 +1,7 @@
# core qdev-related obj files, also used by *-user:
common-obj-y += qdev.o qdev-properties.o
common-obj-y += fw-path-provider.o
+common-obj-y += nmi.o
# irq.o needed for qdev GPIO handling:
common-obj-y += irq.o
common-obj-y += hotplug.o
diff --git a/hw/core/nmi.c b/hw/core/nmi.c
new file mode 100644
index 0000000..01009d3
--- /dev/null
+++ b/hw/core/nmi.c
@@ -0,0 +1,50 @@
+/*
+ * NMI (non-maskable interrupt) interface and helper.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "hw/nmi.h"
+
+int nmi_try_deliver(CPUState *cs)
+{
+ Object *obj = OBJECT(first_cpu);
+ NMIObj *nmi;
+ NMIClass *nmic;
+
+ while (obj->parent) {
+ nmi = (NMIObj *) object_dynamic_cast(obj, TYPE_NMI);
+ if (nmi) {
+ nmic = NMI_GET_CLASS(nmi);
+ nmic->deliver_nmi(nmi, cs);
+ return 0;
+ }
+ obj = obj->parent;
+ }
+
+ return -1;
+}
+
+static const TypeInfo nmi_info = {
+ .name = TYPE_NMI,
+ .parent = TYPE_INTERFACE,
+ .class_size = sizeof(NMIClass),
+};
+
+static void nmi_register_types(void)
+{
+ type_register_static(&nmi_info);
+}
+
+type_init(nmi_register_types)
diff --git a/include/hw/nmi.h b/include/hw/nmi.h
new file mode 100644
index 0000000..53075e3
--- /dev/null
+++ b/include/hw/nmi.h
@@ -0,0 +1,48 @@
+/*
+ * NMI (non-maskable interrupt) interface and helper definitions.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NMI_H
+#define NMI_H 1
+
+#include "qom/object.h"
+#include "qom/cpu.h"
+
+#define TYPE_NMI "nmi"
+
+#define NMI_CLASS(klass) \
+ OBJECT_CLASS_CHECK(NMIClass, (klass), TYPE_NMI)
+#define NMI_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(NMIClass, (obj), TYPE_NMI)
+#define NMI(obj) \
+ INTERFACE_CHECK(NMIObj, (obj), TYPE_NMI)
+
+typedef struct NMIiObj {
+ /* private */
+ Object parent_obj;
+} NMIObj;
+
+typedef struct NMIClass {
+ /* private */
+ InterfaceClass parent_class;
+
+ /* public */
+ void (*deliver_nmi)(NMIObj *p, CPUState *cs);
+} NMIClass;
+
+extern int nmi_try_deliver(CPUState *cs);
+
+#endif /* NMI_H */
--
1.8.4.rc4