[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 13/17] hw/gpio/pl061: Convert to 3-phase reset and assert GPIO lin
From: |
Peter Maydell |
Subject: |
[PULL 13/17] hw/gpio/pl061: Convert to 3-phase reset and assert GPIO lines correctly on reset |
Date: |
Fri, 9 Jul 2021 17:09:59 +0100 |
The PL061 comes out of reset with all its lines configured as input,
which means they might need to be pulled to 0 or 1 depending on the
'pullups' and 'pulldowns' properties. Currently we do not assert
these lines on reset; they will only be set whenever the guest first
touches a register that triggers a call to pl061_update().
Convert the device to three-phase reset so we have a place where we
can safely call qemu_set_irq() to set the floating lines to their
correct values.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
hw/gpio/pl061.c | 29 +++++++++++++++++++++++++----
hw/gpio/trace-events | 1 +
2 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
index 5ba398fcd42..4002ab51544 100644
--- a/hw/gpio/pl061.c
+++ b/hw/gpio/pl061.c
@@ -446,13 +446,14 @@ static void pl061_write(void *opaque, hwaddr offset,
return;
}
-static void pl061_reset(DeviceState *dev)
+static void pl061_enter_reset(Object *obj, ResetType type)
{
- PL061State *s = PL061(dev);
+ PL061State *s = PL061(obj);
+
+ trace_pl061_reset(DEVICE(s)->canonical_path);
/* reset values from PL061 TRM, Stellaris LM3S5P31 & LM3S8962 Data Sheet */
s->data = 0;
- s->old_out_data = 0;
s->old_in_data = 0;
s->dir = 0;
s->isense = 0;
@@ -474,6 +475,24 @@ static void pl061_reset(DeviceState *dev)
s->amsel = 0;
}
+static void pl061_hold_reset(Object *obj)
+{
+ PL061State *s = PL061(obj);
+ int i, level;
+ uint8_t floating = pl061_floating(s);
+ uint8_t pullups = pl061_pullups(s);
+
+ for (i = 0; i < N_GPIOS; i++) {
+ if (extract32(floating, i, 1)) {
+ continue;
+ }
+ level = extract32(pullups, i, 1);
+ trace_pl061_set_output(DEVICE(s)->canonical_path, i, level);
+ qemu_set_irq(s->out[i], level);
+ }
+ s->old_out_data = pullups;
+}
+
static void pl061_set_irq(void * opaque, int irq, int level)
{
PL061State *s = (PL061State *)opaque;
@@ -543,11 +562,13 @@ static Property pl061_props[] = {
static void pl061_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
dc->vmsd = &vmstate_pl061;
- dc->reset = &pl061_reset;
dc->realize = pl061_realize;
device_class_set_props(dc, pl061_props);
+ rc->phases.enter = pl061_enter_reset;
+ rc->phases.hold = pl061_hold_reset;
}
static const TypeInfo pl061_info = {
diff --git a/hw/gpio/trace-events b/hw/gpio/trace-events
index eb5fb4701c6..1dab99c5604 100644
--- a/hw/gpio/trace-events
+++ b/hw/gpio/trace-events
@@ -20,6 +20,7 @@ pl061_input_change(const char *id, int gpio, int level) "%s
input %d changed to
pl061_update_istate(const char *id, uint32_t istate, uint32_t im, int level)
"%s GPIORIS 0x%x GPIOIE 0x%x interrupt level %d"
pl061_read(const char *id, uint64_t offset, uint64_t r) "%s offset 0x%" PRIx64
" value 0x%" PRIx64
pl061_write(const char *id, uint64_t offset, uint64_t value) "%s offset 0x%"
PRIx64 " value 0x%" PRIx64
+pl061_reset(const char *id) "%s reset"
# sifive_gpio.c
sifive_gpio_read(uint64_t offset, uint64_t r) "offset 0x%" PRIx64 " value 0x%"
PRIx64
--
2.20.1
- [PULL 00/17] target-arm queue, Peter Maydell, 2021/07/09
- [PULL 01/17] stm32f100: Add the stm32f100 SoC, Peter Maydell, 2021/07/09
- [PULL 02/17] stm32vldiscovery: Add the STM32VLDISCOVERY Machine, Peter Maydell, 2021/07/09
- [PULL 05/17] hw/intc/arm_gicv3_cpuif: Fix virtual irq number check in icv_[dir|eoir]_write, Peter Maydell, 2021/07/09
- [PULL 03/17] docs/system: arm: Add stm32 boards description, Peter Maydell, 2021/07/09
- [PULL 04/17] tests/boot-serial-test: Add STM32VLDISCOVERY board testcase, Peter Maydell, 2021/07/09
- [PULL 09/17] hw/gpio/pl061: Document the interface of this device, Peter Maydell, 2021/07/09
- [PULL 07/17] hw/gpio/pl061: Clean up read/write offset handling logic, Peter Maydell, 2021/07/09
- [PULL 06/17] hw/gpio/pl061: Convert DPRINTF to tracepoints, Peter Maydell, 2021/07/09
- [PULL 08/17] hw/gpio/pl061: Add tracepoints for register read and write, Peter Maydell, 2021/07/09
- [PULL 13/17] hw/gpio/pl061: Convert to 3-phase reset and assert GPIO lines correctly on reset,
Peter Maydell <=
- [PULL 15/17] hw/arm/stellaris: Expand comment about handling of OLED chipselect, Peter Maydell, 2021/07/09
- [PULL 17/17] hw/intc: Improve formatting of MEMTX_ERROR guest error message, Peter Maydell, 2021/07/09
- [PULL 10/17] hw/gpio/pl061: Honour Luminary PL061 PUR and PDR registers, Peter Maydell, 2021/07/09
- [PULL 16/17] target/arm: Correct the encoding of MDCCSR_EL0 and DBGDSCRint, Peter Maydell, 2021/07/09
- [PULL 11/17] hw/gpio/pl061: Make pullup/pulldown of outputs configurable, Peter Maydell, 2021/07/09
- [PULL 14/17] hw/gpio/pl061: Document a shortcoming in our implementation, Peter Maydell, 2021/07/09
- [PULL 12/17] hw/arm/virt: Make PL061 GPIO lines pulled low, not high, Peter Maydell, 2021/07/09
- Re: [PULL 00/17] target-arm queue, Peter Maydell, 2021/07/11