qemu-devel
[Top][All Lists]
Advanced

[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";
> +        };
> +    };
> +};
>
>
>
>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]