soc/intel/common/nvm: Allow overriding to_flash_offset() function
On apollolake, the flash is memory-mapped differently, and the default MMIO to flash calculation does not produce correct results. While the long-term solution is to rewrite the NVM functionality to keep the flash offset as part of its context, as a temporary measure, allow overriding the to_flash_offset() function by declaring it weak. Change-Id: Ic54baeba2441a08cfe1a47e235747797f6efb59b Signed-off-by: Alexandru Gagniuc <alexandrux.gagniuc@intel.com> Signed-off-by: Andrey Petrov <andrey.petrov@intel.com> Reviewed-on: https://review.coreboot.org/14247 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
parent
5a57725126
commit
922064162b
|
@ -46,8 +46,20 @@ static int nvm_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert memory mapped pointer to flash offset. */
|
/*
|
||||||
static inline uint32_t to_flash_offset(void *p)
|
* Convert memory mapped pointer to flash offset.
|
||||||
|
*
|
||||||
|
* This is weak because not every platforms memory-maps the NVM media in the
|
||||||
|
* same manner. This is a stop-gap solution.
|
||||||
|
*
|
||||||
|
* The root of the problem is that users of this API work in memory space for
|
||||||
|
* both reads and writes, but erase and write must be done in flash space. This
|
||||||
|
* also only works when the media is memory-mapped, which is no longer
|
||||||
|
* universally true. The long-term approach should be to rewrite this and its
|
||||||
|
* users to work in flash space, while using rdev_read() instead of rdev_mmap().
|
||||||
|
*/
|
||||||
|
__attribute__((weak))
|
||||||
|
uint32_t nvm_mmio_to_flash_offset(void *p)
|
||||||
{
|
{
|
||||||
return CONFIG_ROM_SIZE + (uintptr_t)p;
|
return CONFIG_ROM_SIZE + (uintptr_t)p;
|
||||||
}
|
}
|
||||||
|
@ -70,7 +82,7 @@ int nvm_erase(void *start, size_t size)
|
||||||
{
|
{
|
||||||
if (nvm_init() < 0)
|
if (nvm_init() < 0)
|
||||||
return -1;
|
return -1;
|
||||||
return flash->erase(flash, to_flash_offset(start), size);
|
return flash->erase(flash, nvm_mmio_to_flash_offset(start), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write data to NVM. Returns 0 on success < 0 on error. */
|
/* Write data to NVM. Returns 0 on success < 0 on error. */
|
||||||
|
@ -78,7 +90,7 @@ int nvm_write(void *start, const void *data, size_t size)
|
||||||
{
|
{
|
||||||
if (nvm_init() < 0)
|
if (nvm_init() < 0)
|
||||||
return -1;
|
return -1;
|
||||||
return flash->write(flash, to_flash_offset(start), size, data);
|
return flash->write(flash, nvm_mmio_to_flash_offset(start), size, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read flash status register to determine if write protect is active */
|
/* Read flash status register to determine if write protect is active */
|
||||||
|
@ -115,7 +127,7 @@ int nvm_protect(void *start, size_t size)
|
||||||
#if IS_ENABLED(CONFIG_MRC_SETTINGS_PROTECT)
|
#if IS_ENABLED(CONFIG_MRC_SETTINGS_PROTECT)
|
||||||
if (nvm_init() < 0)
|
if (nvm_init() < 0)
|
||||||
return -1;
|
return -1;
|
||||||
return spi_flash_protect(to_flash_offset(start), size);
|
return spi_flash_protect(nvm_mmio_to_flash_offset(start), size);
|
||||||
#else
|
#else
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,4 +33,7 @@ int nvm_is_write_protected(void);
|
||||||
/* Apply protection to a range of flash */
|
/* Apply protection to a range of flash */
|
||||||
int nvm_protect(void *start, size_t size);
|
int nvm_protect(void *start, size_t size);
|
||||||
|
|
||||||
|
/* Map MMIO address to actual address in flash */
|
||||||
|
uint32_t nvm_mmio_to_flash_offset(void *p);
|
||||||
|
|
||||||
#endif /* _COMMON_NVM_H_ */
|
#endif /* _COMMON_NVM_H_ */
|
||||||
|
|
Loading…
Reference in New Issue