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 <sjg@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/26174
This commit is contained in:
Simon Glass
2012-06-24 11:57:25 -07:00
committed by Gerrit
parent 9b48067b09
commit 9a4eff992f
3 changed files with 60 additions and 20 deletions

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 <size> bytes of data from offset <offset> into <data>. */
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 <size> bytes of data from offset <offset> into <data>. */
int flash_read(int offset, int size, char *data);