[Top][All Lists]
[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";
+ };
+ };
+};
- Re: [Qemu-devel] [PATCH 1/4] Include and build libfdt, (continued)
- [Qemu-devel] [PATCH 3/4] Stellaris machine config,
Paul Brook <=
[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