All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.