aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2017-09-08 20:44:56 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2017-09-08 20:44:56 +0900
commit2c9191c4b365e08bf3ee4272a190473a7c372ca1 (patch)
tree3ee1315a7286e47fb107eda4a53ca29b6e8e2403
parentaf5982507f5f6831b202d1014138a92b8a243183 (diff)
Implement flash ROM emulation on GNU/LInux.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
-rw-r--r--ChangeLog4
-rw-r--r--mcu/sys-gnu-linux.c121
2 files changed, 123 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 1b4f036..f97607d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2017-09-08 NIIBE Yutaka <gniibe@fsij.org>
+
+ * mcu/sys-gnu-linux.c: Flash emulation implemented.
+
2017-09-05 NIIBE Yutaka <gniibe@fsij.org>
* example-cdc: Use stack-def.h.
diff --git a/mcu/sys-gnu-linux.c b/mcu/sys-gnu-linux.c
index f7f51b0..b6e88c3 100644
--- a/mcu/sys-gnu-linux.c
+++ b/mcu/sys-gnu-linux.c
@@ -1,6 +1,15 @@
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
#include "board.h"
const uint8_t sys_version[8] = {
@@ -19,36 +28,144 @@ set_led (int on)
puts (on ? "*": "");
}
+static const char *flash_path;
+static size_t flash_size;
+static void * flash_addr;
+static int flash_fd;
+
+void
+flash_init (const char *f_name)
+{
+ int fd;
+ struct stat sb;
+ void *addr;
+
+ fd = open (f_name, O_RDONLY);
+ if (fd < 0)
+ {
+ perror ("flash_init: open");
+ exit (1);
+ }
+
+ if (fstat (fd, &sb) < 0)
+ {
+ perror ("flash_init: fstat");
+ exit (1);
+ }
+
+ addr = mmap (NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
+ if (addr == MAP_FAILED)
+ {
+ perror ("flash_init: mmap");
+ exit (1);
+ }
+
+ if (close (fd) < 0)
+ {
+ perror ("flash_init: close");
+ exit (1);
+ }
+
+ flash_path = f_name;
+ flash_addr = addr;
+ flash_size = sb.st_size;
+}
+
void
flash_unlock (void)
{
+ int fd;
+
+ fd = open (flash_path, O_WRONLY);
+ if (fd < 0)
+ {
+ perror ("flash_unlock: open");
+ exit (1);
+ }
+ flash_fd = fd;
}
int
flash_program_halfword (uint32_t addr, uint16_t data)
{
+ off_t offset;
+ char buf[2];
+
fprintf (stderr, "flash_program_halfword: addr=%08x, data=%04x\n", addr, data);
+ offset = (off_t)(addr - (uint32_t)flash_addr);
+ offset = lseek (flash_fd, offset, SEEK_SET);
+ if (offset == (off_t)-1)
+ {
+ perror ("flash_program_halfword");
+ return 1;
+ }
+ buf[0] = (data & 0xff);
+ buf[1] = (data >> 8);
+ if (write (flash_fd, buf, 2) != 2)
+ {
+ perror ("flash_program_halfword");
+ return 2;
+ }
return 0;
}
+static const uint8_t erased[] = { [0 ... 1023 ] = 0xff };
+
int
flash_erase_page (uint32_t addr)
{
+ off_t offset;
+
fprintf (stderr, "flash_erase_page: addr=%08x\n", addr);
+
+ offset = (off_t)(addr - (uint32_t)flash_addr);
+ offset = lseek (flash_fd, offset, SEEK_SET);
+ if (offset == (off_t)-1)
+ {
+ perror ("flash_erase_page");
+ return 1;
+ }
+
+ if (write (flash_fd, erased, sizeof (erased)) != len)
+ {
+ perror ("flash_erase_page");
+ return 2;
+ }
return 0;
}
int
flash_check_blank (const uint8_t *p_start, size_t size)
{
- fprintf (stderr, "flash_check_blank: addr=%p, size=%zd\n", p_start, size);
- return 0;
+ const uint8_t *p;
+
+ for (p = p_start; p < p_start + size; p++)
+ if (*p != 0xff)
+ return 0;
+
+ return 1;
}
int
flash_write (uint32_t dst_addr, const uint8_t *src, size_t len)
{
+ off_t offset;
+
fprintf (stderr, "flash_write: addr=%08x, %p, %zd\n", dst_addr, src, len);
+
+ offset = (off_t)(dst_addr - (uint32_t)flash_addr);
+ offset = lseek (flash_fd, offset, SEEK_SET);
+ if (offset == (off_t)-1)
+ {
+ perror ("flash_write");
+ return 1;
+ }
+
+ if (write (flash_fd, src, len) != len)
+ {
+ perror ("flash_write");
+ return 2;
+ }
return 0;
}