#include "qapi/error.h"
#include "hw/sysbus.h"
#include "hw/ssi/ssi.h"
-#include "hw/arm/arm.h"
-#include "hw/devices.h"
+#include "hw/arm/boot.h"
#include "qemu/timer.h"
#include "hw/i2c/i2c.h"
#include "net/net.h"
#include "hw/boards.h"
#include "qemu/log.h"
#include "exec/address-spaces.h"
+#include "sysemu/runstate.h"
#include "sysemu/sysemu.h"
#include "hw/arm/armv7m.h"
#include "hw/char/pl011.h"
+#include "hw/input/gamepad.h"
+#include "hw/irq.h"
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
+#include "migration/vmstate.h"
#include "hw/misc/unimp.h"
#include "cpu.h"
s->state |= 1;
if ((s->control & 0x20)) {
/* Output trigger. */
- qemu_irq_pulse(s->trigger);
+ qemu_irq_pulse(s->trigger);
}
if (s->mode[0] & 1) {
/* One-shot. */
return 0;
default:
qemu_log_mask(LOG_GUEST_ERROR,
- "GPTM: read at bad offset 0x%x\n", (int)offset);
+ "GPTM: read at bad offset 0x02%" HWADDR_PRIx "\n",
+ offset);
return 0;
}
}
break;
default:
qemu_log_mask(LOG_GUEST_ERROR,
- "GPTM: read at bad offset 0x%x\n", (int)offset);
+ "GPTM: write at bad offset 0x02%" HWADDR_PRIx "\n",
+ offset);
}
gptm_update_irq(s);
}
sysbus_init_mmio(sbd, &s->iomem);
s->opaque[0] = s->opaque[1] = s;
+}
+
+static void stellaris_gptm_realize(DeviceState *dev, Error **errp)
+{
+ gptm_state *s = STELLARIS_GPTM(dev);
s->timer[0] = timer_new_ns(QEMU_CLOCK_VIRTUAL, gptm_tick, &s->opaque[0]);
s->timer[1] = timer_new_ns(QEMU_CLOCK_VIRTUAL, gptm_tick, &s->opaque[1]);
}
-
/* System controller. */
typedef struct {
case 0x040: /* SRCR0 */
case 0x044: /* SRCR1 */
case 0x048: /* SRCR2 */
- fprintf(stderr, "Peripheral reset not implemented\n");
+ qemu_log_mask(LOG_UNIMP, "Peripheral reset not implemented\n");
break;
case 0x054: /* IMC */
s->int_mask = value & 0x7f;
memory_region_init_io(&s->iomem, NULL, &ssys_ops, s, "ssys", 0x00001000);
memory_region_add_subregion(get_system_memory(), base, &s->iomem);
ssys_reset(s);
- vmstate_register(NULL, -1, &vmstate_stellaris_sys, s);
+ vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_stellaris_sys, s);
return 0;
}
/* TODO: Handle errors. */
if (s->msa & 1) {
/* Recv */
- s->mdr = i2c_recv(s->bus) & 0xff;
+ s->mdr = i2c_recv(s->bus);
} else {
/* Send */
i2c_send(s->bus, s->mdr);
* Stellaris LM3S6965 Microcontroller Data Sheet (rev I)
* http://www.ti.com/lit/ds/symlink/lm3s6965.pdf
*
- * 40000000 wdtimer (unimplemented)
+ * 40000000 wdtimer
* 40002000 i2c (unimplemented)
* 40004000 GPIO
* 40005000 GPIO
sram_size = ((board->dc0 >> 18) + 1) * 1024;
/* Flash programming is done via the SCU, so pretend it is ROM. */
- memory_region_init_ram(flash, NULL, "stellaris.flash", flash_size,
+ memory_region_init_rom(flash, NULL, "stellaris.flash", flash_size,
&error_fatal);
- memory_region_set_readonly(flash, true);
memory_region_add_subregion(system_memory, 0, flash);
memory_region_init_ram(sram, NULL, "stellaris.sram", sram_size,
&error_fatal);
memory_region_add_subregion(system_memory, 0x20000000, sram);
- nvic = qdev_create(NULL, TYPE_ARMV7M);
+ nvic = qdev_new(TYPE_ARMV7M);
qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES);
qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type);
+ qdev_prop_set_bit(nvic, "enable-bitband", true);
object_property_set_link(OBJECT(nvic), OBJECT(get_system_memory()),
"memory", &error_abort);
/* This will exit with an error if the user passed us a bad cpu_type */
- qdev_init_nofail(nvic);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(nvic), &error_fatal);
qdev_connect_gpio_out_named(nvic, "SYSRESETREQ", 0,
qemu_allocate_irq(&do_sys_reset, NULL, 0));
stellaris_sys_init(0x400fe000, qdev_get_gpio_in(nvic, 28),
board, nd_table[0].macaddr.a);
+
+ if (board->dc1 & (1 << 3)) { /* watchdog present */
+ dev = qdev_new(TYPE_LUMINARY_WATCHDOG);
+
+ /* system_clock_scale is valid now */
+ uint32_t mainclk = NANOSECONDS_PER_SECOND / system_clock_scale;
+ qdev_prop_set_uint32(dev, "wdogclk-frq", mainclk);
+
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev),
+ 0,
+ 0x40000000u);
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev),
+ 0,
+ qdev_get_gpio_in(nvic, 18));
+ }
+
+
for (i = 0; i < 7; i++) {
if (board->dc4 & (1 << i)) {
gpio_dev[i] = sysbus_create_simple("pl061_luminary", gpio_addr[i],
qemu_check_nic_model(&nd_table[0], "stellaris");
- enet = qdev_create(NULL, "stellaris_enet");
+ enet = qdev_new("stellaris_enet");
qdev_set_nic_properties(enet, &nd_table[0]);
- qdev_init_nofail(enet);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(enet), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(enet), 0, 0x40048000);
sysbus_connect_irq(SYS_BUS_DEVICE(enet), 0, qdev_get_gpio_in(nvic, 42));
}
/* Add dummy regions for the devices we don't implement yet,
* so guest accesses don't cause unlogged crashes.
*/
- create_unimplemented_device("wdtimer", 0x40000000, 0x1000);
create_unimplemented_device("i2c-0", 0x40002000, 0x1000);
create_unimplemented_device("i2c-2", 0x40021000, 0x1000);
create_unimplemented_device("PWM", 0x40028000, 0x1000);
DeviceClass *dc = DEVICE_CLASS(klass);
dc->vmsd = &vmstate_stellaris_gptm;
+ dc->realize = stellaris_gptm_realize;
}
static const TypeInfo stellaris_gptm_info = {