* [Qemu-devel] [PATCH 0/2] pl061: convert to VMState, add GPIOAMSEL register
@ 2011-08-03 23:04 Peter Maydell
2011-08-03 23:04 ` [Qemu-devel] [PATCH 1/2] hw/pl061: Convert to VMState Peter Maydell
2011-08-03 23:04 ` [Qemu-devel] [PATCH 2/2] hw/pl061.c: Support GPIOAMSEL register Peter Maydell
0 siblings, 2 replies; 3+ messages in thread
From: Peter Maydell @ 2011-08-03 23:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Engin AYDOGAN, patches
The main aim of this patchset is to add the GPIOAMSEL register
to the PL061 GPIO module. I've converted the PL061 to VMState format
first, though, because I didn't really feel like adding a new
field/version to an old-style save/load format device...
Notes: the old vmstate format for pl061 is 32 bits per register on the
wire despite being only 8 bits in the struct. I opted to widen the
struct member fields to 32 bits as the least unpalatable of the various
possible ways to deal with this in VMState format.
The GPIOAMSEL register is TI/Stellaris specific, but we leave it
in the ARM PL061 to match all the other Stellaris specific registers.
It's also only present on newer Stellaris chips, but common init code
typically tries to write to it anyway. Since it doesn't do anything in
the model there doesn't seem any point trying to distinguish between
revisions where it reads-as-written and revisions where it is
unimplemented and will RAZ/WI.
These patches plus Engin's one for the RCC2 register are enough
for the example binary from http://www.keil.com/download/docs/345.asp
to boot and at least get as far as drawing to the screen (although
there may still be some issues with networking).
Peter Maydell (2):
hw/pl061: Convert to VMState
hw/pl061.c: Support GPIOAMSEL register
hw/pl061.c | 181 ++++++++++++++++++++++++++++-------------------------------
1 files changed, 86 insertions(+), 95 deletions(-)
--
1.7.4.1
^ permalink raw reply [flat|nested] 3+ messages in thread
* [Qemu-devel] [PATCH 1/2] hw/pl061: Convert to VMState
2011-08-03 23:04 [Qemu-devel] [PATCH 0/2] pl061: convert to VMState, add GPIOAMSEL register Peter Maydell
@ 2011-08-03 23:04 ` Peter Maydell
2011-08-03 23:04 ` [Qemu-devel] [PATCH 2/2] hw/pl061.c: Support GPIOAMSEL register Peter Maydell
1 sibling, 0 replies; 3+ messages in thread
From: Peter Maydell @ 2011-08-03 23:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Engin AYDOGAN, patches
Convert the PL061 to VMState. We choose to widen the struct members
to uint32_t rather than the other two options of breaking migration
compatibility or using vmstate hacks to read/write a 32 bit value
into an 8 bit struct field.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/pl061.c | 174 +++++++++++++++++++++++++++---------------------------------
1 files changed, 79 insertions(+), 95 deletions(-)
diff --git a/hw/pl061.c b/hw/pl061.c
index 79e5c53..27de824 100644
--- a/hw/pl061.c
+++ b/hw/pl061.c
@@ -30,31 +30,60 @@ static const uint8_t pl061_id_luminary[12] =
typedef struct {
SysBusDevice busdev;
- int locked;
- uint8_t data;
- uint8_t old_data;
- uint8_t dir;
- uint8_t isense;
- uint8_t ibe;
- uint8_t iev;
- uint8_t im;
- uint8_t istate;
- uint8_t afsel;
- uint8_t dr2r;
- uint8_t dr4r;
- uint8_t dr8r;
- uint8_t odr;
- uint8_t pur;
- uint8_t pdr;
- uint8_t slr;
- uint8_t den;
- uint8_t cr;
- uint8_t float_high;
+ uint32_t locked;
+ uint32_t data;
+ uint32_t old_data;
+ uint32_t dir;
+ uint32_t isense;
+ uint32_t ibe;
+ uint32_t iev;
+ uint32_t im;
+ uint32_t istate;
+ uint32_t afsel;
+ uint32_t dr2r;
+ uint32_t dr4r;
+ uint32_t dr8r;
+ uint32_t odr;
+ uint32_t pur;
+ uint32_t pdr;
+ uint32_t slr;
+ uint32_t den;
+ uint32_t cr;
+ uint32_t float_high;
qemu_irq irq;
qemu_irq out[8];
const unsigned char *id;
} pl061_state;
+static const VMStateDescription vmstate_pl061 = {
+ .name = "pl061",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(locked, pl061_state),
+ VMSTATE_UINT32(data, pl061_state),
+ VMSTATE_UINT32(old_data, pl061_state),
+ VMSTATE_UINT32(dir, pl061_state),
+ VMSTATE_UINT32(isense, pl061_state),
+ VMSTATE_UINT32(ibe, pl061_state),
+ VMSTATE_UINT32(iev, pl061_state),
+ VMSTATE_UINT32(im, pl061_state),
+ VMSTATE_UINT32(istate, pl061_state),
+ VMSTATE_UINT32(afsel, pl061_state),
+ VMSTATE_UINT32(dr2r, pl061_state),
+ VMSTATE_UINT32(dr4r, pl061_state),
+ VMSTATE_UINT32(dr8r, pl061_state),
+ VMSTATE_UINT32(odr, pl061_state),
+ VMSTATE_UINT32(pur, pl061_state),
+ VMSTATE_UINT32(pdr, pl061_state),
+ VMSTATE_UINT32(slr, pl061_state),
+ VMSTATE_UINT32(den, pl061_state),
+ VMSTATE_UINT32(cr, pl061_state),
+ VMSTATE_UINT32(float_high, pl061_state),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static void pl061_update(pl061_state *s)
{
uint8_t changed;
@@ -148,19 +177,19 @@ static void pl061_write(void *opaque, target_phys_addr_t offset,
}
switch (offset) {
case 0x400: /* Direction */
- s->dir = value;
+ s->dir = value & 0xff;
break;
case 0x404: /* Interrupt sense */
- s->isense = value;
+ s->isense = value & 0xff;
break;
case 0x408: /* Interrupt both edges */
- s->ibe = value;
+ s->ibe = value & 0xff;
break;
case 0x40c: /* Interrupt event */
- s->iev = value;
+ s->iev = value & 0xff;
break;
case 0x410: /* Interrupt mask */
- s->im = value;
+ s->im = value & 0xff;
break;
case 0x41c: /* Interrupt clear */
s->istate &= ~value;
@@ -170,35 +199,35 @@ static void pl061_write(void *opaque, target_phys_addr_t offset,
s->afsel = (s->afsel & ~mask) | (value & mask);
break;
case 0x500: /* 2mA drive */
- s->dr2r = value;
+ s->dr2r = value & 0xff;
break;
case 0x504: /* 4mA drive */
- s->dr4r = value;
+ s->dr4r = value & 0xff;
break;
case 0x508: /* 8mA drive */
- s->dr8r = value;
+ s->dr8r = value & 0xff;
break;
case 0x50c: /* Open drain */
- s->odr = value;
+ s->odr = value & 0xff;
break;
case 0x510: /* Pull-up */
- s->pur = value;
+ s->pur = value & 0xff;
break;
case 0x514: /* Pull-down */
- s->pdr = value;
+ s->pdr = value & 0xff;
break;
case 0x518: /* Slew rate control */
- s->slr = value;
+ s->slr = value & 0xff;
break;
case 0x51c: /* Digital enable */
- s->den = value;
+ s->den = value & 0xff;
break;
case 0x520: /* Lock */
s->locked = (value != 0xacce551);
break;
case 0x524: /* Commit */
if (!s->locked)
- s->cr = value;
+ s->cr = value & 0xff;
break;
default:
hw_error("pl061_write: Bad offset %x\n", (int)offset);
@@ -238,62 +267,6 @@ static CPUWriteMemoryFunc * const pl061_writefn[] = {
pl061_write
};
-static void pl061_save(QEMUFile *f, void *opaque)
-{
- pl061_state *s = (pl061_state *)opaque;
-
- qemu_put_be32(f, s->locked);
- qemu_put_be32(f, s->data);
- qemu_put_be32(f, s->old_data);
- qemu_put_be32(f, s->dir);
- qemu_put_be32(f, s->isense);
- qemu_put_be32(f, s->ibe);
- qemu_put_be32(f, s->iev);
- qemu_put_be32(f, s->im);
- qemu_put_be32(f, s->istate);
- qemu_put_be32(f, s->afsel);
- qemu_put_be32(f, s->dr2r);
- qemu_put_be32(f, s->dr4r);
- qemu_put_be32(f, s->dr8r);
- qemu_put_be32(f, s->odr);
- qemu_put_be32(f, s->pur);
- qemu_put_be32(f, s->pdr);
- qemu_put_be32(f, s->slr);
- qemu_put_be32(f, s->den);
- qemu_put_be32(f, s->cr);
- qemu_put_be32(f, s->float_high);
-}
-
-static int pl061_load(QEMUFile *f, void *opaque, int version_id)
-{
- pl061_state *s = (pl061_state *)opaque;
- if (version_id != 1)
- return -EINVAL;
-
- s->locked = qemu_get_be32(f);
- s->data = qemu_get_be32(f);
- s->old_data = qemu_get_be32(f);
- s->dir = qemu_get_be32(f);
- s->isense = qemu_get_be32(f);
- s->ibe = qemu_get_be32(f);
- s->iev = qemu_get_be32(f);
- s->im = qemu_get_be32(f);
- s->istate = qemu_get_be32(f);
- s->afsel = qemu_get_be32(f);
- s->dr2r = qemu_get_be32(f);
- s->dr4r = qemu_get_be32(f);
- s->dr8r = qemu_get_be32(f);
- s->odr = qemu_get_be32(f);
- s->pur = qemu_get_be32(f);
- s->pdr = qemu_get_be32(f);
- s->slr = qemu_get_be32(f);
- s->den = qemu_get_be32(f);
- s->cr = qemu_get_be32(f);
- s->float_high = qemu_get_be32(f);
-
- return 0;
-}
-
static int pl061_init(SysBusDevice *dev, const unsigned char *id)
{
int iomemtype;
@@ -307,7 +280,6 @@ static int pl061_init(SysBusDevice *dev, const unsigned char *id)
qdev_init_gpio_in(&dev->qdev, pl061_set_irq, 8);
qdev_init_gpio_out(&dev->qdev, s->out, 8);
pl061_reset(s);
- register_savevm(&dev->qdev, "pl061_gpio", -1, 1, pl061_save, pl061_load, s);
return 0;
}
@@ -321,12 +293,24 @@ static int pl061_init_arm(SysBusDevice *dev)
return pl061_init(dev, pl061_id);
}
+static SysBusDeviceInfo pl061_info = {
+ .init = pl061_init_arm,
+ .qdev.name = "pl061",
+ .qdev.size = sizeof(pl061_state),
+ .qdev.vmsd = &vmstate_pl061,
+};
+
+static SysBusDeviceInfo pl061_luminary_info = {
+ .init = pl061_init_luminary,
+ .qdev.name = "pl061_luminary",
+ .qdev.size = sizeof(pl061_state),
+ .qdev.vmsd = &vmstate_pl061,
+};
+
static void pl061_register_devices(void)
{
- sysbus_register_dev("pl061", sizeof(pl061_state),
- pl061_init_arm);
- sysbus_register_dev("pl061_luminary", sizeof(pl061_state),
- pl061_init_luminary);
+ sysbus_register_withprop(&pl061_info);
+ sysbus_register_withprop(&pl061_luminary_info);
}
device_init(pl061_register_devices)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [Qemu-devel] [PATCH 2/2] hw/pl061.c: Support GPIOAMSEL register
2011-08-03 23:04 [Qemu-devel] [PATCH 0/2] pl061: convert to VMState, add GPIOAMSEL register Peter Maydell
2011-08-03 23:04 ` [Qemu-devel] [PATCH 1/2] hw/pl061: Convert to VMState Peter Maydell
@ 2011-08-03 23:04 ` Peter Maydell
1 sibling, 0 replies; 3+ messages in thread
From: Peter Maydell @ 2011-08-03 23:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Engin AYDOGAN, patches
Support the GPIOAMSEL register found on some Stellaris boards.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/pl061.c | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/hw/pl061.c b/hw/pl061.c
index 27de824..d13746c 100644
--- a/hw/pl061.c
+++ b/hw/pl061.c
@@ -50,6 +50,7 @@ typedef struct {
uint32_t den;
uint32_t cr;
uint32_t float_high;
+ uint32_t amsel;
qemu_irq irq;
qemu_irq out[8];
const unsigned char *id;
@@ -57,7 +58,7 @@ typedef struct {
static const VMStateDescription vmstate_pl061 = {
.name = "pl061",
- .version_id = 1,
+ .version_id = 2,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT32(locked, pl061_state),
@@ -80,6 +81,7 @@ static const VMStateDescription vmstate_pl061 = {
VMSTATE_UINT32(den, pl061_state),
VMSTATE_UINT32(cr, pl061_state),
VMSTATE_UINT32(float_high, pl061_state),
+ VMSTATE_UINT32_V(amsel, pl061_state, 2),
VMSTATE_END_OF_LIST()
}
};
@@ -157,6 +159,8 @@ static uint32_t pl061_read(void *opaque, target_phys_addr_t offset)
return s->locked;
case 0x524: /* Commit */
return s->cr;
+ case 0x528: /* Analog mode select */
+ return s->amsel;
default:
hw_error("pl061_read: Bad offset %x\n", (int)offset);
return 0;
@@ -229,6 +233,9 @@ static void pl061_write(void *opaque, target_phys_addr_t offset,
if (!s->locked)
s->cr = value & 0xff;
break;
+ case 0x528:
+ s->amsel = value & 0xff;
+ break;
default:
hw_error("pl061_write: Bad offset %x\n", (int)offset);
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2011-08-03 23:26 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-08-03 23:04 [Qemu-devel] [PATCH 0/2] pl061: convert to VMState, add GPIOAMSEL register Peter Maydell
2011-08-03 23:04 ` [Qemu-devel] [PATCH 1/2] hw/pl061: Convert to VMState Peter Maydell
2011-08-03 23:04 ` [Qemu-devel] [PATCH 2/2] hw/pl061.c: Support GPIOAMSEL register Peter Maydell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).