提交 40905a6a 编写于 作者: P Paul Brook

Stellaris qdev conversion

Signed-off-by: NPaul Brook <paul@codesourcery.com>
上级 2c6554bc
...@@ -117,18 +117,35 @@ static CPUWriteMemoryFunc *bitband_writefn[] = { ...@@ -117,18 +117,35 @@ static CPUWriteMemoryFunc *bitband_writefn[] = {
bitband_writel bitband_writel
}; };
static void armv7m_bitband_init(void) typedef struct {
SysBusDevice busdev;
uint32_t base;
} BitBandState;
static void bitband_init(SysBusDevice *dev)
{ {
BitBandState *s = FROM_SYSBUS(BitBandState, dev);
int iomemtype; int iomemtype;
static uint32_t bitband1_offset = 0x20000000;
static uint32_t bitband2_offset = 0x40000000;
s->base = qdev_get_prop_int(&dev->qdev, "base", 0);
iomemtype = cpu_register_io_memory(0, bitband_readfn, bitband_writefn, iomemtype = cpu_register_io_memory(0, bitband_readfn, bitband_writefn,
&bitband1_offset); &s->base);
cpu_register_physical_memory(0x22000000, 0x02000000, iomemtype); sysbus_init_mmio(dev, 0x02000000, iomemtype);
iomemtype = cpu_register_io_memory(0, bitband_readfn, bitband_writefn, }
&bitband2_offset);
cpu_register_physical_memory(0x42000000, 0x02000000, iomemtype); static void armv7m_bitband_init(void)
{
DeviceState *dev;
dev = qdev_create(NULL, "ARM,bitband-memory");
qdev_set_prop_int(dev, "base", 0x20000000);
qdev_init(dev);
sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0x22000000);
dev = qdev_create(NULL, "ARM,bitband-memory");
qdev_set_prop_int(dev, "base", 0x40000000);
qdev_init(dev);
sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0x42000000);
} }
/* Board init. */ /* Board init. */
...@@ -220,3 +237,11 @@ qemu_irq *armv7m_init(int flash_size, int sram_size, ...@@ -220,3 +237,11 @@ qemu_irq *armv7m_init(int flash_size, int sram_size,
return pic; return pic;
} }
static void armv7m_register_devices(void)
{
sysbus_register_dev("ARM,bitband-memory", sizeof(BitBandState),
bitband_init);
}
device_init(armv7m_register_devices)
...@@ -8,8 +8,7 @@ ...@@ -8,8 +8,7 @@
* This code is licenced under the GPL. * This code is licenced under the GPL.
*/ */
#include "hw.h" #include "sysbus.h"
#include "primecell.h"
//#define DEBUG_PL061 1 //#define DEBUG_PL061 1
...@@ -28,6 +27,7 @@ static const uint8_t pl061_id[12] = ...@@ -28,6 +27,7 @@ static const uint8_t pl061_id[12] =
{ 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1 }; { 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1 };
typedef struct { typedef struct {
SysBusDevice busdev;
int locked; int locked;
uint8_t data; uint8_t data;
uint8_t old_data; uint8_t old_data;
...@@ -291,21 +291,25 @@ static int pl061_load(QEMUFile *f, void *opaque, int version_id) ...@@ -291,21 +291,25 @@ static int pl061_load(QEMUFile *f, void *opaque, int version_id)
return 0; return 0;
} }
/* Returns an array of inputs. */ static void pl061_init(SysBusDevice *dev)
qemu_irq *pl061_init(uint32_t base, qemu_irq irq, qemu_irq **out)
{ {
int iomemtype; int iomemtype;
pl061_state *s; pl061_state *s = FROM_SYSBUS(pl061_state, dev);
s = (pl061_state *)qemu_mallocz(sizeof(pl061_state));
iomemtype = cpu_register_io_memory(0, pl061_readfn, iomemtype = cpu_register_io_memory(0, pl061_readfn,
pl061_writefn, s); pl061_writefn, s);
cpu_register_physical_memory(base, 0x00001000, iomemtype); sysbus_init_mmio(dev, 0x1000, iomemtype);
s->irq = irq; sysbus_init_irq(dev, &s->irq);
qdev_init_gpio_in(&dev->qdev, pl061_set_irq, 8);
qdev_init_gpio_out(&dev->qdev, s->out, 8);
pl061_reset(s); pl061_reset(s);
if (out)
*out = s->out;
register_savevm("pl061_gpio", -1, 1, pl061_save, pl061_load, s); register_savevm("pl061_gpio", -1, 1, pl061_save, pl061_load, s);
return qemu_allocate_irqs(pl061_set_irq, s, 8);
} }
static void pl061_register_devices(void)
{
sysbus_register_dev("pl061", sizeof(pl061_state),
pl061_init);
}
device_init(pl061_register_devices)
...@@ -5,10 +5,6 @@ ...@@ -5,10 +5,6 @@
/* Also includes some devices that are currently only used by the /* Also includes some devices that are currently only used by the
ARM boards. */ ARM boards. */
/* pl061.c */
void pl061_float_high(void *opaque, uint8_t mask);
qemu_irq *pl061_init(uint32_t base, qemu_irq irq, qemu_irq **out);
/* pl080.c */ /* pl080.c */
void *pl080_init(uint32_t base, qemu_irq irq, int nchannels); void *pl080_init(uint32_t base, qemu_irq irq, int nchannels);
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include "sysbus.h" #include "sysbus.h"
#include "ssi.h" #include "ssi.h"
#include "arm-misc.h" #include "arm-misc.h"
#include "primecell.h"
#include "devices.h" #include "devices.h"
#include "qemu-timer.h" #include "qemu-timer.h"
#include "i2c.h" #include "i2c.h"
...@@ -45,6 +44,7 @@ typedef const struct { ...@@ -45,6 +44,7 @@ typedef const struct {
/* General purpose timer module. */ /* General purpose timer module. */
typedef struct gptm_state { typedef struct gptm_state {
SysBusDevice busdev;
uint32_t config; uint32_t config;
uint32_t mode[2]; uint32_t mode[2];
uint32_t control; uint32_t control;
...@@ -112,8 +112,7 @@ static void gptm_tick(void *opaque) ...@@ -112,8 +112,7 @@ static void gptm_tick(void *opaque)
s->state |= 1; s->state |= 1;
if ((s->control & 0x20)) { if ((s->control & 0x20)) {
/* Output trigger. */ /* Output trigger. */
qemu_irq_raise(s->trigger); qemu_irq_pulse(s->trigger);
qemu_irq_lower(s->trigger);
} }
if (s->mode[0] & 1) { if (s->mode[0] & 1) {
/* One-shot. */ /* One-shot. */
...@@ -340,19 +339,19 @@ static int gptm_load(QEMUFile *f, void *opaque, int version_id) ...@@ -340,19 +339,19 @@ static int gptm_load(QEMUFile *f, void *opaque, int version_id)
return 0; return 0;
} }
static void stellaris_gptm_init(uint32_t base, qemu_irq irq, qemu_irq trigger) static void stellaris_gptm_init(SysBusDevice *dev)
{ {
int iomemtype; int iomemtype;
gptm_state *s; gptm_state *s = FROM_SYSBUS(gptm_state, dev);
s = (gptm_state *)qemu_mallocz(sizeof(gptm_state)); sysbus_init_irq(dev, &s->irq);
s->irq = irq; qdev_init_gpio_out(&dev->qdev, &s->trigger, 1);
s->trigger = trigger;
s->opaque[0] = s->opaque[1] = s;
iomemtype = cpu_register_io_memory(0, gptm_readfn, iomemtype = cpu_register_io_memory(0, gptm_readfn,
gptm_writefn, s); gptm_writefn, s);
cpu_register_physical_memory(base, 0x00001000, iomemtype); sysbus_init_mmio(dev, 0x1000, iomemtype);
s->opaque[0] = s->opaque[1] = s;
s->timer[0] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[0]); s->timer[0] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[0]);
s->timer[1] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[1]); s->timer[1] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[1]);
register_savevm("stellaris_gptm", -1, 1, gptm_save, gptm_load, s); register_savevm("stellaris_gptm", -1, 1, gptm_save, gptm_load, s);
...@@ -906,6 +905,7 @@ static void stellaris_i2c_init(SysBusDevice * dev) ...@@ -906,6 +905,7 @@ static void stellaris_i2c_init(SysBusDevice * dev)
typedef struct typedef struct
{ {
SysBusDevice busdev;
uint32_t actss; uint32_t actss;
uint32_t ris; uint32_t ris;
uint32_t im; uint32_t im;
...@@ -1178,26 +1178,23 @@ static int stellaris_adc_load(QEMUFile *f, void *opaque, int version_id) ...@@ -1178,26 +1178,23 @@ static int stellaris_adc_load(QEMUFile *f, void *opaque, int version_id)
return 0; return 0;
} }
static qemu_irq stellaris_adc_init(uint32_t base, qemu_irq *irq) static void stellaris_adc_init(SysBusDevice *dev)
{ {
stellaris_adc_state *s; stellaris_adc_state *s = FROM_SYSBUS(stellaris_adc_state, dev);
int iomemtype; int iomemtype;
qemu_irq *qi;
int n; int n;
s = (stellaris_adc_state *)qemu_mallocz(sizeof(stellaris_adc_state));
for (n = 0; n < 4; n++) { for (n = 0; n < 4; n++) {
s->irq[n] = irq[n]; sysbus_init_irq(dev, &s->irq[n]);
} }
iomemtype = cpu_register_io_memory(0, stellaris_adc_readfn, iomemtype = cpu_register_io_memory(0, stellaris_adc_readfn,
stellaris_adc_writefn, s); stellaris_adc_writefn, s);
cpu_register_physical_memory(base, 0x00001000, iomemtype); sysbus_init_mmio(dev, 0x1000, iomemtype);
stellaris_adc_reset(s); stellaris_adc_reset(s);
qi = qemu_allocate_irqs(stellaris_adc_trigger, s, 1); qdev_init_gpio_in(&dev->qdev, stellaris_adc_trigger, 1);
register_savevm("stellaris_adc", -1, 1, register_savevm("stellaris_adc", -1, 1,
stellaris_adc_save, stellaris_adc_load, s); stellaris_adc_save, stellaris_adc_load, s);
return qi[0];
} }
/* Some boards have both an OLED controller and SD card connected to /* Some boards have both an OLED controller and SD card connected to
...@@ -1294,27 +1291,36 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, ...@@ -1294,27 +1291,36 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31}; static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
qemu_irq *pic; qemu_irq *pic;
qemu_irq *gpio_in[7]; DeviceState *gpio_dev[7];
qemu_irq *gpio_out[7]; qemu_irq gpio_in[7][8];
qemu_irq gpio_out[7][8];
qemu_irq adc; qemu_irq adc;
int sram_size; int sram_size;
int flash_size; int flash_size;
i2c_bus *i2c; i2c_bus *i2c;
DeviceState *dev;
int i; int i;
int j;
flash_size = ((board->dc0 & 0xffff) + 1) << 1; flash_size = ((board->dc0 & 0xffff) + 1) << 1;
sram_size = (board->dc0 >> 18) + 1; sram_size = (board->dc0 >> 18) + 1;
pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model); pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model);
if (board->dc1 & (1 << 16)) { if (board->dc1 & (1 << 16)) {
adc = stellaris_adc_init(0x40038000, pic + 14); dev = sysbus_create_varargs("stellaris-adc", 0x40038000,
pic[14], pic[15], pic[16], pic[17], NULL);
adc = qdev_get_gpio_in(dev, 0);
} else { } else {
adc = NULL; adc = NULL;
} }
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if (board->dc2 & (0x10000 << i)) { if (board->dc2 & (0x10000 << i)) {
stellaris_gptm_init(0x40030000 + i * 0x1000, dev = sysbus_create_simple("stellaris-gptm",
pic[timer_irq[i]], adc); 0x40030000 + i * 0x1000,
pic[timer_irq[i]]);
/* TODO: This is incorrect, but we get away with it because
the ADC output is only ever pulsed. */
qdev_connect_gpio_out(dev, 0, adc);
} }
} }
...@@ -1322,13 +1328,16 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, ...@@ -1322,13 +1328,16 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
for (i = 0; i < 7; i++) { for (i = 0; i < 7; i++) {
if (board->dc4 & (1 << i)) { if (board->dc4 & (1 << i)) {
gpio_in[i] = pl061_init(gpio_addr[i], pic[gpio_irq[i]], gpio_dev[i] = sysbus_create_simple("pl061", gpio_addr[i],
&gpio_out[i]); pic[gpio_irq[i]]);
for (j = 0; j < 8; j++) {
gpio_in[i][j] = qdev_get_gpio_in(gpio_dev[i], j);
gpio_out[i][j] = NULL;
}
} }
} }
if (board->dc2 & (1 << 12)) { if (board->dc2 & (1 << 12)) {
DeviceState *dev;
dev = sysbus_create_simple("stellaris-i2c", 0x40020000, pic[8]); dev = sysbus_create_simple("stellaris-i2c", 0x40020000, pic[8]);
i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
if (board->peripherals & BP_OLED_I2C) { if (board->peripherals & BP_OLED_I2C) {
...@@ -1343,7 +1352,6 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, ...@@ -1343,7 +1352,6 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
} }
} }
if (board->dc2 & (1 << 4)) { if (board->dc2 & (1 << 4)) {
DeviceState *dev;
dev = sysbus_create_simple("pl022", 0x40008000, pic[7]); dev = sysbus_create_simple("pl022", 0x40008000, pic[7]);
if (board->peripherals & BP_OLED_SSI) { if (board->peripherals & BP_OLED_SSI) {
DeviceState *mux; DeviceState *mux;
...@@ -1387,6 +1395,15 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, ...@@ -1387,6 +1395,15 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
stellaris_gamepad_init(5, gpad_irq, gpad_keycode); stellaris_gamepad_init(5, gpad_irq, gpad_keycode);
} }
for (i = 0; i < 7; i++) {
if (board->dc4 & (1 << i)) {
for (j = 0; j < 8; j++) {
if (gpio_out[i][j]) {
qdev_connect_gpio_out(gpio_dev[i], j, gpio_out[i][j]);
}
}
}
}
} }
/* FIXME: Figure out how to generate these from stellaris_boards. */ /* FIXME: Figure out how to generate these from stellaris_boards. */
...@@ -1435,6 +1452,10 @@ static void stellaris_register_devices(void) ...@@ -1435,6 +1452,10 @@ static void stellaris_register_devices(void)
{ {
sysbus_register_dev("stellaris-i2c", sizeof(stellaris_i2c_state), sysbus_register_dev("stellaris-i2c", sizeof(stellaris_i2c_state),
stellaris_i2c_init); stellaris_i2c_init);
sysbus_register_dev("stellaris-gptm", sizeof(gptm_state),
stellaris_gptm_init);
sysbus_register_dev("stellaris-adc", sizeof(stellaris_adc_state),
stellaris_adc_init);
ssi_register_slave("evb6965-ssi", sizeof(stellaris_ssi_bus_state), ssi_register_slave("evb6965-ssi", sizeof(stellaris_ssi_bus_state),
&stellaris_ssi_bus_info); &stellaris_ssi_bus_info);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册