|
|
|
@ -6,6 +6,7 @@ |
|
|
|
|
#include <sys/mman.h> |
|
|
|
|
#include <sys/stat.h> |
|
|
|
|
|
|
|
|
|
#include <bitops.h> |
|
|
|
|
#include <flash.h> |
|
|
|
|
#include <macros.h> |
|
|
|
|
|
|
|
|
@ -22,12 +23,15 @@ static int stdio_flash_read(struct flash_dev *dev, uint32_t addr, void *data, |
|
|
|
|
size_t len); |
|
|
|
|
static int stdio_flash_write(struct flash_dev *dev, uint32_t addr, |
|
|
|
|
const void *data, size_t len); |
|
|
|
|
static int stdio_flash_erase(struct flash_dev *dev, uint32_t addr, size_t len); |
|
|
|
|
static int stdio_flash_copy(struct flash_dev *dev, uint32_t dst, uint32_t src, |
|
|
|
|
size_t len); |
|
|
|
|
static int stdio_flash_erase(struct flash_dev *dev, uint32_t addr, size_t block_size); |
|
|
|
|
|
|
|
|
|
static struct flash_ops stdio_flash_ops = { |
|
|
|
|
.get_size = stdio_flash_get_size, |
|
|
|
|
.read = stdio_flash_read, |
|
|
|
|
.write = stdio_flash_write, |
|
|
|
|
.copy = stdio_flash_copy, |
|
|
|
|
.erase = stdio_flash_erase, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
@ -72,15 +76,40 @@ static int stdio_flash_write(struct flash_dev *dev, uint32_t addr, |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int stdio_flash_erase(struct flash_dev *dev, uint32_t addr, |
|
|
|
|
static int stdio_flash_copy(struct flash_dev *dev, uint32_t dst, uint32_t src, |
|
|
|
|
size_t len) |
|
|
|
|
{ |
|
|
|
|
uint8_t data[64]; |
|
|
|
|
size_t nbytes; |
|
|
|
|
|
|
|
|
|
while (len) { |
|
|
|
|
nbytes = min(sizeof data, len); |
|
|
|
|
|
|
|
|
|
if (stdio_flash_read(dev, src, data, nbytes) < 0) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
if (stdio_flash_write(dev, dst, data, nbytes) < 0) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
dst += nbytes; |
|
|
|
|
src += nbytes; |
|
|
|
|
len -= nbytes; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int stdio_flash_erase(struct flash_dev *dev, uint32_t addr, |
|
|
|
|
size_t block_size) |
|
|
|
|
{ |
|
|
|
|
struct stdio_flash_priv *priv = dev->priv; |
|
|
|
|
size_t log2_block_size = ilog2(block_size); |
|
|
|
|
|
|
|
|
|
if (!IS_ROUND(addr, 4 * KIB) || !IS_ROUND(len, 4 * KIB)) |
|
|
|
|
if (block_size != (UINT32_C(1) << log2_block_size)) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
memset(priv->data + addr, 0xFF, len); |
|
|
|
|
memset(priv->data + (addr << log2_block_size), 0xff, |
|
|
|
|
(1 << log2_block_size)); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|