[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 3/4] hw/xtensa: xtfpga: use MX PIC for SMP
From: |
Max Filippov |
Subject: |
[Qemu-devel] [PATCH 3/4] hw/xtensa: xtfpga: use MX PIC for SMP |
Date: |
Sun, 27 Jan 2019 18:09:36 -0800 |
Create and use MX PIC as a peripheral interrupt controller when more
than 1 processor is enabled on xtfpga board. Connect xtensa CPU cores to
the MX PIC and select secondary reset vector on all cores except the
first one.
Signed-off-by: Max Filippov <address@hidden>
---
hw/xtensa/xtfpga.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
index 3102f8c04709..792a225e03a2 100644
--- a/hw/xtensa/xtfpga.c
+++ b/hw/xtensa/xtfpga.c
@@ -45,6 +45,7 @@
#include "qemu/option.h"
#include "bootparam.h"
#include "xtensa_memory.h"
+#include "hw/xtensa/mx_pic.h"
typedef struct XtfpgaFlashDesc {
hwaddr base;
@@ -225,6 +226,7 @@ static void xtfpga_init(const XtfpgaBoardDesc *board,
MachineState *machine)
XtensaCPU *cpu = NULL;
CPUXtensaState *env = NULL;
MemoryRegion *system_io;
+ XtensaMxPic *mx_pic = NULL;
qemu_irq *extints;
DriveInfo *dinfo;
pflash_t *flash = NULL;
@@ -237,6 +239,10 @@ static void xtfpga_init(const XtfpgaBoardDesc *board,
MachineState *machine)
uint32_t freq = 10000000;
int n;
+ if (smp_cpus > 1) {
+ mx_pic = xtensa_mx_pic_init(31);
+ qemu_register_reset(xtensa_mx_pic_reset, mx_pic);
+ }
for (n = 0; n < smp_cpus; n++) {
CPUXtensaState *cenv = NULL;
@@ -247,14 +253,28 @@ static void xtfpga_init(const XtfpgaBoardDesc *board,
MachineState *machine)
freq = env->config->clock_freq_khz * 1000;
}
+ if (mx_pic) {
+ MemoryRegion *mx_eri;
+
+ mx_eri = xtensa_mx_pic_register_cpu(mx_pic,
+ xtensa_get_extints(cenv),
+ xtensa_get_runstall(cenv));
+ memory_region_add_subregion(xtensa_get_er_region(cenv),
+ 0, mx_eri);
+ }
cenv->sregs[PRID] = n;
+ xtensa_select_static_vectors(cenv, n != 0);
qemu_register_reset(xtfpga_reset, cpu);
/* Need MMU initialized prior to ELF loading,
* so that ELF gets loaded into virtual addresses
*/
cpu_reset(CPU(cpu));
}
- extints = xtensa_get_extints(env);
+ if (smp_cpus > 1) {
+ extints = xtensa_mx_pic_get_extints(mx_pic);
+ } else {
+ extints = xtensa_get_extints(env);
+ }
if (env) {
XtensaMemory sysram = env->config->sysram;
--
2.11.0