[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 09/11] hw/gpio/pl061: Convert to 3-phase reset and assert GPIO li
From: |
Peter Maydell |
Subject: |
[PATCH 09/11] hw/gpio/pl061: Convert to 3-phase reset and assert GPIO lines correctly on reset |
Date: |
Fri, 2 Jul 2021 11:40:16 +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>
---
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 bb496a19ade..8d12b2d6b97 100644
--- a/hw/gpio/pl061.c
+++ b/hw/gpio/pl061.c
@@ -448,13 +448,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;
@@ -476,6 +477,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;
@@ -545,11 +564,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
- Re: [PATCH 04/11] hw/gpio/pl061: Add tracepoints for register read and write, (continued)
Re: [PATCH 03/11] hw/gpio/pl061: Clean up read/write offset handling logic, Richard Henderson, 2021/07/06
[PATCH 07/11] hw/gpio/pl061: Make pullup/pulldown of outputs configurable, Peter Maydell, 2021/07/02
[PATCH 09/11] hw/gpio/pl061: Convert to 3-phase reset and assert GPIO lines correctly on reset,
Peter Maydell <=
[PATCH 06/11] hw/gpio/pl061: Honour Luminary PL061 PUR and PDR registers, Peter Maydell, 2021/07/02
[PATCH 11/11] hw/arm/stellaris: Expand comment about handling of OLED chipselect, Peter Maydell, 2021/07/02
[PATCH 05/11] hw/gpio/pl061: Document the interface of this device, Peter Maydell, 2021/07/02
[PATCH 10/11] hw/gpio/pl061: Document a shortcoming in our implementation, Peter Maydell, 2021/07/02
[PATCH 08/11] hw/arm/virt: Make PL061 GPIO lines pulled low, not high, Peter Maydell, 2021/07/02