Code Review
/
kvmfornfv.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
review
|
tree
raw
|
inline
| side by side
These changes are the raw update to qemu-2.6.
[kvmfornfv.git]
/
qemu
/
hw
/
gpio
/
pl061.c
diff --git
a/qemu/hw/gpio/pl061.c
b/qemu/hw/gpio/pl061.c
index
4ba730b
..
29dc7fc
100644
(file)
--- a/
qemu/hw/gpio/pl061.c
+++ b/
qemu/hw/gpio/pl061.c
@@
-8,6
+8,7
@@
* This code is licensed under the GPL.
*/
* This code is licensed under the GPL.
*/
+#include "qemu/osdep.h"
#include "hw/sysbus.h"
//#define DEBUG_PL061 1
#include "hw/sysbus.h"
//#define DEBUG_PL061 1
@@
-55,17
+56,17
@@
typedef struct PL061State {
uint32_t slr;
uint32_t den;
uint32_t cr;
uint32_t slr;
uint32_t den;
uint32_t cr;
- uint32_t float_high;
uint32_t amsel;
qemu_irq irq;
qemu_irq out[8];
const unsigned char *id;
uint32_t amsel;
qemu_irq irq;
qemu_irq out[8];
const unsigned char *id;
+ uint32_t rsvd_start; /* reserved area: [rsvd_start, 0xfcc] */
} PL061State;
static const VMStateDescription vmstate_pl061 = {
.name = "pl061",
} PL061State;
static const VMStateDescription vmstate_pl061 = {
.name = "pl061",
- .version_id =
3
,
- .minimum_version_id =
3
,
+ .version_id =
4
,
+ .minimum_version_id =
4
,
.fields = (VMStateField[]) {
VMSTATE_UINT32(locked, PL061State),
VMSTATE_UINT32(data, PL061State),
.fields = (VMStateField[]) {
VMSTATE_UINT32(locked, PL061State),
VMSTATE_UINT32(data, PL061State),
@@
-87,7
+88,6
@@
static const VMStateDescription vmstate_pl061 = {
VMSTATE_UINT32(slr, PL061State),
VMSTATE_UINT32(den, PL061State),
VMSTATE_UINT32(cr, PL061State),
VMSTATE_UINT32(slr, PL061State),
VMSTATE_UINT32(den, PL061State),
VMSTATE_UINT32(cr, PL061State),
- VMSTATE_UINT32(float_high, PL061State),
VMSTATE_UINT32_V(amsel, PL061State, 2),
VMSTATE_END_OF_LIST()
}
VMSTATE_UINT32_V(amsel, PL061State, 2),
VMSTATE_END_OF_LIST()
}
@@
-153,12
+153,15
@@
static uint64_t pl061_read(void *opaque, hwaddr offset,
{
PL061State *s = (PL061State *)opaque;
{
PL061State *s = (PL061State *)opaque;
- if (offset >= 0xfd0 && offset < 0x1000) {
- return s->id[(offset - 0xfd0) >> 2];
- }
if (offset < 0x400) {
return s->data & (offset >> 2);
}
if (offset < 0x400) {
return s->data & (offset >> 2);
}
+ if (offset >= s->rsvd_start && offset <= 0xfcc) {
+ goto err_out;
+ }
+ if (offset >= 0xfd0 && offset < 0x1000) {
+ return s->id[(offset - 0xfd0) >> 2];
+ }
switch (offset) {
case 0x400: /* Direction */
return s->dir;
switch (offset) {
case 0x400: /* Direction */
return s->dir;
@@
-199,10
+202,12
@@
static uint64_t pl061_read(void *opaque, hwaddr offset,
case 0x528: /* Analog mode select */
return s->amsel;
default:
case 0x528: /* Analog mode select */
return s->amsel;
default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "pl061_read: Bad offset %x\n", (int)offset);
- return 0;
+ break;
}
}
+err_out:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "pl061_read: Bad offset %x\n", (int)offset);
+ return 0;
}
static void pl061_write(void *opaque, hwaddr offset,
}
static void pl061_write(void *opaque, hwaddr offset,
@@
-217,6
+222,9
@@
static void pl061_write(void *opaque, hwaddr offset,
pl061_update(s);
return;
}
pl061_update(s);
return;
}
+ if (offset >= s->rsvd_start) {
+ goto err_out;
+ }
switch (offset) {
case 0x400: /* Direction */
s->dir = value & 0xff;
switch (offset) {
case 0x400: /* Direction */
s->dir = value & 0xff;
@@
-275,16
+283,41
@@
static void pl061_write(void *opaque, hwaddr offset,
s->amsel = value & 0xff;
break;
default:
s->amsel = value & 0xff;
break;
default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "pl061_write: Bad offset %x\n", (int)offset);
+ goto err_out;
}
pl061_update(s);
}
pl061_update(s);
+ return;
+err_out:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "pl061_write: Bad offset %x\n", (int)offset);
}
}
-static void pl061_reset(
PL061State *s
)
+static void pl061_reset(
DeviceState *dev
)
{
{
- s->locked = 1;
- s->cr = 0xff;
+ PL061State *s = PL061(dev);
+
+ /* 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;
+ s->ibe = 0;
+ s->iev = 0;
+ s->im = 0;
+ s->istate = 0;
+ s->afsel = 0;
+ s->dr2r = 0xff;
+ s->dr4r = 0;
+ s->dr8r = 0;
+ s->odr = 0;
+ s->pur = 0;
+ s->pdr = 0;
+ s->slr = 0;
+ s->den = 0;
+ s->locked = 1;
+ s->cr = 0xff;
+ s->amsel = 0;
}
static void pl061_set_irq(void * opaque, int irq, int level)
}
static void pl061_set_irq(void * opaque, int irq, int level)
@@
-317,7
+350,7
@@
static int pl061_initfn(SysBusDevice *sbd)
sysbus_init_irq(sbd, &s->irq);
qdev_init_gpio_in(dev, pl061_set_irq, 8);
qdev_init_gpio_out(dev, s->out, 8);
sysbus_init_irq(sbd, &s->irq);
qdev_init_gpio_in(dev, pl061_set_irq, 8);
qdev_init_gpio_out(dev, s->out, 8);
- pl061_reset(s);
+
return 0;
}
return 0;
}
@@
-326,6
+359,7
@@
static void pl061_luminary_init(Object *obj)
PL061State *s = PL061(obj);
s->id = pl061_id_luminary;
PL061State *s = PL061(obj);
s->id = pl061_id_luminary;
+ s->rsvd_start = 0x52c;
}
static void pl061_init(Object *obj)
}
static void pl061_init(Object *obj)
@@
-333,6
+367,7
@@
static void pl061_init(Object *obj)
PL061State *s = PL061(obj);
s->id = pl061_id;
PL061State *s = PL061(obj);
s->id = pl061_id;
+ s->rsvd_start = 0x424;
}
static void pl061_class_init(ObjectClass *klass, void *data)
}
static void pl061_class_init(ObjectClass *klass, void *data)
@@
-342,6
+377,7
@@
static void pl061_class_init(ObjectClass *klass, void *data)
k->init = pl061_initfn;
dc->vmsd = &vmstate_pl061;
k->init = pl061_initfn;
dc->vmsd = &vmstate_pl061;
+ dc->reset = &pl061_reset;
}
static const TypeInfo pl061_info = {
}
static const TypeInfo pl061_info = {