qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Yoshinori Sato <ysato@users.sourceforge.jp>
To: qemu-devel@nongnu.org
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Subject: [PATCH 03/20] hw/rx: Firmware and kernel loader.
Date: Thu, 27 Aug 2020 21:38:42 +0900	[thread overview]
Message-ID: <20200827123859.81793-4-ysato@users.sourceforge.jp> (raw)
In-Reply-To: <20200827123859.81793-1-ysato@users.sourceforge.jp>

Suppoerted format.
ELF, HEX, SREC and Raw firmware.
fit and Raw kernel image.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 include/hw/rx/loader.h |  35 ++++++++
 hw/rx/loader.c         | 182 +++++++++++++++++++++++++++++++++++++++++
 hw/rx/Kconfig          |   1 +
 hw/rx/meson.build      |   1 +
 4 files changed, 219 insertions(+)
 create mode 100644 include/hw/rx/loader.h
 create mode 100644 hw/rx/loader.c

diff --git a/include/hw/rx/loader.h b/include/hw/rx/loader.h
new file mode 100644
index 0000000000..71f3bd2bb3
--- /dev/null
+++ b/include/hw/rx/loader.h
@@ -0,0 +1,35 @@
+/*
+ * RX QEMU frimware loader
+ *
+ * Copyright (c) 2020 Yoshinori Sato
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+
+typedef struct {
+    hwaddr ram_start;
+    size_t ram_size;
+    hwaddr entry;
+    hwaddr kernel_entry;
+    hwaddr dtb_address;
+    const char *filename;
+    const char *dtbname;
+    const char *cmdline;
+} rx_kernel_info_t;
+
+bool load_bios(const char *filename, int rom_size, Error **errp);
+
+bool load_kernel(rx_kernel_info_t *info);
diff --git a/hw/rx/loader.c b/hw/rx/loader.c
new file mode 100644
index 0000000000..c262f3ef86
--- /dev/null
+++ b/hw/rx/loader.c
@@ -0,0 +1,182 @@
+/*
+ * RX QEMU frimware loader
+ *
+ * Copyright (c) 2020 Yoshinori Sato
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "elf.h"
+#include "hw/loader.h"
+#include "hw/loader-fit.h"
+#include "hw/rx/loader.h"
+#include "sysemu/device_tree.h"
+#include "exec/cpu-defs.h"
+#include <libfdt.h>
+
+#define RX_RESET_VEC 0xfffffffc
+#define ADDRESS_TOP ((1LL << TARGET_PHYS_ADDR_SPACE_BITS) - 1)
+
+bool load_bios(const char *filename, int rom_size, Error **errp)
+{
+    int size;
+    uint64_t entry64 = UINT64_MAX;
+    uint32_t entry;
+
+    size = load_elf(filename, NULL, NULL, NULL, &entry64,
+                    NULL, NULL, NULL, 0, EM_RX, 0, 0);
+    if (size > 0) {
+        goto load_ok;
+    }
+    size = load_targphys_hex_as(filename, &entry64, NULL);
+    if (size > 0) {
+        goto load_ok;
+    }
+    size = load_targphys_srec_as(filename, &entry64, NULL);
+    if (size > 0) {
+        goto load_ok;
+    }
+    size = get_image_size(filename);
+    if (size < 0) {
+        error_setg(errp, "\"%s\" is open failed.", filename);
+        return false;
+    }
+    if (size > rom_size) {
+        error_setg(errp, "\"%s\" is too large for ROM area.", filename);
+        return false;
+    }
+
+    /*
+     * The RX CPU reset vector is at the top of the ROM,
+     * so the raw binary is loaded there.
+     */
+    rom_add_file_fixed(filename, -size, 0);
+ load_ok:
+    if (rom_ptr(RX_RESET_VEC, 4) == NULL) {
+        if (entry64 <= ADDRESS_TOP) {
+            entry = cpu_to_le32(entry64);
+            rom_add_blob_fixed("entry", &entry, 4, RX_RESET_VEC);
+        } else {
+            error_setg(errp, "Reset vector is not set");
+            return false;
+        }
+    }
+    return true;
+}
+
+static hwaddr rx_addr_to_phys(void *opaque, uint64_t addr)
+{
+    /* No address translation */
+    return addr;
+}
+
+static bool setup_commandline(void *dtb, rx_kernel_info_t *info)
+{
+    if (info->cmdline &&
+        qemu_fdt_setprop_string(dtb, "/chosen", "bootargs",
+                                info->cmdline) < 0) {
+        return false;
+    }
+    return true;
+}
+
+
+static const void *rx_fdt_filter(void *opaque, const void *fdt_orig,
+                                 const void *match_data, hwaddr *load_addr)
+{
+    rx_kernel_info_t *info = opaque;
+    void *fdt;
+    size_t fdt_sz;
+    int err;
+
+    fdt_sz = fdt_totalsize(fdt_orig) + 0x1000;
+    fdt = g_malloc0(fdt_sz);
+
+    err = fdt_open_into(fdt_orig, fdt, fdt_sz);
+    if (err) {
+        error_report("couldn't open dtb");
+        return NULL;
+    }
+
+    if (!setup_commandline(fdt, info)) {
+        error_report("couldn't set /chosen/bootargs");
+        return NULL;
+    }
+    fdt_sz = fdt_totalsize(fdt);
+    fdt = g_realloc(fdt, fdt_totalsize(fdt));
+    info->dtb_address = info->ram_start + info->ram_size - fdt_sz;
+    *load_addr = info->dtb_address;
+
+    return fdt;
+}
+
+static const void *rx_kernel_filter(void *opaque, const void *kernel,
+                                        hwaddr *load_addr, hwaddr *entry_addr)
+{
+    rx_kernel_info_t *info = opaque;
+
+    info->kernel_entry = *entry_addr;
+
+    return kernel;
+}
+
+static const struct fit_loader rx_fit_loader = {
+    .addr_to_phys = rx_addr_to_phys,
+    .fdt_filter = rx_fdt_filter,
+    .kernel_filter = rx_kernel_filter,
+};
+
+bool load_kernel(rx_kernel_info_t *info)
+{
+    ram_addr_t kernel_offset;
+    size_t kernel_size;
+
+    if (load_fit(&rx_fit_loader, info->filename, info) == 0) {
+        return true;
+    }
+
+    /*
+     * The kernel image is loaded into
+     * the latter half of the SDRAM space.
+     */
+    kernel_offset = info->ram_size / 2;
+
+    info->entry = info->ram_start + kernel_offset;
+    kernel_size = load_image_targphys(info->filename,
+                                      info->entry, info->ram_size / 2);
+    if (kernel_size == -1) {
+        return false;
+    }
+    if (info->dtbname) {
+        ram_addr_t dtb_offset;
+        int dtb_size;
+        void *dtb;
+
+        dtb = load_device_tree(info->dtbname, &dtb_size);
+        if (dtb == NULL) {
+            error_report("Couldn't open dtb file %s", info->dtbname);
+            return false;
+        }
+        if (!setup_commandline(dtb, info)) {
+            error_report("Couldn't set /chosen/bootargs");
+            return false;
+        }
+        /* DTB is located at the end of SDRAM space. */
+        dtb_size = fdt_totalsize(dtb);
+        dtb_offset = info->ram_size - dtb_size;
+        info->dtb_address = info->ram_start + dtb_offset;
+        rom_add_blob_fixed("dtb", dtb, dtb_size, info->dtb_address);
+    }
+    return true;
+}
diff --git a/hw/rx/Kconfig b/hw/rx/Kconfig
index 2b297c5a6a..a63e4a5520 100644
--- a/hw/rx/Kconfig
+++ b/hw/rx/Kconfig
@@ -8,3 +8,4 @@ config RX62N_MCU
 config RX_GDBSIM
     bool
     select RX62N_MCU
