qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 3/4] Stellaris machine config


From: Paul Brook
Subject: [Qemu-devel] [PATCH 3/4] Stellaris machine config
Date: Wed, 10 Jun 2009 18:38:29 +0100
User-agent: StGIT/0.14.2

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
        @true
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]