#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 "qemu/log.h"
#include "exec/address-spaces.h"
#include "sysemu/sysemu.h"
+#include "hw/arm/armv7m.h"
#include "hw/char/pl011.h"
+#include "hw/input/gamepad.h"
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
#include "hw/misc/unimp.h"
+#include "cpu.h"
#define GPIO_A 0
#define GPIO_B 1
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 s->rtc;
}
qemu_log_mask(LOG_UNIMP,
- "GPTM: read of TAR but timer read not supported");
+ "GPTM: read of TAR but timer read not supported\n");
return 0;
case 0x4c: /* TBR */
qemu_log_mask(LOG_UNIMP,
- "GPTM: read of TBR but timer read not supported");
+ "GPTM: read of TBR but timer read not supported\n");
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);
}
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;
/* 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);
break;
case 0x20: /* MCR */
if (value & 1) {
- qemu_log_mask(LOG_UNIMP, "stellaris_i2c: Loopback not implemented");
+ qemu_log_mask(LOG_UNIMP,
+ "stellaris_i2c: Loopback not implemented\n");
}
if (value & 0x20) {
qemu_log_mask(LOG_UNIMP,
- "stellaris_i2c: Slave mode not implemented");
+ "stellaris_i2c: Slave mode not implemented\n");
}
s->mcr = value & 0x31;
break;
s->sspri = value;
break;
case 0x28: /* PSSI */
- qemu_log_mask(LOG_UNIMP, "ADC: sample initiate unimplemented");
+ qemu_log_mask(LOG_UNIMP, "ADC: sample initiate unimplemented\n");
break;
case 0x30: /* SAC */
s->sac = value;
}
};
-static void stellaris_init(const char *kernel_filename, const char *cpu_model,
- stellaris_board_info *board)
+static void stellaris_init(MachineState *ms, stellaris_board_info *board)
{
static const int uart_irq[] = {5, 6, 33, 34};
static const int timer_irq[] = {19, 21, 23, 35};
* 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
/* Flash programming is done via the SCU, so pretend it is ROM. */
memory_region_init_ram(flash, NULL, "stellaris.flash", flash_size,
&error_fatal);
- vmstate_register_ram_global(flash);
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);
- vmstate_register_ram_global(sram);
memory_region_add_subregion(system_memory, 0x20000000, sram);
- nvic = armv7m_init(system_memory, flash_size, NUM_IRQ_LINES,
- kernel_filename, cpu_model);
+ nvic = qdev_create(NULL, 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);
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_create(NULL, 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);
+
+ qdev_init_nofail(dev);
+ 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],
if (board->dc2 & (1 << i)) {
pl011_luminary_create(0x4000c000 + i * 0x1000,
qdev_get_gpio_in(nvic, uart_irq[i]),
- serial_hds[i]);
+ serial_hd(i));
}
}
if (board->dc2 & (1 << 4)) {
/* 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);
create_unimplemented_device("analogue-comparator", 0x4003c000, 0x1000);
create_unimplemented_device("hibernation", 0x400fc000, 0x1000);
create_unimplemented_device("flash-control", 0x400fd000, 0x1000);
+
+ armv7m_load_kernel(ARM_CPU(first_cpu), ms->kernel_filename, flash_size);
}
/* FIXME: Figure out how to generate these from stellaris_boards. */
static void lm3s811evb_init(MachineState *machine)
{
- const char *cpu_model = machine->cpu_model;
- const char *kernel_filename = machine->kernel_filename;
- stellaris_init(kernel_filename, cpu_model, &stellaris_boards[0]);
+ stellaris_init(machine, &stellaris_boards[0]);
}
static void lm3s6965evb_init(MachineState *machine)
{
- const char *cpu_model = machine->cpu_model;
- const char *kernel_filename = machine->kernel_filename;
- stellaris_init(kernel_filename, cpu_model, &stellaris_boards[1]);
+ stellaris_init(machine, &stellaris_boards[1]);
}
static void lm3s811evb_class_init(ObjectClass *oc, void *data)
mc->desc = "Stellaris LM3S811EVB";
mc->init = lm3s811evb_init;
+ mc->ignore_memory_transaction_failures = true;
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3");
}
static const TypeInfo lm3s811evb_type = {
mc->desc = "Stellaris LM3S6965EVB";
mc->init = lm3s6965evb_init;
+ mc->ignore_memory_transaction_failures = true;
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3");
}
static const TypeInfo lm3s6965evb_type = {