[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 4/4] zynq_slcr: Implement CPU reset and halting
From: |
Peter Crosthwaite |
Subject: |
[Qemu-devel] [PATCH v2 4/4] zynq_slcr: Implement CPU reset and halting |
Date: |
Thu, 4 Oct 2012 10:16:14 +1000 |
From: Peter A. G. Crosthwaite <address@hidden>
Implement the CPU reset and halt functions of the A9_CPU_RST_CTRL register
(offset 0x244).
Signed-off-by: Peter A. G. Crosthwaite <address@hidden>
---
hw/zynq_slcr.c | 18 ++++++++++++++++++
1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/hw/zynq_slcr.c b/hw/zynq_slcr.c
index 6eafad5..c1922fc 100644
--- a/hw/zynq_slcr.c
+++ b/hw/zynq_slcr.c
@@ -116,6 +116,9 @@ typedef enum {
RESET_MAX
} ResetValues;
+#define A9_CPU_RST_CTRL_RST_SHIFT 0
+#define A9_CPU_RST_CTRL_CLKSTOP_SHIFT 4
+
typedef struct {
SysBusDevice busdev;
MemoryRegion iomem;
@@ -346,6 +349,7 @@ static void zynq_slcr_write(void *opaque,
target_phys_addr_t offset,
uint64_t val, unsigned size)
{
ZynqSLCRState *s = (ZynqSLCRState *)opaque;
+ int i;
DB_PRINT("offset: %08x data: %08x\n", offset, (unsigned)val);
@@ -400,6 +404,20 @@ static void zynq_slcr_write(void *opaque,
target_phys_addr_t offset,
goto bad_reg;
}
s->reset[(offset - 0x200) / 4] = val;
+ if (offset - 0x200 == A9_CPU * 4) { /* CPU Reset */
+ for (i = 0; i < NUM_CPUS && s->cpus[i]; ++i) {
+ bool is_rst = val & (1 << (A9_CPU_RST_CTRL_RST_SHIFT + i));
+ bool is_clkstop = val &
+ (1 << (A9_CPU_RST_CTRL_CLKSTOP_SHIFT + i));
+ if (is_rst) {
+ CPU_GET_CLASS(CPU(s->cpus[i]))->reset(CPU(s->cpus[i]));
+ DB_PRINT("resetting cpu %d\n", i);
+ }
+ s->cpus[i]->env.halted = is_rst || is_clkstop;
+ DB_PRINT("%shalting cpu %d\n", s->cpus[i]->env.halted ?
+ "" : "un", i);
+ }
+ }
break;
case 0x300:
s->apu_ctrl = val;
--
1.7.0.4
Re: [Qemu-devel] [PATCH v2 0/4] Xilinx-Zynq boot process patches, Peter Crosthwaite, 2012/10/09