[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v9 03/10] target-avr: adding a sample AVR board
From: |
Michael Rolnik |
Subject: |
[Qemu-devel] [PATCH v9 03/10] target-avr: adding a sample AVR board |
Date: |
Wed, 22 Jun 2016 12:51:48 +0300 |
Signed-off-by: Michael Rolnik <address@hidden>
---
MAINTAINERS | 6 ++
hw/avr/Makefile.objs | 21 +++++
hw/avr/sample-io.c | 227 +++++++++++++++++++++++++++++++++++++++++++++++++++
hw/avr/sample.c | 116 ++++++++++++++++++++++++++
4 files changed, 370 insertions(+)
create mode 100644 hw/avr/Makefile.objs
create mode 100644 hw/avr/sample-io.c
create mode 100644 hw/avr/sample.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 2ab6e3b..04060e4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -110,6 +110,12 @@ F: disas/arm.c
F: disas/arm-a64.cc
F: disas/libvixl/
+AVR
+M: Michael Rolnik <address@hidden>
+S: Maintained
+F: target-avr/
+F: hw/avr/
+
CRIS
M: Edgar E. Iglesias <address@hidden>
S: Maintained
diff --git a/hw/avr/Makefile.objs b/hw/avr/Makefile.objs
new file mode 100644
index 0000000..c080e4e
--- /dev/null
+++ b/hw/avr/Makefile.objs
@@ -0,0 +1,21 @@
+#
+# QEMU AVR CPU
+#
+# Copyright (c) 2016 Michael Rolnik
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, see
+# <http://www.gnu.org/licenses/lgpl-2.1.html>
+#
+
+obj-y += sample.o sample-io.o
diff --git a/hw/avr/sample-io.c b/hw/avr/sample-io.c
new file mode 100644
index 0000000..5f5767c
--- /dev/null
+++ b/hw/avr/sample-io.c
@@ -0,0 +1,227 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2016 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "include/hw/sysbus.h"
+
+#define TYPE_SAMPLEIO "SampleIO"
+#define SAMPLEIO(obj) OBJECT_CHECK(SAMPLEIOState, (obj), TYPE_SAMPLEIO)
+
+#ifndef DEBUG_SAMPLEIO
+#define DEBUG_SAMPLEIO 1
+#endif
+
+#define DPRINTF(fmt, args...) \
+ do { \
+ if (DEBUG_SAMPLEIO) { \
+ fprintf(stderr, "[%s]%s: " fmt , TYPE_SAMPLEIO, __func__, ##args);\
+ } \
+ } \
+ while (0)
+
+#define AVR_IO_CPU_REGS_SIZE 0x0020
+#define AVR_IO_CPU_IO_SIZE 0x0040
+#define AVR_IO_EXT_IO_SIZE 0x00a0
+#define AVR_IO_SIZE (AVR_IO_CPU_REGS_SIZE \
+ + AVR_IO_CPU_IO_SIZE \
+ + AVR_IO_EXT_IO_SIZE)
+
+#define AVR_IO_CPU_REGS_BASE 0x0000
+#define AVR_IO_CPU_IO_BASE (AVR_IO_CPU_REGS_BASE \
+ + AVR_IO_CPU_REGS_SIZE)
+#define AVR_IO_EXTERN_IO_BASE (AVR_IO_CPU_IO_BASE \
+ + AVR_IO_CPU_IO_SIZE)
+
+
+typedef struct SAMPLEIOState {
+ SysBusDevice parent;
+
+ MemoryRegion iomem;
+
+ AVRCPU *cpu;
+
+ uint8_t io[AVR_IO_CPU_IO_SIZE];
+ uint8_t exio[AVR_IO_EXT_IO_SIZE];
+} SAMPLEIOState;
+
+static uint64_t sample_io_read(void *opaque, hwaddr offset, unsigned size);
+static void sample_io_write(void *opaque, hwaddr offset, uint64_t value,
+ unsigned size);
+static int sample_io_init(DeviceState *sbd);
+static void sample_io_class_init(ObjectClass *klass, void *data);
+static void sample_io_register_types(void);
+
+static void write_Rx(CPUAVRState *env, int inst, uint8_t data);
+static uint8_t read_Rx(CPUAVRState *env, int inst);
+
+static const MemoryRegionOps sample_io_ops = {
+ .read = sample_io_read,
+ .write = sample_io_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static Property sample_io_properties[] = {
+ DEFINE_PROP_END_OF_LIST(),
+};
+static const VMStateDescription sample_io_vmstate = {
+ .name = TYPE_SAMPLEIO,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[])
+ {
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+void write_Rx(CPUAVRState *env, int inst, uint8_t data)
+{
+ env->r[inst] = data;
+}
+uint8_t read_Rx(CPUAVRState *env, int inst)
+{
+ return env->r[inst];
+}
+
+static
+void sample_io_reset(DeviceState *dev)
+{
+ DPRINTF("\n");
+}
+
+static
+uint64_t sample_io_read(void *opaque, hwaddr offset, unsigned size)
+{
+ SAMPLEIOState *s = SAMPLEIO(opaque);
+ AVRCPU *cpu = s->cpu;
+ CPUAVRState *env = &cpu->env;
+ uint64_t res = 0;
+
+ assert(size == 1);
+
+#if AVR_IO_CPU_REGS_BASE == 0
+ if (offset < (AVR_IO_CPU_REGS_BASE + AVR_IO_CPU_REGS_SIZE)) {
+#else
+ if (AVR_IO_CPU_REGS_BASE <= offset
+ && offset < (AVR_IO_CPU_REGS_BASE + AVR_IO_CPU_REGS_SIZE)) {
+#endif
+ res = read_Rx(env, offset - AVR_IO_CPU_REGS_BASE);
+ } else if (AVR_IO_CPU_IO_BASE <= offset
+ && offset < (AVR_IO_CPU_IO_BASE + AVR_IO_CPU_IO_SIZE)) {
+ /* TODO: do IO related stuff here */
+ res = s->io[offset - AVR_IO_CPU_IO_BASE];
+ } else if (AVR_IO_EXTERN_IO_BASE <= offset
+ && offset < (AVR_IO_EXTERN_IO_BASE + AVR_IO_EXT_IO_SIZE)) {
+ /* TODO: do EXT IO related stuff here */
+ res = s->io[offset - AVR_IO_EXTERN_IO_BASE];
+ } else {
+ g_assert_not_reached();
+ }
+
+ qemu_log("%s addr:%2x data:%2x\n", __func__, (int)offset, (int)res);
+
+ return res;
+}
+
+static
+void sample_io_write(void *opaque, hwaddr offset, uint64_t value, unsigned
size)
+{
+ SAMPLEIOState *s = SAMPLEIO(opaque);
+ AVRCPU *cpu = s->cpu;
+ CPUAVRState *env = &cpu->env;
+
+ assert(size == 1);
+
+ qemu_log("%s addr:%2x data:%2x\n", __func__, (int)offset, (int)value);
+
+#if AVR_IO_CPU_REGS_BASE == 0
+ if (offset < (AVR_IO_CPU_REGS_BASE + AVR_IO_CPU_REGS_SIZE)) {
+#else
+ if (AVR_IO_CPU_REGS_BASE <= offset
+ && offset < (AVR_IO_CPU_REGS_BASE + AVR_IO_CPU_REGS_SIZE)) {
+#endif
+ return write_Rx(env, offset - AVR_IO_CPU_REGS_BASE, value);
+ } else if (AVR_IO_CPU_IO_BASE <= offset
+ && offset < (AVR_IO_CPU_IO_BASE + AVR_IO_CPU_IO_SIZE)) {
+ /* TODO: do IO related stuff here */
+ s->io[offset - AVR_IO_CPU_IO_BASE] = value;
+ } else if (AVR_IO_EXTERN_IO_BASE <= offset
+ && offset < (AVR_IO_EXTERN_IO_BASE + AVR_IO_EXT_IO_SIZE)) {
+ /* TODO: do EXT IO related stuff here */
+ s->io[offset - AVR_IO_EXTERN_IO_BASE] = value;
+ } else {
+ g_assert_not_reached();
+ }
+}
+
+static
+int sample_io_init(DeviceState *dev)
+{
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+ SAMPLEIOState *s = SAMPLEIO(dev);
+
+ assert(AVR_IO_SIZE <= TARGET_PAGE_SIZE);
+
+ s->cpu = AVR_CPU(qemu_get_cpu(0));
+
+ memory_region_init_io(
+ &s->iomem,
+ OBJECT(s),
+ &sample_io_ops,
+ s,
+ TYPE_SAMPLEIO,
+ AVR_IO_SIZE);
+ sysbus_init_mmio(sbd, &s->iomem);
+
+ return 0;
+}
+
+static
+void sample_io_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ DPRINTF("\n");
+
+ dc->init = sample_io_init;
+ dc->reset = sample_io_reset;
+ dc->desc = "at90 io regs";
+ dc->vmsd = &sample_io_vmstate;
+ dc->props = sample_io_properties;
+}
+
+static const
+TypeInfo sample_io_info = {
+ .name = TYPE_SAMPLEIO,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(SAMPLEIOState),
+ .class_init = sample_io_class_init,
+};
+
+static
+void sample_io_register_types(void)
+{
+ DPRINTF("\n");
+ type_register_static(&sample_io_info);
+}
+
+type_init(sample_io_register_types)
diff --git a/hw/avr/sample.c b/hw/avr/sample.c
new file mode 100644
index 0000000..5b95dea
--- /dev/null
+++ b/hw/avr/sample.c
@@ -0,0 +1,116 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2016 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "hw/hw.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/qtest.h"
+#include "ui/console.h"
+#include "hw/boards.h"
+#include "hw/devices.h"
+#include "hw/loader.h"
+#include "qemu/error-report.h"
+#include "exec/address-spaces.h"
+#include "include/hw/sysbus.h"
+
+#define VIRT_BASE_FLASH 0x00000000
+#define VIRT_BASE_ISRAM 0x00000100
+#define VIRT_BASE_EXMEM 0x00001100
+#define VIRT_BASE_EEPROM 0x00000000
+
+#define SIZE_FLASH 0x00020000
+#define SIZE_ISRAM 0x00001000
+#define SIZE_EXMEM 0x00010000
+#define SIZE_EEPROM 0x00001000
+#define SIZE_IOREG SIZE_REGS
+
+#define PHYS_BASE_FLASH (PHYS_BASE_CODE)
+
+#define PHYS_BASE_ISRAM (PHYS_BASE_DATA)
+#define PHYS_BASE_EXMEM (PHYS_BASE_ISRAM + SIZE_ISRAM)
+#define PHYS_BASE_EEPROM (PHYS_BASE_EXMEM + SIZE_EXMEM)
+
+#define PHYS_BASE_IOREG (PHYS_BASE_REGS)
+
+
+static void sample_init(MachineState *machine)
+{
+ MemoryRegion *address_space_mem = get_system_memory();
+
+ MemoryRegion *flash;
+ MemoryRegion *isram;
+ MemoryRegion *exmem;
+
+ AVRCPU *cpu_avr ATTRIBUTE_UNUSED;
+ DeviceState *io;
+ SysBusDevice *bus;
+
+ flash = g_new(MemoryRegion, 1);
+ isram = g_new(MemoryRegion, 1);
+ exmem = g_new(MemoryRegion, 1);
+
+ cpu_avr = cpu_avr_init("avr5");
+ io = qdev_create(NULL, "SampleIO");
+ bus = SYS_BUS_DEVICE(io);
+ qdev_init_nofail(io);
+
+ memory_region_init_ram(flash, NULL, "flash", SIZE_FLASH, &error_fatal);
+ memory_region_init_ram(isram, NULL, "isram", SIZE_ISRAM, &error_fatal);
+ memory_region_init_ram(exmem, NULL, "exmem", SIZE_EXMEM, &error_fatal);
+
+ memory_region_add_subregion(address_space_mem, PHYS_BASE_FLASH, flash);
+ memory_region_add_subregion(address_space_mem, PHYS_BASE_ISRAM, isram);
+ memory_region_add_subregion(address_space_mem, PHYS_BASE_EXMEM, exmem);
+
+ vmstate_register_ram_global(flash);
+ vmstate_register_ram_global(isram);
+ vmstate_register_ram_global(exmem);
+
+ memory_region_set_readonly(flash, true);
+
+ char const *firmware = NULL;
+ char const *filename;
+
+ if (machine->firmware) {
+ firmware = machine->firmware;
+ }
+
+ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, firmware);
+ if (!filename) {
+ error_report("Could not find flash image file '%s'", firmware);
+ exit(1);
+ }
+
+ load_image_targphys(filename, PHYS_BASE_FLASH, SIZE_FLASH);
+
+ sysbus_mmio_map(bus, 0, PHYS_BASE_REGS);
+}
+
+static void sample_machine_init(MachineClass *mc)
+{
+ mc->desc = "sample";
+ mc->init = sample_init;
+ mc->is_default = 1;
+}
+
+DEFINE_MACHINE("sample", sample_machine_init)
--
2.4.9 (Apple Git-60)
- [Qemu-devel] [PATCH v9 00/10] 8bit AVR cores, Michael Rolnik, 2016/06/22
- [Qemu-devel] [PATCH v9 03/10] target-avr: adding a sample AVR board,
Michael Rolnik <=
- [Qemu-devel] [PATCH v9 05/10] target-avr: adding AVR interrupt handling, Michael Rolnik, 2016/06/22
- [Qemu-devel] [PATCH v9 01/10] target-avr: AVR cores support is added. 1. basic CPU structure 2. registers 3. no instructions 4. saving sreg, rampD, rampX, rampY, rampD, eind in HW representation saving cpu features, Michael Rolnik, 2016/06/22
- [Qemu-devel] [PATCH v9 04/10] target-avr: adding instructions encodings, Michael Rolnik, 2016/06/22
- [Qemu-devel] [PATCH v9 06/10] target-avr: adding helpers for IN, OUT, SLEEP, WBR & unsupported instructions, Michael Rolnik, 2016/06/22
- [Qemu-devel] [PATCH v9 07/10] target-avr: adding instruction decoder, Michael Rolnik, 2016/06/22
- [Qemu-devel] [PATCH v9 02/10] target-avr: adding AVR CPU features/flavors, Michael Rolnik, 2016/06/22
- [Qemu-devel] [PATCH v9 09/10] target-avr: updating translate.c to use instructions translation, Michael Rolnik, 2016/06/22
- [Qemu-devel] [PATCH v9 10/10] target-avr: decoder generator. currently not used by the build, can be used manually, Michael Rolnik, 2016/06/22
- [Qemu-devel] [PATCH v9 08/10] target-avr: adding instruction translation, Michael Rolnik, 2016/06/22