+    select FITLOADER
diff --git a/hw/rx/meson.build b/hw/rx/meson.build
index d223512a78..e73850f303 100644
--- a/hw/rx/meson.build
+++ b/hw/rx/meson.build
@@ -1,4 +1,5 @@
 rx_ss = ss.source_set()
+rx_ss.add(files('loader.c'))
 rx_ss.add(when: 'CONFIG_RX_GDBSIM', if_true: files('rx-gdbsim.c'))
 rx_ss.add(when: 'CONFIG_RX62N_MCU', if_true: files('rx62n.c'))
 
-- 
2.20.1



  parent reply	other threads:[~2020-08-27 12:40 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-27 12:38 [PATCH 00/20] RX target update Yoshinori Sato
2020-08-27 12:38 ` [PATCH 01/20] loader.c: Add support Motrola S-record format Yoshinori Sato
2020-09-08 20:44   ` Philippe Mathieu-Daudé
2020-10-25  0:43   ` Philippe Mathieu-Daudé
2020-10-27 21:05   ` Alistair Francis
2020-08-27 12:38 ` [PATCH 02/20] include/elf.h: Add EM_RX Yoshinori Sato
2020-08-27 12:38 ` Yoshinori Sato [this message]
2020-09-08 20:47   ` [PATCH 03/20] hw/rx: Firmware and kernel loader Philippe Mathieu-Daudé
2020-08-27 12:38 ` [PATCH 04/20] hw/rx: New firmware loader Yoshinori Sato
2020-08-27 12:38 ` [PATCH 05/20] hw/rx: Add RX62N Clock generator Yoshinori Sato
2020-09-08 21:11   ` Philippe Mathieu-Daudé
2020-10-24 21:56   ` Philippe Mathieu-Daudé
2020-10-24 21:58     ` Philippe Mathieu-Daudé
2020-08-27 12:38 ` [PATCH 06/20] hw/timer: Renesas 8bit timer emulation Yoshinori Sato
2020-10-24 21:27   ` Philippe Mathieu-Daudé
2020-10-24 21:29     ` Philippe Mathieu-Daudé
2020-08-27 12:38 ` [PATCH 07/20] hw/rx: RX62N convert new 8bit timer Yoshinori Sato
2020-08-27 12:38 ` [PATCH 08/20] hw/timer: Renesas TMU/CMT module Yoshinori Sato
2020-10-24 22:47   ` Philippe Mathieu-Daudé
2020-08-27 12:38 ` [PATCH 09/20] hw/timer: Remove renesas_cmt Yoshinori Sato
2020-08-27 12:38 ` [PATCH 10/20] hw/rx: Convert to renesas_timer Yoshinori Sato
2020-08-27 12:38 ` [PATCH 11/20] hw/char: Renesas SCI module Yoshinori Sato
2020-10-24 21:40   ` Philippe Mathieu-Daudé
2020-08-27 12:38 ` [PATCH 12/20] hw/rx/rx62n: Use New " Yoshinori Sato
2020-10-25  0:33   ` Philippe Mathieu-Daudé
2020-08-27 12:38 ` [PATCH 13/20] hw/timer: Add Renesas MTU2 Yoshinori Sato
2020-08-27 12:38 ` [PATCH 14/20] hw/rx/rx62n: RX62N Add MTU module Yoshinori Sato
2020-09-08 21:12   ` Philippe Mathieu-Daudé
2020-08-27 12:38 ` [PATCH 15/20] hw/net: Add generic Bit-bang MDIO PHY Yoshinori Sato
2020-08-27 12:38 ` [PATCH 16/20] hw/net: Add Renesas On-chip Ethernet MAC Yoshinori Sato
2020-10-24 21:37   ` Philippe Mathieu-Daudé
2020-08-27 12:38 ` [PATCH 17/20] hw/rx/rx62n: Add Ethernet support Yoshinori Sato
2020-08-27 12:38 ` [PATCH 18/20] hw/rx: Add Tokudenkairo TKDN-RX62N-BRD Yoshinori Sato
2020-09-08 21:18   ` Philippe Mathieu-Daudé
2020-08-27 12:38 ` [PATCH 19/20] hw/rx: Add CQ-FRK-RX62N target Yoshinori Sato
2020-09-08 21:20   ` Philippe Mathieu-Daudé
2020-08-27 12:38 ` [PATCH 20/20] MAINTAINERS: Update RX entry Yoshinori Sato
2020-09-08 21:21   ` Philippe Mathieu-Daudé
2020-08-31 20:38 ` [PATCH 00/20] RX target update Philippe Mathieu-Daudé
2020-09-10 16:06   ` Yoshinori Sato

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=20200827123859.81793-4-ysato@users.sourceforge.jp \
    --to=ysato@users.sourceforge.jp \
    --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).