From 9a4eff992fa0efdbbe909ed0e635b7139f178948 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 24 Jun 2012 11:57:25 -0700 Subject: [PATCH] flash: Provide direct flash access with flash_dataptr() Sometimes it is useful to get access to the flash directly, without using flash_read(). Add a function to do this. Since the range checking is done in every function in flash_common, use the new function to do it for us. That way we get a slight (64 byte) code size reduction. BUG=chrome-os-partner:10146 TEST=manual: build and boot on snow with SPI flash emulation, in U-Boot: See that the 32KB of flash has been provided correctly. Change-Id: I6622a24234edaed371dd5b9bf43d1f3974d55e39 Signed-off-by: Simon Glass Reviewed-on: https://gerrit.chromium.org/gerrit/26174 --- chip/stm32/flash-stm32f100.c | 1 + common/flash_common.c | 42 +++++++++++++++++++----------------- include/flash.h | 37 +++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 20 deletions(-) diff --git a/chip/stm32/flash-stm32f100.c b/chip/stm32/flash-stm32f100.c index 9fb5250514..abb9cfb9a9 100644 --- a/chip/stm32/flash-stm32f100.c +++ b/chip/stm32/flash-stm32f100.c @@ -71,6 +71,7 @@ int flash_physical_read(int offset, int size, char *data) return EC_SUCCESS; } + static int unlock(int locks) { /* unlock CR if needed */ diff --git a/common/flash_common.c b/common/flash_common.c index e79b4d9d79..306894d6ae 100644 --- a/common/flash_common.c +++ b/common/flash_common.c @@ -136,11 +136,23 @@ int flash_get_size(void) } +char *flash_dataptr(int offset, int size_req, int align, int *sizep) +{ + if (offset < 0 || size_req < 0 || + offset + size_req > usable_flash_size || + (offset | size_req) & (align - 1)) + return NULL; /* Invalid range */ + if (sizep) + *sizep = usable_flash_size - offset; + + return flash_physical_dataptr(offset); +} + + int flash_read(int offset, int size, char *data) { - if (size < 0 || offset > usable_flash_size || - offset + size > usable_flash_size) - return EC_ERROR_UNKNOWN; /* Invalid range */ + if (!flash_dataptr(offset, size, 1, NULL)) + return EC_ERROR_INVAL; /* Invalid range */ return flash_physical_read(offset, size, data); } @@ -148,10 +160,8 @@ int flash_read(int offset, int size, char *data) int flash_write(int offset, int size, const char *data) { - if (size < 0 || offset > usable_flash_size || - offset + size > usable_flash_size || - (offset | size) & (flash_get_write_block_size() - 1)) - return EC_ERROR_UNKNOWN; /* Invalid range */ + if (!flash_dataptr(offset, size, flash_get_write_block_size(), NULL)) + return EC_ERROR_INVAL; /* Invalid range */ /* TODO (crosbug.com/p/7478) - safety check - don't allow writing to * the image we're running from */ @@ -162,10 +172,8 @@ int flash_write(int offset, int size, const char *data) int flash_erase(int offset, int size) { - if (size < 0 || offset > usable_flash_size || - offset + size > usable_flash_size || - (offset | size) & (flash_get_erase_block_size() - 1)) - return EC_ERROR_UNKNOWN; /* Invalid range */ + if (!flash_dataptr(offset, size, flash_get_erase_block_size(), NULL)) + return EC_ERROR_INVAL; /* Invalid range */ /* TODO (crosbug.com/p/7478) - safety check - don't allow erasing the * image we're running from */ @@ -179,9 +187,7 @@ int flash_protect_until_reboot(int offset, int size) int pbsize = flash_get_protect_block_size(); int i; - if (size < 0 || offset > usable_flash_size || - offset + size > usable_flash_size || - (offset | size) & (pbsize - 1)) + if (!flash_dataptr(offset, size, pbsize, NULL)) return EC_ERROR_INVAL; /* Invalid range */ /* Convert offset and size to blocks */ @@ -200,9 +206,7 @@ int flash_set_protect(int offset, int size, int enable) int pbsize = flash_get_protect_block_size(); int rv, i; - if (size < 0 || offset > usable_flash_size || - offset + size > usable_flash_size || - (offset | size) & (pbsize - 1)) + if (!flash_dataptr(offset, size, pbsize, NULL)) return EC_ERROR_INVAL; /* Invalid range */ /* Fail if write protect block is already locked */ @@ -288,9 +292,7 @@ int flash_get_protect(int offset, int size) uint8_t minflags = 0xff; int i; - if (size < 0 || offset > usable_flash_size || - offset + size > usable_flash_size || - (offset | size) & (pbsize - 1)) + if (!flash_dataptr(offset, size, pbsize, NULL)) return 0; /* Invalid range; assume nothing protected */ /* Convert offset and size to blocks */ diff --git a/include/flash.h b/include/flash.h index 9b0a60a5e2..7611639add 100644 --- a/include/flash.h +++ b/include/flash.h @@ -24,6 +24,22 @@ int flash_get_protect_block_size(void); /* Return the physical size of flash in bytes */ int flash_physical_size(void); +/** + * Get the physical memory address of a flash offset + * + * This is used for direct flash access. We assume that the flash is + * contiguous from this start address through to the end of the usable + * flash. + * + * @param offset Flash offset to get address of + * @param dataptrp Returns pointer to memory address of flash offset + * @return pointer to flash memory offset, if ok, else NULL + */ +static inline char *flash_physical_dataptr(int offset) +{ + return (char *)offset; +} + /* Read bytes of data from offset into . */ int flash_physical_read(int offset, int size, char *data); @@ -50,6 +66,27 @@ int flash_pre_init(void); * smaller than the actual flash size, */ int flash_get_size(void); +/** + * Get the physical memory address of a flash offset + * + * This is used for direct flash access. We assume that the flash is + * contiguous from this start address through to the end of the usable + * flash. + * + * This function returns NULL if offset + size_req extends beyond the end + * of flash, or if either size_req or offset are not aligned to 'align'. + * + * @param offset Flash offset to get address of + * @param size_req Number of bytes requested + * @param align Ensure offset and size_req are aligned to given + * power of two. + * @param sizep If not NULL, returns amount of flash available at + * this memory addr, unless function fails, iwc it is + * unset. + * @return pointer to flash, or NULL on error + */ +char *flash_dataptr(int offset, int size_req, int align, int *sizep); + /* Reads bytes of data from offset into . */ int flash_read(int offset, int size, char *data);