From: Yoshinori Sato <ysato@users.sourceforge.jp>
To: qemu-devel@nongnu.org
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Subject: [PATCH 01/20] loader.c: Add support Motrola S-record format.
Date: Thu, 27 Aug 2020 21:38:40 +0900 [thread overview]
Message-ID: <20200827123859.81793-2-ysato@users.sourceforge.jp> (raw)
In-Reply-To: <20200827123859.81793-1-ysato@users.sourceforge.jp>
Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
include/hw/loader.h | 14 +++
hw/core/loader.c | 208 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 222 insertions(+)
diff --git a/include/hw/loader.h b/include/hw/loader.h
index a9eeea3952..6f1fb62ded 100644
--- a/include/hw/loader.h
+++ b/include/hw/loader.h
@@ -55,6 +55,20 @@ int load_image_targphys_as(const char *filename,
*/
int load_targphys_hex_as(const char *filename, hwaddr *entry, AddressSpace *as);
+/*
+ * load_targphys_srec_as:
+ * @filename: Path to the .hex file
+ * @entry: Store the entry point given by the .hex file
+ * @as: The AddressSpace to load the .hex file to. The value of
+ * address_space_memory is used if nothing is supplied here.
+ *
+ * Load a fixed .srec file into memory.
+ *
+ * Returns the size of the loaded .hex file on success, -1 otherwise.
+ */
+int load_targphys_srec_as(const char *filename,
+ hwaddr *entry, AddressSpace *as);
+
/** load_image_targphys:
* Same as load_image_targphys_as(), but doesn't allow the caller to specify
* an AddressSpace.
diff --git a/hw/core/loader.c b/hw/core/loader.c
index 8bbb1797a4..6964b04ec7 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -1618,3 +1618,211 @@ int load_targphys_hex_as(const char *filename, hwaddr *entry, AddressSpace *as)
g_free(hex_blob);
return total_size;
}
+
+typedef enum {
+ SREC_SOH,
+ SREC_TYPE,
+ SREC_LEN,
+ SREC_ADDR,
+ SREC_DATA,
+ SREC_SKIP,
+ SREC_SUM,
+} srec_state;
+
+typedef struct {
+ srec_state state;
+ int nibble;
+ int total_size;
+ uint32_t address;
+ uint32_t topaddr;
+ uint32_t bufremain;
+ int length;
+ int addr_len;
+ int record_type;
+ uint8_t byte;
+ uint8_t data[DATA_FIELD_MAX_LEN];
+ uint8_t *datap;
+ uint8_t *bufptr;
+ uint8_t sum;
+} SrecLine;
+
+static bool parse_srec_line(SrecLine *line, char c)
+{
+ if (!g_ascii_isxdigit(c)) {
+ return false;
+ }
+ line->byte <<= 4;
+ line->byte |= g_ascii_xdigit_value(c);
+ line->nibble++;
+ if (line->nibble == 2) {
+ line->nibble = 0;
+ line->length--;
+ line->sum += line->byte;
+ switch (line->state) {
+ case SREC_SOH:
+ case SREC_TYPE:
+ /* first 2chars ignore parse */
+ break;
+ case SREC_LEN:
+ line->sum = line->length = line->byte;
+ if (line->addr_len > 0) {
+ line->state = SREC_ADDR;
+ line->address = 0;
+ } else {
+ line->state = SREC_SKIP;
+ }
+ break;
+ case SREC_ADDR:
+ line->address <<= 8;
+ line->address |= line->byte;
+ if (--line->addr_len == 0) {
+ if (line->length > 1) {
+ if (line->record_type != 0) {
+ line->state = SREC_DATA;
+ } else {
+ line->state = SREC_SKIP;
+ }
+ line->datap = line->data;
+ } else {
+ line->state = SREC_SUM;
+ }
+ }
+ break;
+ case SREC_DATA:
+ *line->datap++ = line->byte;
+ /* fail through */
+ case SREC_SKIP:
+ if (line->length == 1) {
+ line->state = SREC_SUM;
+ }
+ break;
+ case SREC_SUM:
+ if ((line->sum & 0xff) != 0xff) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+#define SRECBUFSIZE 0x40000
+
+/* return size or -1 if error */
+static int parse_srec_blob(const char *filename, hwaddr *addr,
+ uint8_t *hex_blob, size_t hex_blob_size,
+ AddressSpace *as)
+{
+ SrecLine line;
+ size_t len;
+ int total_len = 0;
+ uint8_t *end = hex_blob + hex_blob_size;
+ rom_transaction_begin();
+ line.state = SREC_SOH;
+ line.bufptr = g_malloc(SRECBUFSIZE);
+ line.bufremain = SRECBUFSIZE;
+ line.topaddr = UINT32_MAX;
+ for (; hex_blob < end; ++hex_blob) {
+ switch (*hex_blob) {
+ case '\r':
+ case '\n':
+ if (line.state == SREC_SUM) {
+ switch (line.record_type) {
+ case 1:
+ case 2:
+ case 3:
+ len = line.datap - line.data;
+ if (line.topaddr == UINT32_MAX) {
+ line.topaddr = line.address;
+ }
+ if (line.bufremain < len || line.address < line.topaddr) {
+ rom_add_blob_fixed_as(filename, line.bufptr,
+ SRECBUFSIZE - line.bufremain,
+ line.topaddr, as);
+ line.topaddr = line.address;
+ line.bufremain = SRECBUFSIZE;
+ }
+ memcpy(line.bufptr + (line.address - line.topaddr),
+ line.data, len);
+ line.bufremain -= len;
+ total_len += len;
+ break;
+ case 7:
+ case 8:
+ case 9:
+ *addr = line.address;
+ break;
+ }
+ line.state = SREC_SOH;
+ }
+ break;
+ /* start of a new record. */
+ case 'S':
+ if (line.state != SREC_SOH) {
+ total_len = -1;
+ goto out;
+ }
+ line.state = SREC_TYPE;
+ break;
+ /* decoding lines */
+ default:
+ if (line.state == SREC_TYPE) {
+ if (g_ascii_isdigit(*hex_blob)) {
+ line.record_type = g_ascii_digit_value(*hex_blob);
+ switch (line.record_type) {
+ case 1:
+ case 2:
+ case 3:
+ line.addr_len = 1 + line.record_type;
+ break;
+ case 0:
+ case 5:
+ line.addr_len = 2;
+ break;
+ case 7:
+ case 8:
+ case 9:
+ line.addr_len = 11 - line.record_type;
+ break;
+ default:
+ line.addr_len = 0;
+ }
+ }
+ line.state = SREC_LEN;
+ line.nibble = 0;
+ } else {
+ if (!parse_srec_line(&line, *hex_blob)) {
+ total_len = -1;
+ goto out;
+ }
+ }
+ break;
+ }
+ }
+ if (line.bufremain < SRECBUFSIZE) {
+ rom_add_blob_fixed_as(filename, line.bufptr,
+ SRECBUFSIZE - line.bufremain,
+ line.topaddr, as);
+ }
+out:
+ rom_transaction_end(total_len != -1);
+ g_free(line.bufptr);
+ return total_len;
+}
+
+/* return size or -1 if error */
+int load_targphys_srec_as(const char *filename, hwaddr *entry, AddressSpace *as)
+{
+ gsize hex_blob_size;
+ gchar *hex_blob;
+ int total_size = 0;
+
+ if (!g_file_get_contents(filename, &hex_blob, &hex_blob_size, NULL)) {
+ return -1;
+ }
+
+ total_size = parse_srec_blob(filename, entry, (uint8_t *)hex_blob,
+ hex_blob_size, as);
+
+ g_free(hex_blob);
+ return total_size;
+}
--
2.20.1
next prev 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 ` Yoshinori Sato [this message]
2020-09-08 20:44 ` [PATCH 01/20] loader.c: Add support Motrola S-record format 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 ` [PATCH 03/20] hw/rx: Firmware and kernel loader Yoshinori Sato
2020-09-08 20:47 ` 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-2-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.