qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Michael Rolnik <mrolnik@gmail.com>
To: qemu-devel@nongnu.org
Cc: rth@twiddle.net, peter.maydell@linaro.org,
	Michael Rolnik <mrolnik@gmail.com>
Subject: [Qemu-devel] [PATCH v9 03/10] target-avr: adding a sample AVR board
Date: Wed, 22 Jun 2016 12:51:48 +0300	[thread overview]
Message-ID: <1466589115-57738-4-git-send-email-mrolnik@gmail.com> (raw)
In-Reply-To: <1466589115-57738-1-git-send-email-mrolnik@gmail.com>

Signed-off-by: Michael Rolnik <mrolnik@gmail.com>
---
 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 <mrolnik@gmail.com>
+S: Maintained
+F: target-avr/
+F: hw/avr/
+
 CRIS
 M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
 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)

  parent reply	other threads:[~2016-06-22  9:52 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-22  9:51 [Qemu-devel] [PATCH v9 00/10] 8bit AVR cores Michael Rolnik
2016-06-22  9:51 ` [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  9:51 ` [Qemu-devel] [PATCH v9 02/10] target-avr: adding AVR CPU features/flavors Michael Rolnik
2016-06-22  9:51 ` Michael Rolnik [this message]
2016-06-22  9:51 ` [Qemu-devel] [PATCH v9 04/10] target-avr: adding instructions encodings Michael Rolnik
2016-06-22  9:51 ` [Qemu-devel] [PATCH v9 05/10] target-avr: adding AVR interrupt handling Michael Rolnik
2016-06-22  9:51 ` [Qemu-devel] [PATCH v9 06/10] target-avr: adding helpers for IN, OUT, SLEEP, WBR & unsupported instructions Michael Rolnik
2016-06-22  9:51 ` [Qemu-devel] [PATCH v9 07/10] target-avr: adding instruction decoder Michael Rolnik
2016-06-22  9:51 ` [Qemu-devel] [PATCH v9 08/10] target-avr: adding instruction translation Michael Rolnik
2016-06-22  9:51 ` [Qemu-devel] [PATCH v9 09/10] target-avr: updating translate.c to use instructions translation Michael Rolnik
2016-06-22  9:51 ` [Qemu-devel] [PATCH v9 10/10] target-avr: decoder generator. currently not used by the build, can be used manually Michael Rolnik
  -- strict thread matches above, loose matches on Subject: below --
2016-07-01 14:47 [Qemu-devel] [PATCH v9 00/10] 8bit AVR cores Michael Rolnik
2016-07-01 14:47 ` [Qemu-devel] [PATCH v9 03/10] target-avr: adding a sample AVR board Michael Rolnik

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1466589115-57738-4-git-send-email-mrolnik@gmail.com \
    --to=mrolnik@gmail.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).