Signed-off-by: Maksim Kozlov <m.koz...@samsung.com> --- hw/exynos4210_pmu.c | 34 +++++++++++++++++++++++++++++++++- 1 files changed, 33 insertions(+), 1 deletions(-)
diff --git a/hw/exynos4210_pmu.c b/hw/exynos4210_pmu.c index 7f09c79..2ae3b60 100644 --- a/hw/exynos4210_pmu.c +++ b/hw/exynos4210_pmu.c @@ -25,6 +25,7 @@ */ #include "sysbus.h" +#include "sysemu.h" #ifndef DEBUG_PMU #define DEBUG_PMU 0 @@ -230,6 +231,8 @@ #define EXYNOS4210_PMU_REGS_MEM_SIZE 0x3d0c +#define SWRESET_SYSTEM_MASK 0x00000001 + typedef struct Exynos4210PmuReg { const char *name; /* for debug only */ uint32_t offset; @@ -458,7 +461,17 @@ static void exynos4210_pmu_write(void *opaque, target_phys_addr_t offset, PRINT_DEBUG_EXTEND("%s [0x%04x] <- 0x%04x\n", exynos4210_pmu_regs[index].name, (uint32_t)offset, (uint32_t)val); - s->reg[index] = val; + switch (offset) { + case SWRESET: + if (val & SWRESET_SYSTEM_MASK) { + s->reg[index] = val; + qemu_system_reset_request(); + } + break; + default: + s->reg[index] = val; + break; + } } static const MemoryRegionOps exynos4210_pmu_ops = { @@ -477,9 +490,28 @@ static void exynos4210_pmu_reset(DeviceState *dev) Exynos4210PmuState *s = container_of(dev, Exynos4210PmuState, busdev.qdev); unsigned i; + uint32_t index = exynos4210_pmu_get_register_index(s, SWRESET); + uint32_t swreset = s->reg[index]; /* Set default values for registers */ for (i = 0; i < PMU_NUM_OF_REGISTERS; i++) { + if (swreset) { + switch (exynos4210_pmu_regs[i].offset) { + case INFORM0: + case INFORM1: + case INFORM2: + case INFORM3: + case INFORM4: + case INFORM5: + case INFORM6: + case INFORM7: + case PS_HOLD_CONTROL: + /* keep these registers during SW reset */ + continue; + default: + break; + } + } s->reg[i] = exynos4210_pmu_regs[i].reset_value; } } -- 1.7.5.4