[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 3/4] Stellaris machine config
From: |
M P |
Subject: |
Re: [Qemu-devel] [PATCH 3/4] Stellaris machine config |
Date: |
Thu, 11 Jun 2009 09:21:49 +0100 |
I've been following the tree, and the qdev bits in general since I
have my own stack of patches against a few things.
I'm sure it's been discussed to death already, but I just recently
joined so sorry to add another layer on top.
I don't understand how replacing things with a non-source code file
helps anything in this case. The original stellaris code was rather
bad already compared to some other CPUs/SoC:
+ Not a single #define constant, all encoded in good old HEX.
+ No constants for /anything/ in fact, down to the number of GPIO
ports hard coded to 7 in many places.
+ No way to create a derivative board with /just/ the SoC, and add custom IOs.
So now, with qdev, it's all official, /every value, constant, and
bitfield/ is hard coded, in hex, into a different non-code file, with
no way of derivating or overloading from.
I've seen (well I even done a few) projects that tought that using a
super-duper 'meta file' (xml etc) was a fantastic idea, it turns out
it's never really a fantastic idea, and you spend your time looking at
code that is busy recovering properties from deep down an abstract
(and unreadable) runtime tree to do /anything/.
If you look at your diff here and count lines, it's exactly whats
happening, You replaced about 2 page-worth of straightforward readable
code with countless new pages of entirely unrelated non-code. In fact,
the stellaris share /a lot/ between themselves, and there is not a
single shared line between your two stellaris boards definition file.
When I started hacking at qemu to add my own board supports some month
ago, I tought it was the neatest, meanest, "no frill" approach that
made it so cool. You could actualy /follow code thru!/ -- how
refreshing! Now there are a bunch of arcane and ugly /macros/ to
convert blindly struct into others, with no type checking, no
overloading, no methods. It's like even-worse-c++.
Sorry for the rant, I'll go back to idling.
Michel
On Wed, Jun 10, 2009 at 6:38 PM, Paul Brook<address@hidden> wrote:
> Replace hardcoded stellaris boards with machine configs
>
> Signed-off-by: Paul Brook <address@hidden>
> ---
>
> Makefile | 4 -
> Makefile.hw | 2
> hw/arm-cpu.c | 3
> hw/armv7m.c | 61 +++++++++
> hw/gpio-buttons.c | 124 ++++++++++++++++++
> hw/pl011.c | 2
> hw/pl061.c | 25 +++-
> hw/stellaris.c | 272
> +++++++++-------------------------------
> hw/stellaris_enet.c | 2
> hw/stellaris_input.c | 91 -------------
> pc-bios/boards/lm3s6965evb.dts | 212 +++++++++++++++++++++++++++++++
> pc-bios/boards/lm3s811evb.dts | 155 +++++++++++++++++++++++
> 12 files changed, 645 insertions(+), 308 deletions(-)
> create mode 100644 hw/gpio-buttons.c
> delete mode 100644 hw/stellaris_input.c
> create mode 100644 pc-bios/boards/lm3s6965evb.dts
> create mode 100644 pc-bios/boards/lm3s811evb.dts
>
> diff --git a/Makefile b/Makefile
> index 6d15c44..48a3ec3 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -46,7 +46,7 @@ endif
> #######################################################################
> # Board descriptions
>
> -BOARDS = syborg
> +BOARDS = syborg lm3s811evb lm3s6965evb
>
> ifdef DTC
> BOARDS_BIN = $(BOARDS:%=pc-bios/boards/%.dtb)
> @@ -115,7 +115,7 @@ OBJS+=readline.o console.o
>
> OBJS+=irq.o ptimer.o
> OBJS+=i2c.o smbus.o smbus_eeprom.o max7310.o max111x.o wm8750.o
> -OBJS+=ssd0303.o ssd0323.o ads7846.o stellaris_input.o twl92230.o
> +OBJS+=ssd0303.o ssd0323.o ads7846.o twl92230.o
> OBJS+=tmp105.o lm832x.o eeprom93xx.o tsc2005.o
> OBJS+=scsi-disk.o cdrom.o
> OBJS+=scsi-generic.o
> diff --git a/Makefile.hw b/Makefile.hw
> index 6accb3b..1953b85 100644
> --- a/Makefile.hw
> +++ b/Makefile.hw
> @@ -28,6 +28,8 @@ OBJS+= lsi53c895a.o esp.o
>
> OBJS+= dma-helpers.o sysbus.o
>
> +OBJS+= gpio-buttons.o
> +
> all: $(HWLIB)
> # Dummy command so that make thinks it has done something
> address@hidden
> diff --git a/hw/arm-cpu.c b/hw/arm-cpu.c
> index c15eb12..4c128d1 100644
> --- a/hw/arm-cpu.c
> +++ b/hw/arm-cpu.c
> @@ -17,7 +17,8 @@ static const struct {
> const char *cpuname;
> } cpu_device_name_map[] = {
> {"ARM,ARM926EJ-S", "arm926"},
> - {"ARM,Cortex-A8", "cortex-a8"}
> + {"ARM,Cortex-A8", "cortex-a8"},
> + {"ARM,Cortex-M3", "cortex-m3"}
> };
>
> typedef struct {
> diff --git a/hw/armv7m.c b/hw/armv7m.c
> index c3c5b9e..d74a2fb 100644
> --- a/hw/armv7m.c
> +++ b/hw/armv7m.c
> @@ -10,6 +10,7 @@
> #include "sysbus.h"
> #include "arm-misc.h"
> #include "sysemu.h"
> +#include "boards.h"
>
> /* Bitbanded IO. Each word corresponds to a single bit. */
>
> @@ -149,6 +150,47 @@ static void armv7m_bitband_init(void)
> }
>
> /* Board init. */
> +/* Reset initialization and iage loading for ARMv7-M cores. */
> +static void armv7m_bootstrap(ram_addr_t ram_size, const char *boot_device,
> + const char *kernel_filename, const char *kernel_cmdline,
> + const char *initrd_filename)
> +{
> + CPUState *env = first_cpu;
> + uint32_t pc;
> + int image_size;
> + uint64_t entry;
> + uint64_t lowaddr;
> +
> + image_size = load_elf(kernel_filename, 0, &entry, &lowaddr, NULL);
> + if (image_size < 0) {
> + image_size = load_image_targphys(kernel_filename, 0, ram_size);
> + lowaddr = 0;
> + }
> + if (image_size < 0) {
> + fprintf(stderr, "qemu: could not load kernel '%s'\n",
> + kernel_filename);
> + exit(1);
> + }
> +
> + /* If the image was loaded at address zero then assume it is a
> + regular ROM image and perform the normal CPU reset sequence.
> + Otherwise jump directly to the entry point. */
> + if (lowaddr == 0) {
> + env->regs[13] = ldl_phys(0);
> + pc = ldl_phys(4);
> + } else {
> + pc = entry;
> + }
> + env->thumb = pc & 1;
> + env->regs[15] = pc & ~1;
> +
> + /* Hack to map an additional page of ram at the top of the address
> + space. This stops qemu complaining about executing code outside RAM
> + when returning from an exception. */
> + cpu_register_physical_memory(0xfffff000, 0x1000,
> + qemu_ram_alloc(0x1000) | IO_MEM_RAM);
> +}
> +
> /* Init CPU and memory for a v7-M based board.
> flash_size and sram_size are in kb.
> Returns the NVIC array. */
> @@ -238,10 +280,25 @@ qemu_irq *armv7m_init(int flash_size, int sram_size,
> return pic;
> }
>
> +static SysBusDeviceInfo bitband_info = {
> + .init = bitband_init,
> + .qdev.props = (DevicePropList[]) {
> + {.name = "base", .type = PROP_TYPE_INT},
> + {.name = NULL}
> + }
> +};
> +
> static void armv7m_register_devices(void)
> {
> - sysbus_register_dev("ARM,bitband-memory", sizeof(BitBandState),
> - bitband_init);
> + sysbus_register_withprop("ARM,bitband-memory", sizeof(BitBandState),
> + &bitband_info);
> }
>
> device_init(armv7m_register_devices)
> +
> +static void armv7m_boot_register(void)
> +{
> + register_machine_bootstrap("ARMv7-M", armv7m_bootstrap);
> +}
> +
> +machine_init(armv7m_boot_register);
> diff --git a/hw/gpio-buttons.c b/hw/gpio-buttons.c
> new file mode 100644
> index 0000000..0627818
> --- /dev/null
> +++ b/hw/gpio-buttons.c
> @@ -0,0 +1,124 @@
> +/*
> + * Buttons connected directly to GPIO pins.
> + *
> + * Copyright (c) 2009 CodeSourcery.
> + * Written by Paul Brook
> + *
> + * This code is licenced under the GNU GPL v2.
> + */
> +#include "sysbus.h"
> +#include "console.h"
> +
> +#define KEY_INVERT 0x80000000u
> +#define KEY_CODE_MASK 0x0000ffffu
> +
> +typedef struct {
> + SysBusDevice busdev;
> + qemu_irq *irq;
> + const uint32_t *keys;
> + int *pressed;
> + int num_buttons;
> + int extension;
> +} GPIOButtonsState;
> +
> +static void gpio_buttons_put_key(void *opaque, int keycode)
> +{
> + GPIOButtonsState *s = (GPIOButtonsState *)opaque;
> + int i;
> + int down;
> +
> + if (keycode == 0xe0 && !s->extension) {
> + s->extension = 0x80;
> + return;
> + }
> +
> + down = (keycode & 0x80) == 0;
> + keycode = (keycode & 0x7f) | s->extension;
> +
> + for (i = 0; i < s->num_buttons; i++) {
> + if ((s->keys[i] & KEY_CODE_MASK) == keycode
> + && s->pressed[i] != down) {
> + s->pressed[i] = down;
> + if (s->keys[i] & KEY_INVERT) {
> + qemu_set_irq(s->irq[i], !down);
> + } else {
> + qemu_set_irq(s->irq[i], down);
> + }
> + }
> + }
> +
> + s->extension = 0;
> +}
> +
> +static void gpio_buttons_save(QEMUFile *f, void *opaque)
> +{
> + GPIOButtonsState *s = (GPIOButtonsState *)opaque;
> + int i;
> +
> + qemu_put_be32(f, s->extension);
> + for (i = 0; i < s->num_buttons; i++)
> + qemu_put_byte(f, s->pressed[i]);
> +}
> +
> +static int gpio_buttons_load(QEMUFile *f, void *opaque, int version_id)
> +{
> + GPIOButtonsState *s = (GPIOButtonsState *)opaque;
> + int i;
> +
> + if (version_id != 1)
> + return -EINVAL;
> +
> + s->extension = qemu_get_be32(f);
> + for (i = 0; i < s->num_buttons; i++)
> + s->pressed[i] = qemu_get_byte(f);
> +
> + return 0;
> +}
> +
> +static void gpio_buttons_late_init(DeviceState *dev)
> +{
> + GPIOButtonsState *s = FROM_SYSBUS(GPIOButtonsState,
> sysbus_from_qdev(dev));
> + int i;
> +
> + for (i = 0; i < s->num_buttons; i++) {
> + if (s->keys[i] & KEY_INVERT) {
> + qemu_irq_raise(s->irq[i]);
> + }
> + }
> +}
> +
> +static void gpio_buttons_init(SysBusDevice *dev)
> +{
> + GPIOButtonsState *s = FROM_SYSBUS(GPIOButtonsState, dev);
> +
> + s->num_buttons = qdev_get_prop_array(&dev->qdev, "keys", &s->keys);
> + if (s->num_buttons <= 0) {
> + hw_error("gpio-buttons: Missing keys property");
> + }
> +
> + s->irq = qemu_mallocz(sizeof(qemu_irq) * s->num_buttons);
> + qdev_init_gpio_out(&dev->qdev, s->irq, s->num_buttons);
> + s->pressed = qemu_mallocz(sizeof(int) * s->num_buttons);
> + qemu_add_kbd_event_handler(gpio_buttons_put_key, s);
> + register_savevm("gpio-buttons", -1, 1,
> + gpio_buttons_save, gpio_buttons_load, s);
> +}
> +
> +static SysBusDeviceInfo gpio_buttons_info = {
> + .init = gpio_buttons_init,
> + .qdev.late_init = gpio_buttons_late_init,
> + .qdev.props = (DevicePropList[]) {
> + {.name = "keys", .type = PROP_TYPE_ARRAY},
> + {.name = NULL}
> + }
> +};
> +
> +static void gpio_buttons_register_devices(void)
> +{
> + /* ??? This isn't really attached to the system bus, but it's as good
> + a place as any to put it. */
> + sysbus_register_withprop("qemu,gpio-buttons", sizeof(GPIOButtonsState),
> + &gpio_buttons_info);
> +}
> +
> +device_init(gpio_buttons_register_devices)
> diff --git a/hw/pl011.c b/hw/pl011.c
> index 3a1a4cb..f167bec 100644
> --- a/hw/pl011.c
> +++ b/hw/pl011.c
> @@ -323,7 +323,7 @@ static void pl011_register_devices(void)
> {
> sysbus_register_dev("pl011", sizeof(pl011_state),
> pl011_init_arm);
> - sysbus_register_dev("pl011_luminary", sizeof(pl011_state),
> + sysbus_register_dev("luminary,pl011", sizeof(pl011_state),
> pl011_init_luminary);
> }
>
> diff --git a/hw/pl061.c b/hw/pl061.c
> index aa0a322..8e38bd6 100644
> --- a/hw/pl061.c
> +++ b/hw/pl061.c
> @@ -291,6 +291,18 @@ static int pl061_load(QEMUFile *f, void *opaque, int
> version_id)
> return 0;
> }
>
> +static void pl061_late_init(DeviceState *dev)
> +{
> + pl061_state *s = FROM_SYSBUS(pl061_state, sysbus_from_qdev(dev));
> + int i;
> +
> + for (i = 0; i < 8; i++) {
> + if (s->float_high & (1 << i)) {
> + qemu_irq_raise(s->out[i]);
> + }
> + }
> +}
> +
> static void pl061_init(SysBusDevice *dev)
> {
> int iomemtype;
> @@ -302,14 +314,23 @@ static void pl061_init(SysBusDevice *dev)
> 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);
> + s->float_high = qdev_get_prop_int(&dev->qdev, "float-high", 0);
> pl061_reset(s);
> register_savevm("pl061_gpio", -1, 1, pl061_save, pl061_load, s);
> }
>
> +static SysBusDeviceInfo pl061_info = {
> + .init = pl061_init,
> + .qdev.late_init = pl061_late_init,
> + .qdev.props = (DevicePropList[]) {
> + {.name = "float-high", .type = PROP_TYPE_INT},
> + {.name = NULL}
> + }
> +};
> static void pl061_register_devices(void)
> {
> - sysbus_register_dev("pl061", sizeof(pl061_state),
> - pl061_init);
> + sysbus_register_withprop("pl061", sizeof(pl061_state),
> + &pl061_info);
> }
>
> device_init(pl061_register_devices)
> diff --git a/hw/stellaris.c b/hw/stellaris.c
> index 38b9830..ba5b11f 100644
> --- a/hw/stellaris.c
> +++ b/hw/stellaris.c
> @@ -361,6 +361,7 @@ static void stellaris_gptm_init(SysBusDevice *dev)
> /* System controller. */
>
> typedef struct {
> + SysBusDevice busdev;
> uint32_t pborctl;
> uint32_t ldopctl;
> uint32_t int_status;
> @@ -374,8 +375,12 @@ typedef struct {
> uint32_t ldoarst;
> uint32_t user0;
> uint32_t user1;
> + uint32_t did0;
> + uint32_t did1;
> + uint32_t dc[4];
> qemu_irq irq;
> - stellaris_board_info *board;
> + int got_mac;
> + DeviceState *netdev;
> } ssys_state;
>
> static void ssys_update(ssys_state *s)
> @@ -421,25 +426,38 @@ static uint32_t pllcfg_fury[16] = {
> 0xb11c /* 8.192 Mhz */
> };
>
> +static void ssys_get_mac(ssys_state *s)
> +{
> + uint8_t macaddr[6];
> +
> + s->got_mac = 1;
> + if (!s->netdev) {
> + return;
> + }
> + qdev_get_macaddr(s->netdev, macaddr);
> + s->user0 = macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16);
> + s->user1 = macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16);
> +}
> +
> static uint32_t ssys_read(void *opaque, target_phys_addr_t offset)
> {
> ssys_state *s = (ssys_state *)opaque;
>
> switch (offset) {
> case 0x000: /* DID0 */
> - return s->board->did0;
> + return s->did0;
> case 0x004: /* DID1 */
> - return s->board->did1;
> + return s->did1;
> case 0x008: /* DC0 */
> - return s->board->dc0;
> + return s->dc[0];
> case 0x010: /* DC1 */
> - return s->board->dc1;
> + return s->dc[1];
> case 0x014: /* DC2 */
> - return s->board->dc2;
> + return s->dc[2];
> case 0x018: /* DC3 */
> - return s->board->dc3;
> + return s->dc[3];
> case 0x01c: /* DC4 */
> - return s->board->dc4;
> + return s->dc[4];
> case 0x030: /* PBORCTL */
> return s->pborctl;
> case 0x034: /* LDOPCTL */
> @@ -464,7 +482,7 @@ static uint32_t ssys_read(void *opaque,
> target_phys_addr_t offset)
> {
> int xtal;
> xtal = (s->rcc >> 6) & 0xf;
> - if (s->board->did0 & (1 << 16)) {
> + if (s->did0 & (1 << 16)) {
> return pllcfg_fury[xtal];
> } else {
> return pllcfg_sandstorm[xtal];
> @@ -493,8 +511,14 @@ static uint32_t ssys_read(void *opaque,
> target_phys_addr_t offset)
> case 0x160: /* LDOARST */
> return s->ldoarst;
> case 0x1e0: /* USER0 */
> + if (!s->got_mac) {
> + ssys_get_mac(s);
> + }
> return s->user0;
> case 0x1e4: /* USER1 */
> + if (!s->got_mac) {
> + ssys_get_mac(s);
> + }
> return s->user1;
> default:
> hw_error("ssys_read: Bad offset 0x%x\n", (int)offset);
> @@ -654,23 +678,25 @@ static int ssys_load(QEMUFile *f, void *opaque, int
> version_id)
> return 0;
> }
>
> -static void stellaris_sys_init(uint32_t base, qemu_irq irq,
> - stellaris_board_info * board,
> - uint8_t *macaddr)
> +static void stellaris_sysctl_init(SysBusDevice *dev)
> {
> int iomemtype;
> - ssys_state *s;
> -
> - s = (ssys_state *)qemu_mallocz(sizeof(ssys_state));
> - s->irq = irq;
> - s->board = board;
> - /* Most devices come preprogrammed with a MAC address in the user data.
> */
> - s->user0 = macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16);
> - s->user1 = macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16);
> + ssys_state *s = FROM_SYSBUS(ssys_state, dev);
>
> iomemtype = cpu_register_io_memory(0, ssys_readfn,
> ssys_writefn, s);
> - cpu_register_physical_memory(base, 0x00001000, iomemtype);
> + sysbus_init_mmio(dev, 0x1000, iomemtype);
> + sysbus_init_irq(dev, &s->irq);
> + s->netdev = qdev_get_prop_dev(&dev->qdev, "enet");
> + s->got_mac = 0;
> + s->did0 = qdev_get_prop_int(&dev->qdev, "did0", 0);
> + s->did1 = qdev_get_prop_int(&dev->qdev, "did1", 0);
> + s->dc[0] = qdev_get_prop_int(&dev->qdev, "dc0", 0);
> + s->dc[1] = qdev_get_prop_int(&dev->qdev, "dc1", 0);
> + s->dc[2] = qdev_get_prop_int(&dev->qdev, "dc2", 0);
> + s->dc[3] = qdev_get_prop_int(&dev->qdev, "dc3", 0);
> + s->dc[4] = qdev_get_prop_int(&dev->qdev, "dc4", 0);
> +
> ssys_reset(s);
> register_savevm("stellaris_sys", -1, 1, ssys_save, ssys_load, s);
> }
> @@ -1256,200 +1282,30 @@ static void stellaris_ssi_bus_init(SSISlave *dev)
> stellaris_ssi_bus_save, stellaris_ssi_bus_load, s);
> }
>
> -/* Board init. */
> -static stellaris_board_info stellaris_boards[] = {
> - { "LM3S811EVB",
> - 0,
> - 0x0032000e,
> - 0x001f001f, /* dc0 */
> - 0x001132bf,
> - 0x01071013,
> - 0x3f0f01ff,
> - 0x0000001f,
> - BP_OLED_I2C
> - },
> - { "LM3S6965EVB",
> - 0x10010002,
> - 0x1073402e,
> - 0x00ff007f, /* dc0 */
> - 0x001133ff,
> - 0x030f5317,
> - 0x0f0f87ff,
> - 0x5000007f,
> - BP_OLED_SSI | BP_GAMEPAD
> - }
> -};
> -
> -static void stellaris_init(const char *kernel_filename, const char
> *cpu_model,
> - stellaris_board_info *board)
> -{
> - static const int uart_irq[] = {5, 6, 33, 34};
> - static const int timer_irq[] = {19, 21, 23, 35};
> - static const uint32_t gpio_addr[7] =
> - { 0x40004000, 0x40005000, 0x40006000, 0x40007000,
> - 0x40024000, 0x40025000, 0x40026000};
> - static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
> -
> - qemu_irq *pic;
> - DeviceState *gpio_dev[7];
> - qemu_irq gpio_in[7][8];
> - qemu_irq gpio_out[7][8];
> - qemu_irq adc;
> - int sram_size;
> - int flash_size;
> - i2c_bus *i2c;
> - DeviceState *dev;
> - int i;
> - int j;
> -
> - flash_size = ((board->dc0 & 0xffff) + 1) << 1;
> - sram_size = (board->dc0 >> 18) + 1;
> - pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model);
> -
> - if (board->dc1 & (1 << 16)) {
> - dev = sysbus_create_varargs("stellaris-adc", 0x40038000,
> - pic[14], pic[15], pic[16], pic[17],
> NULL);
> - adc = qdev_get_gpio_in(dev, 0);
> - } else {
> - adc = NULL;
> - }
> - for (i = 0; i < 4; i++) {
> - if (board->dc2 & (0x10000 << i)) {
> - dev = sysbus_create_simple("stellaris-gptm",
> - 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);
> - }
> - }
> -
> - stellaris_sys_init(0x400fe000, pic[28], board, nd_table[0].macaddr);
> -
> - for (i = 0; i < 7; i++) {
> - if (board->dc4 & (1 << i)) {
> - gpio_dev[i] = sysbus_create_simple("pl061", gpio_addr[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)) {
> - dev = sysbus_create_simple("stellaris-i2c", 0x40020000, pic[8]);
> - i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
> - if (board->peripherals & BP_OLED_I2C) {
> - i2c_create_slave(i2c, "ssd0303", 0x3d);
> - }
> - }
> -
> - for (i = 0; i < 4; i++) {
> - if (board->dc2 & (1 << i)) {
> - sysbus_create_simple("pl011_luminary", 0x4000c000 + i * 0x1000,
> - pic[uart_irq[i]]);
> - }
> - }
> - if (board->dc2 & (1 << 4)) {
> - dev = sysbus_create_simple("pl022", 0x40008000, pic[7]);
> - if (board->peripherals & BP_OLED_SSI) {
> - DeviceState *mux;
> - void *bus;
> -
> - bus = qdev_get_child_bus(dev, "ssi");
> - mux = ssi_create_slave(bus, "evb6965-ssi");
> - gpio_out[GPIO_D][0] = qdev_get_gpio_in(mux, 0);
> -
> - bus = qdev_get_child_bus(mux, "ssi0");
> - dev = ssi_create_slave(bus, "ssi-sd");
> -
> - bus = qdev_get_child_bus(mux, "ssi1");
> - dev = ssi_create_slave(bus, "ssd0323");
> - gpio_out[GPIO_C][7] = qdev_get_gpio_in(dev, 0);
> -
> - /* Make sure the select pin is high. */
> - qemu_irq_raise(gpio_out[GPIO_D][0]);
> - }
> - }
> - if (board->dc4 & (1 << 28)) {
> - DeviceState *enet;
> -
> - qemu_check_nic_model(&nd_table[0], "stellaris");
> -
> - enet = qdev_create(NULL, "stellaris_enet");
> - qdev_set_netdev(enet, &nd_table[0]);
> - qdev_init(enet);
> - sysbus_mmio_map(sysbus_from_qdev(enet), 0, 0x40048000);
> - sysbus_connect_irq(sysbus_from_qdev(enet), 0, pic[42]);
> - }
> - if (board->peripherals & BP_GAMEPAD) {
> - qemu_irq gpad_irq[5];
> - static const int gpad_keycode[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d };
> -
> - gpad_irq[0] = qemu_irq_invert(gpio_in[GPIO_E][0]); /* up */
> - gpad_irq[1] = qemu_irq_invert(gpio_in[GPIO_E][1]); /* down */
> - gpad_irq[2] = qemu_irq_invert(gpio_in[GPIO_E][2]); /* left */
> - gpad_irq[3] = qemu_irq_invert(gpio_in[GPIO_E][3]); /* right */
> - gpad_irq[4] = qemu_irq_invert(gpio_in[GPIO_F][1]); /* select */
> -
> - 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. */
> -static void lm3s811evb_init(ram_addr_t ram_size,
> - const char *boot_device,
> - const char *kernel_filename, const char *kernel_cmdline,
> - const char *initrd_filename, const char *cpu_model)
> -{
> - stellaris_init(kernel_filename, cpu_model, &stellaris_boards[0]);
> -}
> -
> -static void lm3s6965evb_init(ram_addr_t ram_size,
> - const char *boot_device,
> - const char *kernel_filename, const char *kernel_cmdline,
> - const char *initrd_filename, const char *cpu_model)
> -{
> - stellaris_init(kernel_filename, cpu_model, &stellaris_boards[1]);
> -}
> -
> -static QEMUMachine lm3s811evb_machine = {
> - .name = "lm3s811evb",
> - .desc = "Stellaris LM3S811EVB",
> - .init = lm3s811evb_init,
> -};
> -
> -static QEMUMachine lm3s6965evb_machine = {
> - .name = "lm3s6965evb",
> - .desc = "Stellaris LM3S6965EVB",
> - .init = lm3s6965evb_init,
> -};
> -
> -static void stellaris_machine_init(void)
> -{
> - qemu_register_machine(&lm3s811evb_machine);
> - qemu_register_machine(&lm3s6965evb_machine);
> -}
> -
> -machine_init(stellaris_machine_init);
> -
> static SSISlaveInfo stellaris_ssi_bus_info = {
> .init = stellaris_ssi_bus_init,
> .transfer = stellaris_ssi_bus_transfer
> };
>
> +static SysBusDeviceInfo ssys_info = {
> + .init = stellaris_sysctl_init,
> + .qdev.props = (DevicePropList[]) {
> + {.name = "enet", .type = PROP_TYPE_DEV},
> + {.name = "did0", .type = PROP_TYPE_INT},
> + {.name = "did1", .type = PROP_TYPE_INT},
> + {.name = "dc0", .type = PROP_TYPE_INT},
> + {.name = "dc1", .type = PROP_TYPE_INT},
> + {.name = "dc2", .type = PROP_TYPE_INT},
> + {.name = "dc3", .type = PROP_TYPE_INT},
> + {.name = "dc4", .type = PROP_TYPE_INT},
> + {.name = NULL}
> + }
> +};
> +
> static void stellaris_register_devices(void)
> {
> + sysbus_register_withprop("stellaris-sysctl", sizeof(ssys_state),
> + &ssys_info);
> sysbus_register_dev("stellaris-i2c", sizeof(stellaris_i2c_state),
> stellaris_i2c_init);
> sysbus_register_dev("stellaris-gptm", sizeof(gptm_state),
> diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c
> index 36fabd3..86df231 100644
> --- a/hw/stellaris_enet.c
> +++ b/hw/stellaris_enet.c
> @@ -417,7 +417,7 @@ static void stellaris_enet_init(SysBusDevice *dev)
>
> static void stellaris_enet_register_devices(void)
> {
> - sysbus_register_dev("stellaris_enet", sizeof(stellaris_enet_state),
> + sysbus_register_dev("stellaris-enet", sizeof(stellaris_enet_state),
> stellaris_enet_init);
> }
>
> diff --git a/hw/stellaris_input.c b/hw/stellaris_input.c
> deleted file mode 100644
> index 33395a4..0000000
> --- a/hw/stellaris_input.c
> +++ /dev/null
> @@ -1,91 +0,0 @@
> -/*
> - * Gamepad style buttons connected to IRQ/GPIO lines
> - *
> - * Copyright (c) 2007 CodeSourcery.
> - * Written by Paul Brook
> - *
> - * This code is licenced under the GPL.
> - */
> -#include "hw.h"
> -#include "devices.h"
> -#include "console.h"
> -
> -typedef struct {
> - qemu_irq irq;
> - int keycode;
> - int pressed;
> -} gamepad_button;
> -
> -typedef struct {
> - gamepad_button *buttons;
> - int num_buttons;
> - int extension;
> -} gamepad_state;
> -
> -static void stellaris_gamepad_put_key(void * opaque, int keycode)
> -{
> - gamepad_state *s = (gamepad_state *)opaque;
> - int i;
> - int down;
> -
> - if (keycode == 0xe0 && !s->extension) {
> - s->extension = 0x80;
> - return;
> - }
> -
> - down = (keycode & 0x80) == 0;
> - keycode = (keycode & 0x7f) | s->extension;
> -
> - for (i = 0; i < s->num_buttons; i++) {
> - if (s->buttons[i].keycode == keycode
> - && s->buttons[i].pressed != down) {
> - s->buttons[i].pressed = down;
> - qemu_set_irq(s->buttons[i].irq, down);
> - }
> - }
> -
> - s->extension = 0;
> -}
> -
> -static void stellaris_gamepad_save(QEMUFile *f, void *opaque)
> -{
> - gamepad_state *s = (gamepad_state *)opaque;
> - int i;
> -
> - qemu_put_be32(f, s->extension);
> - for (i = 0; i < s->num_buttons; i++)
> - qemu_put_byte(f, s->buttons[i].pressed);
> -}
> -
> -static int stellaris_gamepad_load(QEMUFile *f, void *opaque, int version_id)
> -{
> - gamepad_state *s = (gamepad_state *)opaque;
> - int i;
> -
> - if (version_id != 1)
> - return -EINVAL;
> -
> - s->extension = qemu_get_be32(f);
> - for (i = 0; i < s->num_buttons; i++)
> - s->buttons[i].pressed = qemu_get_byte(f);
> -
> - return 0;
> -}
> -
> -/* Returns an array 5 ouput slots. */
> -void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
> -{
> - gamepad_state *s;
> - int i;
> -
> - s = (gamepad_state *)qemu_mallocz(sizeof (gamepad_state));
> - s->buttons = (gamepad_button *)qemu_mallocz(n * sizeof (gamepad_button));
> - for (i = 0; i < n; i++) {
> - s->buttons[i].irq = irq[i];
> - s->buttons[i].keycode = keycode[i];
> - }
> - s->num_buttons = n;
> - qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s);
> - register_savevm("stellaris_gamepad", -1, 1,
> - stellaris_gamepad_save, stellaris_gamepad_load, s);
> -}
> diff --git a/pc-bios/boards/lm3s6965evb.dts b/pc-bios/boards/lm3s6965evb.dts
> new file mode 100644
> index 0000000..9bc0128
> --- /dev/null
> +++ b/pc-bios/boards/lm3s6965evb.dts
> @@ -0,0 +1,212 @@
> +/ {
> + #address-cells = <1>;
> + #size-cells = <1>;
> +
> + cpus {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + cpu0: ARM,address@hidden {
> + device_type = "cpu";
> + reg = <0>;
> + #interrupt-cells = <1>;
> + nvic = <&nvic>;
> + };
> + };
> + address@hidden {
> + device_type = "rom";
> + reg = <00000000 00040000>;
> + };
> + address@hidden {
> + device_type = "memory";
> + reg = <20000000 00010000>;
> + };
> + address@hidden {
> + model = "ARM,bitband-memory";
> + reg = <22000000 02000000>;
> + base = <20000000>;
> + };
> + address@hidden {
> + model = "ARM,bitband-memory";
> + reg = <42000000 02000000>;
> + base = <40000000>;
> + };
> + nvic: address@hidden {
> + model = "armv7m_nvic";
> + interrupt-parent = <&cpu0>;
> + interrupts = <0>;
> + interrupt-controller;
> + #interrupt-cells = <1>;
> + };
> + address@hidden {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + qemu,fold-bus;
> + // TODO Watchdog at 0x40000000
> + gpioA: address@hidden {
> + model = "pl061";
> + reg = <40004000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <0>;
> + qemu,gpio = <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>;
> + };
> + gpioB: address@hidden {
> + model = "pl061";
> + reg = <40005000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <1>;
> + qemu,gpio = <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>;
> + };
> + gpioC: address@hidden {
> + model = "pl061";
> + reg = <40006000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <2>;
> + qemu,gpio = <0 0 0 0 0 0 0 0 0 0 0 0 0 0 &oled 0>;
> + };
> + gpioD: address@hidden {
> + model = "pl061";
> + reg = <40007000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <3>;
> + qemu,gpio = <&ssimux 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>;
> + float-high = <01>;
> + };
> + address@hidden {
> + model = "pl022";
> + reg = <40008000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <7>;
> + ssimux: address@hidden {
> + model = "evb6965-ssi";
> + address@hidden {
> + model = "ssi-sd";
> + qemu,parent-bus = "ssi0";
> + };
> + oled: address@hidden {
> + model = "ssd0323";
> + qemu,parent-bus = "ssi1";
> + };
> + };
> + };
> + address@hidden {
> + model = "luminary,pl011";
> + reg = <4000c000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <5>;
> + };
> + address@hidden {
> + model = "luminary,pl011";
> + reg = <4000d000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <6>;
> + };
> + address@hidden {
> + model = "luminary,pl011";
> + reg = <4000e000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <d#33>;
> + };
> + address@hidden {
> + model = "stellaris-i2c";
> + reg = <40020000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <8>;
> + };
> + address@hidden {
> + model = "stellaris-i2c";
> + reg = <40021000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <d#37>;
> + };
> + gpioE: address@hidden {
> + model = "pl061";
> + reg = <40024000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <4>;
> + qemu,gpio = <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>;
> + };
> + gpioF: address@hidden {
> + model = "pl061";
> + reg = <40025000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <d#30>;
> + qemu,gpio = <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>;
> + };
> + gpioG: address@hidden {
> + model = "pl061";
> + reg = <40026000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <d#31>;
> + qemu,gpio = <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>;
> + };
> + // TODO PWM at 0x40028000
> + // TODO QEI0 at 0x4002c000
> + // TODO QEI1 at 0x4002d000
> + address@hidden {
> + model = "stellaris-gptm";
> + reg = <40030000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <d#19>;
> + qemu,gpio = <&adc0 0>;
> + };
> + address@hidden {
> + model = "stellaris-gptm";
> + reg = <40031000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <d#21>;
> + qemu,gpio = <&adc0 0>;
> + };
> + address@hidden {
> + model = "stellaris-gptm";
> + reg = <40032000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <d#23>;
> + qemu,gpio = <&adc0 0>;
> + };
> + address@hidden {
> + model = "stellaris-gptm";
> + reg = <40033000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <d#35>;
> + qemu,gpio = <&adc0 0>;
> + };
> + adc0: address@hidden {
> + model = "stellaris-adc";
> + reg = <40038000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <d#14 d#15 d#16 d#17>;
> + };
> + // TODO Comparator at 0x4003c000
> + enet: address@hidden {
> + model = "stellaris-enet";
> + reg = <40048000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <d#42>;
> + };
> + // TODO Hybernation module at 0x400fc000
> + address@hidden {
> + model = "stellaris-sysctl";
> + reg = <400fe000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <d#28>;
> + did0 = <10010002>;
> + did1 = <1073402e>;
> + dc0 = <00ff007f>;
> + dc1 = <001133ff>;
> + dc2 = <030f5317>;
> + dc3 = <0f0f87ff>;
> + dc4 = <5000007f>;
> + enet = <&enet>;
> + };
> + address@hidden {
> + model = "qemu,gpio-buttons";
> + keys = <800000c8 800000d0 800000cb 800000cd 8000001d>;
> + qemu,gpio = <&gpioE 0 &gpioE 1 &gpioE 2 &gpioE 3 &gpioF 1>;
> + };
> + };
> + chosen {
> + qemu {
> + bootstrap = "ARMv7-M";
> + };
> + };
> +};
> diff --git a/pc-bios/boards/lm3s811evb.dts b/pc-bios/boards/lm3s811evb.dts
> new file mode 100644
> index 0000000..977d080
> --- /dev/null
> +++ b/pc-bios/boards/lm3s811evb.dts
> @@ -0,0 +1,155 @@
> +/ {
> + #address-cells = <1>;
> + #size-cells = <1>;
> +
> + cpus {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + cpu0: ARM,address@hidden {
> + device_type = "cpu";
> + reg = <0>;
> + #interrupt-cells = <1>;
> + nvic = <&nvic>;
> + };
> + };
> + address@hidden {
> + device_type = "rom";
> + reg = <00000000 00010000>;
> + };
> + address@hidden {
> + device_type = "memory";
> + reg = <20000000 00002000>;
> + };
> + address@hidden {
> + model = "ARM,bitband-memory";
> + reg = <22000000 02000000>;
> + base = <20000000>;
> + };
> + address@hidden {
> + model = "ARM,bitband-memory";
> + reg = <42000000 02000000>;
> + base = <40000000>;
> + };
> + nvic: address@hidden {
> + model = "armv7m_nvic";
> + interrupt-parent = <&cpu0>;
> + interrupts = <0>;
> + interrupt-controller;
> + #interrupt-cells = <1>;
> + };
> + address@hidden {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + qemu,fold-bus;
> + // TODO Watchdog at 0x40000000
> + gpioA: address@hidden {
> + model = "pl061";
> + reg = <40004000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <0>;
> + qemu,gpio = <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>;
> + };
> + gpioB: address@hidden {
> + model = "pl061";
> + reg = <40005000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <1>;
> + qemu,gpio = <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>;
> + };
> + gpioC: address@hidden {
> + model = "pl061";
> + reg = <40006000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <2>;
> + qemu,gpio = <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>;
> + };
> + gpioD: address@hidden {
> + model = "pl061";
> + reg = <40007000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <3>;
> + qemu,gpio = <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>;
> + };
> + address@hidden {
> + model = "pl022";
> + reg = <40008000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <7>;
> + };
> + address@hidden {
> + model = "luminary,pl011";
> + reg = <4000c000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <5>;
> + };
> + address@hidden {
> + model = "luminary,pl011";
> + reg = <4000d000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <6>;
> + };
> + address@hidden {
> + model = "stellaris-i2c";
> + reg = <40020000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <8>;
> + address@hidden {
> + model = "ssd0303";
> + address = <3d>;
> + };
> + };
> + gpioE: address@hidden {
> + model = "pl061";
> + reg = <40024000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <4>;
> + qemu,gpio = <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>;
> + };
> + // TODO PWM at 0x40028000
> + address@hidden {
> + model = "stellaris-gptm";
> + reg = <40030000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <d#19>;
> + qemu,gpio = <&adc0 0>;
> + };
> + address@hidden {
> + model = "stellaris-gptm";
> + reg = <40031000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <d#21>;
> + qemu,gpio = <&adc0 0>;
> + };
> + address@hidden {
> + model = "stellaris-gptm";
> + reg = <40032000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <d#23>;
> + qemu,gpio = <&adc0 0>;
> + };
> + adc0: address@hidden {
> + model = "stellaris-adc";
> + reg = <40038000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <d#14 d#15 d#16 d#17>;
> + };
> + address@hidden {
> + model = "stellaris-sysctl";
> + reg = <400fe000>;
> + interrupt-parent = <&nvic>;
> + interrupts = <d#28>;
> + did0 = <00000000>;
> + did1 = <0032000e>;
> + dc0 = <001f001f>;
> + dc1 = <001132bf>;
> + dc2 = <01071013>;
> + dc3 = <3f0f01ff>;
> + dc4 = <0000001f>;
> + };
> + };
> + chosen {
> + qemu {
> + bootstrap = "ARMv7-M";
> + };
> + };
> +};
>
>
>
>
[Qemu-devel] [PATCH 4/4] Integrator machine config, Paul Brook, 2009/06/10
Re: [Qemu-devel] [PATCH 0/4] Machine config files, Gerd Hoffmann, 2009/06/11
Re: [Qemu-devel] [PATCH 0/4] Machine config files, Gerd Hoffmann, 2009/06/11