117 lines
3.5 KiB
Diff
117 lines
3.5 KiB
Diff
|
|
From 9dc22ff87eb61a8b2bcc5892961ec432986893c9 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Keqian Zhu <zhukeqian1@huawei.com>
|
||
|
|
Date: Thu, 9 Apr 2020 09:31:22 +0800
|
||
|
|
Subject: [PATCH] hw/arm/boot: Add manually register and trigger of CPU reset
|
||
|
|
|
||
|
|
We need to register and trigger CPU reset manually for hotplugged
|
||
|
|
CPU. Besides, we gather CPU reset handlers of all CPUs because CPU
|
||
|
|
reset should happen before GIC reset.
|
||
|
|
|
||
|
|
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||
|
|
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||
|
|
---
|
||
|
|
hw/arm/boot.c | 18 ++++++++++++++++++
|
||
|
|
hw/core/reset.c | 25 +++++++++++++++++++++++++
|
||
|
|
include/hw/arm/boot.h | 3 +++
|
||
|
|
include/sysemu/reset.h | 4 ++++
|
||
|
|
4 files changed, 50 insertions(+)
|
||
|
|
|
||
|
|
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
|
||
|
|
index 21024f7999..3d45de1772 100644
|
||
|
|
--- a/hw/arm/boot.c
|
||
|
|
+++ b/hw/arm/boot.c
|
||
|
|
@@ -814,6 +814,24 @@ static void do_cpu_reset(void *opaque)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
+void cpu_hotplug_register_reset(int ncpu)
|
||
|
|
+{
|
||
|
|
+ CPUState *cpu_0 = qemu_get_cpu(0);
|
||
|
|
+ CPUState *cpu = qemu_get_cpu(ncpu);
|
||
|
|
+ QEMUResetEntry *entry = qemu_get_reset_entry(do_cpu_reset, cpu_0);
|
||
|
|
+
|
||
|
|
+ assert(entry);
|
||
|
|
+ /* Gather the reset handlers of all CPUs */
|
||
|
|
+ qemu_register_reset_after(entry, do_cpu_reset, cpu);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+void cpu_hotplug_reset_manually(int ncpu)
|
||
|
|
+{
|
||
|
|
+ CPUState *cpu = qemu_get_cpu(ncpu);
|
||
|
|
+
|
||
|
|
+ do_cpu_reset(cpu);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
/**
|
||
|
|
* load_image_to_fw_cfg() - Load an image file into an fw_cfg entry identified
|
||
|
|
* by key.
|
||
|
|
diff --git a/hw/core/reset.c b/hw/core/reset.c
|
||
|
|
index e923723d38..314d332111 100644
|
||
|
|
--- a/hw/core/reset.c
|
||
|
|
+++ b/hw/core/reset.c
|
||
|
|
@@ -48,6 +48,31 @@ void qemu_register_reset(QEMUResetHandler *func, void *opaque)
|
||
|
|
QTAILQ_INSERT_TAIL(&reset_handlers, re, entry);
|
||
|
|
}
|
||
|
|
|
||
|
|
+QEMUResetEntry *qemu_get_reset_entry(QEMUResetHandler *func,
|
||
|
|
+ void *opaque)
|
||
|
|
+{
|
||
|
|
+ QEMUResetEntry *re;
|
||
|
|
+
|
||
|
|
+ QTAILQ_FOREACH(re, &reset_handlers, entry) {
|
||
|
|
+ if (re->func == func && re->opaque == opaque) {
|
||
|
|
+ return re;
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return NULL;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+void qemu_register_reset_after(QEMUResetEntry *entry,
|
||
|
|
+ QEMUResetHandler *func,
|
||
|
|
+ void *opaque)
|
||
|
|
+{
|
||
|
|
+ QEMUResetEntry *re = g_malloc0(sizeof(QEMUResetEntry));
|
||
|
|
+
|
||
|
|
+ re->func = func;
|
||
|
|
+ re->opaque = opaque;
|
||
|
|
+ QTAILQ_INSERT_AFTER(&reset_handlers, entry, re, entry);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
|
||
|
|
{
|
||
|
|
QEMUResetEntry *re;
|
||
|
|
diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h
|
||
|
|
index ce2b48b88b..c3c4d3ea79 100644
|
||
|
|
--- a/include/hw/arm/boot.h
|
||
|
|
+++ b/include/hw/arm/boot.h
|
||
|
|
@@ -119,6 +119,9 @@ struct arm_boot_info {
|
||
|
|
arm_endianness endianness;
|
||
|
|
};
|
||
|
|
|
||
|
|
+void cpu_hotplug_register_reset(int ncpu);
|
||
|
|
+void cpu_hotplug_reset_manually(int ncpu);
|
||
|
|
+
|
||
|
|
/**
|
||
|
|
* arm_load_kernel - Loads memory with everything needed to boot
|
||
|
|
*
|
||
|
|
diff --git a/include/sysemu/reset.h b/include/sysemu/reset.h
|
||
|
|
index 0b0d6d7598..f3ff26c637 100644
|
||
|
|
--- a/include/sysemu/reset.h
|
||
|
|
+++ b/include/sysemu/reset.h
|
||
|
|
@@ -2,7 +2,11 @@
|
||
|
|
#define QEMU_SYSEMU_RESET_H
|
||
|
|
|
||
|
|
typedef void QEMUResetHandler(void *opaque);
|
||
|
|
+typedef struct QEMUResetEntry QEMUResetEntry;
|
||
|
|
|
||
|
|
+QEMUResetEntry *qemu_get_reset_entry(QEMUResetHandler *func, void *opaque);
|
||
|
|
+void qemu_register_reset_after(QEMUResetEntry *entry,
|
||
|
|
+ QEMUResetHandler *func, void *opaque);
|
||
|
|
void qemu_register_reset(QEMUResetHandler *func, void *opaque);
|
||
|
|
void qemu_unregister_reset(QEMUResetHandler *func, void *opaque);
|
||
|
|
void qemu_devices_reset(void);
|
||
|
|
--
|
||
|
|
2.27.0
|
||
|
|
|