Implement flash ROM emulation on GNU/LInux.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
@@ -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>
|
2017-09-05 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
* example-cdc: Use stack-def.h.
|
* example-cdc: Use stack-def.h.
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.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"
|
#include "board.h"
|
||||||
|
|
||||||
const uint8_t sys_version[8] = {
|
const uint8_t sys_version[8] = {
|
||||||
@@ -19,36 +28,144 @@ set_led (int on)
|
|||||||
puts (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
|
void
|
||||||
flash_unlock (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
|
int
|
||||||
flash_program_halfword (uint32_t addr, uint16_t data)
|
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);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const uint8_t erased[] = { [0 ... 1023 ] = 0xff };
|
||||||
|
|
||||||
int
|
int
|
||||||
flash_erase_page (uint32_t addr)
|
flash_erase_page (uint32_t addr)
|
||||||
{
|
{
|
||||||
|
off_t offset;
|
||||||
|
|
||||||
fprintf (stderr, "flash_erase_page: addr=%08x\n", addr);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
flash_check_blank (const uint8_t *p_start, size_t size)
|
flash_check_blank (const uint8_t *p_start, size_t size)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "flash_check_blank: addr=%p, size=%zd\n", p_start, size);
|
const uint8_t *p;
|
||||||
|
|
||||||
|
for (p = p_start; p < p_start + size; p++)
|
||||||
|
if (*p != 0xff)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
flash_write (uint32_t dst_addr, const uint8_t *src, size_t len)
|
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);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user