WIP: add mmap backend for virtual spi flash

wip/virtual-tbm
Merlijn Wajer 5 years ago
parent fe3b178d3c
commit 4be866edeb
  1. 121
      source/platform/virtual/spi.c

@ -4,16 +4,54 @@
#include <spi.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>
#include <spi_flash.h>
// XXX: 16 is used in other places in this file too
#define FLASH_SIZE (1 << 16)
static int virtual_spi_tx_rx(struct spi_dev *dev, void *rx_buf, size_t rx_len,
const void *tx_buf, size_t tx_len);
const void *tx_buf, size_t tx_len);
static struct spi_ops virtual_spi_ops = {
.tx_rx = virtual_spi_tx_rx,
};
static void virtual_spi_init(void)
// XXX: make part of dev struct
static unsigned char *flash_map;
static int virtual_spi_init(void)
{
/* TODO */
/* TODO: close this fd */
FILE *flash_fd;
int exists = 0;
exists = access("flash", F_OK) != -1;
/* XXX: treat not existing separately from existing file, since we want to
* null one that doesn't exist yet */
flash_fd = fopen("flash", "ab+");
if (!exists) {
fprintf(stderr,
"flash doesn't exist yet, creating and filling now\n");
char buf[FLASH_SIZE];
int ret = fwrite(buf, sizeof(char), FLASH_SIZE, flash_fd);
fprintf(stderr, "fwrite ret: %d\n", ret);
}
if (flash_fd == NULL) {
perror("flash_open");
fprintf(stderr, "spi init failed\n");
return 1;
}
flash_map =
mmap(NULL, FLASH_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
fileno(flash_fd), 0);
fprintf(stderr, "flash: %p\n", flash_map);
return 0;
}
struct spi_dev *spi_probe(void)
@ -24,11 +62,14 @@ struct spi_dev *spi_probe(void)
return NULL;
dev->ops = &virtual_spi_ops;
/*
dev->dev_id = SPI1;
/*
dev->dev_id = SPI1;
*/
virtual_spi_init();
*/
if (virtual_spi_init()) {
free(dev);
return NULL;
}
return dev;
}
@ -36,10 +77,74 @@ struct spi_dev *spi_probe(void)
void spi_release(struct spi_dev *dev)
{
free(dev);
/* TODO: close fd, close mmap */
}
static int virtual_spi_tx_rx(struct spi_dev *dev, void *rx_buf, size_t rx_len,
const void *tx_buf, size_t tx_len)
const void *tx_buf, size_t tx_len)
{
unsigned char *rx_buf_c = (unsigned char *)rx_buf;
unsigned char *tx_buf_c = (unsigned char *)tx_buf;
unsigned char cmd = tx_buf_c[0];
fprintf(stderr, "? RX len: %ld\n", rx_len);
if (tx_buf != NULL) {
fprintf(stderr, "? TX Command: %d\n", cmd);
fprintf(stderr, "? TX len: %ld\n", tx_len);
if (cmd == SPI_FLASH_JEDEC_ID) {
if (rx_len != 3) {
fprintf(stderr, "UNEXPECTED RX_LEN\n");
}
fprintf(stderr, "SPI_FLASH_JEDEC_ID\n");
rx_buf_c[0] = 0x1;
rx_buf_c[1] = 0x1;
rx_buf_c[2] = 16;
}
if (cmd == SPI_FLASH_READ) {
fprintf(stderr, "SPI_FLASH_READ\n");
unsigned int addr = (tx_buf_c[1] << 16) +
(tx_buf_c[2] << 8) + tx_buf_c[3];
fprintf(stderr, "addr: %d\n", addr);
fprintf(stderr, "memmove: %d\n", addr);
memmove(rx_buf_c, flash_map + addr, rx_len);
}
if (cmd == SPI_FLASH_PAGE_PROGRAM) {
fprintf(stderr, "SPI_FLASH_PAGE_PROGRAM\n");
unsigned int addr = (tx_buf_c[1] << 16) +
(tx_buf_c[2] << 8) + tx_buf_c[3];
fprintf(stderr, "addr: %d\n", addr);
fprintf(stderr, "memmove: %d\n", addr);
memmove(flash_map + addr, tx_buf_c + 4, tx_len - 4);
}
if (cmd == SPI_FLASH_ERASE_4K) {
fprintf(stderr, "SPI_FLASH_ERASE_4K\n");
unsigned int addr = (tx_buf_c[1] << 16) +
(tx_buf_c[2] << 8) + tx_buf_c[3];
fprintf(stderr, "addr: %d\n", addr);
memset(flash_map + addr, 0, 4096);
}
if (cmd == SPI_FLASH_READ_SR1) {
fprintf(stderr, "SPI_FLASH_READ_SR1\n");
/* Just report read/write/erase as done, we are never busy with mmap */
rx_buf_c[0] = 0;
}
if (cmd == SPI_FLASH_WRITE_ENABLE) {
fprintf(stderr, "SPI_FLASH_WRITE_ENABLE\n");
/* These can be stubs */
}
if (cmd == SPI_FLASH_WRITE_DISABLE) {
fprintf(stderr, "SPI_FLASH_WRITE_DISABLE\n");
/* These can be stubs */
}
}
return 0;
}

Loading…
Cancel
Save