From: Max Filippov <jcmvbkbc@gmail.com>
To: qemu-devel@nongnu.org
Cc: jcmvbkbc@gmail.com, linux-xtensa@linux-xtensa.org
Subject: [Qemu-devel] [PATCH 2/2] target-xtensa: add Avnet LX60/LX110/LX200 boards
Date: Mon, 10 Oct 2011 06:27:04 +0400 [thread overview]
Message-ID: <1318213624-3351-3-git-send-email-jcmvbkbc@gmail.com> (raw)
In-Reply-To: <1318213624-3351-1-git-send-email-jcmvbkbc@gmail.com>
These boards carry similar hardware: SDRAM (48M for LX110, 64M for LX60,
96M for LX200), 16 Mbyte FLASH, FPGA, 10/100 Mbps Ethernet PHY and 16550
UART. FPGA may be loaded with almost any Tensilica processor. It is also
used to implement Ethernet MAC, e.g. OpenCores 10/100 Mbps Ethernet MAC
and LED/DIP switches access.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
Makefile.target | 1 +
default-configs/xtensa-softmmu.mak | 3 +
default-configs/xtensaeb-softmmu.mak | 3 +
hw/xtensa_lx60.c | 232 ++++++++++++++++++++++++++++++++++
4 files changed, 239 insertions(+), 0 deletions(-)
create mode 100644 hw/xtensa_lx60.c
diff --git a/Makefile.target b/Makefile.target
index 38a0298..c4069c2 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -371,6 +371,7 @@ obj-alpha-y += alpha_pci.o alpha_dp264.o alpha_typhoon.o
obj-xtensa-y += xtensa_pic.o
obj-xtensa-y += xtensa_sim.o
+obj-xtensa-y += xtensa_lx60.o
obj-xtensa-y += xtensa-semi.o
obj-xtensa-y += core-dc232b.o
obj-xtensa-y += core-fsf.o
diff --git a/default-configs/xtensa-softmmu.mak b/default-configs/xtensa-softmmu.mak
index e5faa09..7f0df34 100644
--- a/default-configs/xtensa-softmmu.mak
+++ b/default-configs/xtensa-softmmu.mak
@@ -1 +1,4 @@
# Default configuration for Xtensa
+
+CONFIG_SERIAL=y
+CONFIG_OPENCORES_ETH=y
diff --git a/default-configs/xtensaeb-softmmu.mak b/default-configs/xtensaeb-softmmu.mak
index e5faa09..7f0df34 100644
--- a/default-configs/xtensaeb-softmmu.mak
+++ b/default-configs/xtensaeb-softmmu.mak
@@ -1 +1,4 @@
# Default configuration for Xtensa
+
+CONFIG_SERIAL=y
+CONFIG_OPENCORES_ETH=y
diff --git a/hw/xtensa_lx60.c b/hw/xtensa_lx60.c
new file mode 100644
index 0000000..1ab6f91
--- /dev/null
+++ b/hw/xtensa_lx60.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2011, Max Filippov, Open Source and Linux Lab.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Open Source and Linux Lab nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "sysemu.h"
+#include "boards.h"
+#include "loader.h"
+#include "elf.h"
+#include "memory.h"
+#include "exec-memory.h"
+#include "pc.h"
+#include "sysbus.h"
+
+typedef struct Lx60FpgaState {
+ MemoryRegion iomem;
+ uint32_t leds;
+ uint32_t switches;
+} Lx60FpgaState;
+
+static void lx60_fpga_reset(void *opaque)
+{
+ Lx60FpgaState *s = opaque;
+
+ s->leds = 0;
+ s->switches = 0;
+}
+
+static uint64_t lx60_fpga_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
+{
+ Lx60FpgaState *s = opaque;
+
+ switch (addr) {
+ case 0x0: /*build date code*/
+ return 0x27092011;
+
+ case 0x4: /*processor clock frequency, Hz*/
+ return 10000000;
+
+ case 0x8: /*LEDs (off = 0, on = 1)*/
+ return s->leds;
+
+ case 0xc: /*DIP switches (off = 0, on = 1)*/
+ return s->switches;
+ }
+ return 0;
+}
+
+static void lx60_fpga_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
+{
+ Lx60FpgaState *s = opaque;
+
+ switch (addr) {
+ case 0x8: /*LEDs (off = 0, on = 1)*/
+ s->leds = val;
+ break;
+
+ case 0x10: /*board reset*/
+ if (val == 0xdead) {
+ qemu_system_reset_request();
+ }
+ break;
+ }
+}
+
+static const MemoryRegionOps lx60_fpga_ops = {
+ .read = lx60_fpga_read,
+ .write = lx60_fpga_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static Lx60FpgaState *lx60_fpga_init(MemoryRegion *address_space,
+ target_phys_addr_t base)
+{
+ Lx60FpgaState *s = g_malloc(sizeof(Lx60FpgaState));
+
+ memory_region_init_io(&s->iomem, &lx60_fpga_ops, s,
+ "lx60-fpga", 0x10000);
+ memory_region_add_subregion(address_space, base, &s->iomem);
+ lx60_fpga_reset(s);
+ qemu_register_reset(lx60_fpga_reset, s);
+ return s;
+}
+
+static void lx60_net_init(MemoryRegion *address_space,
+ target_phys_addr_t base,
+ target_phys_addr_t descriptors,
+ target_phys_addr_t buffers,
+ qemu_irq irq, NICInfo *nd)
+{
+ DeviceState *dev;
+ SysBusDevice *s;
+ MemoryRegion *ram;
+
+ dev = qdev_create(NULL, "open_eth");
+ qdev_set_nic_properties(dev, nd);
+ qdev_init_nofail(dev);
+
+ s = sysbus_from_qdev(dev);
+ sysbus_connect_irq(s, 0, irq);
+ memory_region_add_subregion(address_space, base,
+ sysbus_mmio_get_region(s, 0));
+ memory_region_add_subregion(address_space, descriptors,
+ sysbus_mmio_get_region(s, 1));
+
+ ram = g_malloc(sizeof(*ram));
+ memory_region_init_ram(ram, NULL, "open_eth.ram", 16384);
+ memory_region_add_subregion(address_space, buffers, ram);
+}
+
+static uint64_t translate_phys_addr(void *env, uint64_t addr)
+{
+ return cpu_get_phys_page_debug(env, addr);
+}
+
+static void lx60_reset(void *env)
+{
+ cpu_reset(env);
+}
+
+static void lx60_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)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+ int be = 1;
+#else
+ int be = 0;
+#endif
+ MemoryRegion *system_memory = get_system_memory();
+ CPUState *env = NULL;
+ MemoryRegion *ram, *rom, *system_io;
+ int n;
+
+ for (n = 0; n < smp_cpus; n++) {
+ env = cpu_init(cpu_model);
+ if (!env) {
+ fprintf(stderr, "Unable to find CPU definition\n");
+ exit(1);
+ }
+ env->sregs[PRID] = n;
+ qemu_register_reset(lx60_reset, env);
+ /* Need MMU initialized prior to ELF loading,
+ * so that ELF gets loaded into virtual addresses
+ */
+ cpu_reset(env);
+ }
+
+ ram = g_malloc(sizeof(*ram));
+ memory_region_init_ram(ram, NULL, "xtensa.sram", ram_size);
+ memory_region_add_subregion(system_memory, 0, ram);
+
+ rom = g_malloc(sizeof(*rom));
+ memory_region_init_ram(rom, NULL, "xtensa.rom", 0x1000);
+ memory_region_add_subregion(system_memory, 0xfe000000, rom);
+
+ system_io = g_malloc(sizeof(*system_io));
+ memory_region_init(system_io, "system.io", 224 * 1024 * 1024);
+ memory_region_add_subregion(system_memory, 0xf0000000, system_io);
+ lx60_fpga_init(system_io, 0x0d020000);
+ if (nd_table[0].vlan) {
+ lx60_net_init(system_io, 0x0d030000, 0x0d030400, 0x0d800000,
+ xtensa_get_extint(env, 1), nd_table);
+ }
+
+ if (!serial_hds[0]) {
+ serial_hds[0] = qemu_chr_new("serial0", "null", NULL);
+ }
+ serial_mm_init(0xfd050020, 2, xtensa_get_extint(env, 0),
+ 115200, serial_hds[0], 1, be);
+
+ if (kernel_filename) {
+ uint64_t elf_entry;
+ uint64_t elf_lowaddr;
+ int success = load_elf(kernel_filename, translate_phys_addr, env,
+ &elf_entry, &elf_lowaddr, NULL, be, ELF_MACHINE, 0);
+ if (success > 0) {
+ env->pc = elf_entry;
+ }
+ }
+}
+
+static void xtensa_lx60_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)
+{
+ if (!cpu_model) {
+ cpu_model = "dc232b";
+ }
+ lx60_init(ram_size, boot_device, kernel_filename, kernel_cmdline,
+ initrd_filename, cpu_model);
+}
+
+static QEMUMachine xtensa_lx60_machine = {
+ .name = "lx60",
+ .desc = "lx60 EVB (dc232b)",
+ .init = xtensa_lx60_init,
+ .max_cpus = 4,
+};
+
+static void xtensa_lx60_machine_init(void)
+{
+ qemu_register_machine(&xtensa_lx60_machine);
+}
+
+machine_init(xtensa_lx60_machine_init);
--
1.7.6.4
next prev parent reply other threads:[~2011-10-10 2:27 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-10 2:27 [Qemu-devel] [PATCH 0/2] target-xtensa: add Avnet lx60/lx110/lx200 board and OpenCores Ethernet MAC Max Filippov
2011-10-10 2:27 ` [Qemu-devel] [PATCH 1/2] hw: add OpenCores 10/100 Mbps Ethernet controller Max Filippov
2011-10-10 2:27 ` Max Filippov [this message]
2011-10-15 21:31 ` [Qemu-devel] [PATCH 0/2] target-xtensa: add Avnet lx60/lx110/lx200 board and OpenCores Ethernet MAC Blue Swirl
2011-10-15 21:55 ` Max Filippov
2011-10-16 11:05 ` Blue Swirl
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=1318213624-3351-3-git-send-email-jcmvbkbc@gmail.com \
--to=jcmvbkbc@gmail.com \
--cc=linux-xtensa@linux-xtensa.org \
--cc=qemu-devel@nongnu.org \
/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).