mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-03-16 23:07:00 +00:00
spl: nand: Set bl_len to page size
Since commit 34793598c8
("mtd: nand: mxs_nand_spl: Remove the page aligned
access") there are no longer any users of nand_get_mtd. However, it is
still important to know what the page size is so we can allocate a
large-enough buffer. If the image size is not page-aligned, we will go off
the end of the buffer and clobber some memory.
Introduce a new function nand_page_size which returns the page size. For
most drivers it is easy to determine the page size. However, a few need to
be modified since they only keep the page size around temporarily.
It's possible that this patch could cause a regression on some platforms if
the offset is non-aligned and there is invalid address space immediately
before the load address. spl_load_legacy_img does not (except when
compressing) respect bl_len, so only boards with SPL_LOAD_FIT (8 boards) or
SPL_LOAD_IMX_CONTAINER (none in tree) would be affected.
defconfig CONFIG_TEXT_BASE
======================= ================
am335x_evm 0x80800000
am43xx_evm 0x80800000
am43xx_evm_rtconly 0x80800000
am43xx_evm_usbhost_boot 0x80800000
am43xx_hs_evm 0x80800000
dra7xx_evm 0x80800000
gwventana_nand 0x17800000
imx8mn_bsh_smm_s2 0x40200000
All the sitara boards have DDR mapped at 0x80000000. gwventana is an i.MX6Q
which has DDR at 0x10000000. I don't have the IMX8MNRM handy, but on the
i.MX8M DDR starts at 0x40000000. Therefore all of these boards can handle a
little underflow.
Signed-off-by: Sean Anderson <seanga2@gmail.com>
This commit is contained in:
parent
57d3da6fee
commit
38ef64e6ce
13 changed files with 66 additions and 9 deletions
|
@ -72,23 +72,18 @@ static ulong spl_nand_legacy_read(struct spl_load_info *load, ulong offs,
|
|||
return size;
|
||||
}
|
||||
|
||||
struct mtd_info * __weak nand_get_mtd(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int spl_nand_load_element(struct spl_image_info *spl_image,
|
||||
struct spl_boot_device *bootdev,
|
||||
int offset, struct legacy_img_hdr *header)
|
||||
{
|
||||
struct mtd_info *mtd = nand_get_mtd();
|
||||
int bl_len = mtd ? mtd->writesize : 1;
|
||||
int bl_len;
|
||||
int err;
|
||||
|
||||
err = nand_spl_load_image(offset, sizeof(*header), (void *)header);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
bl_len = nand_page_size();
|
||||
if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
|
||||
image_get_magic(header) == FDT_MAGIC) {
|
||||
struct spl_load_info load;
|
||||
|
@ -118,7 +113,7 @@ static int spl_nand_load_element(struct spl_image_info *spl_image,
|
|||
load.dev = NULL;
|
||||
load.priv = NULL;
|
||||
load.filename = NULL;
|
||||
load.bl_len = 1;
|
||||
load.bl_len = IS_ENABLED(CONFIG_SPL_LZMA) ? bl_len : 1;
|
||||
load.read = spl_nand_legacy_read;
|
||||
|
||||
return spl_load_legacy_img(spl_image, bootdev, &load, offset, header);
|
||||
|
|
|
@ -218,6 +218,11 @@ void nand_init(void)
|
|||
nand_command(0, 0, 0, NAND_CMD_RESET);
|
||||
}
|
||||
|
||||
unsigned int nand_page_size(void)
|
||||
{
|
||||
return nand_to_mtd(&nand_chip)->writesize;
|
||||
}
|
||||
|
||||
/* Unselect after operation */
|
||||
void nand_deselect(void)
|
||||
{
|
||||
|
|
|
@ -1452,6 +1452,11 @@ void nand_init(void)
|
|||
nand_chip.select_chip(mtd, 0);
|
||||
}
|
||||
|
||||
unsigned int nand_page_size(void)
|
||||
{
|
||||
return nand_to_mtd(&nand_chip)->writesize;
|
||||
}
|
||||
|
||||
void nand_deselect(void)
|
||||
{
|
||||
if (nand_chip.select_chip)
|
||||
|
|
|
@ -234,4 +234,9 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned int nand_page_size(void)
|
||||
{
|
||||
return page_size;
|
||||
}
|
||||
|
||||
void nand_deselect(void) {}
|
||||
|
|
|
@ -106,6 +106,8 @@ static inline int bad_block(uchar *marker, int port_size)
|
|||
return __raw_readw((u16 *)marker) != 0xffff;
|
||||
}
|
||||
|
||||
static int saved_page_size;
|
||||
|
||||
int nand_spl_load_image(uint32_t offs, unsigned int uboot_size, void *vdst)
|
||||
{
|
||||
struct fsl_ifc_fcm *gregs = (void *)CFG_SYS_IFC_ADDR;
|
||||
|
@ -150,6 +152,7 @@ int nand_spl_load_image(uint32_t offs, unsigned int uboot_size, void *vdst)
|
|||
if (port_size == 8)
|
||||
bad_marker = 5;
|
||||
}
|
||||
saved_page_size = page_size;
|
||||
|
||||
ver = ifc_in32(&gregs->ifc_rev);
|
||||
if (ver >= FSL_IFC_V2_0_0)
|
||||
|
@ -302,6 +305,11 @@ void nand_init(void)
|
|||
{
|
||||
}
|
||||
|
||||
unsigned int nand_page_size(void)
|
||||
{
|
||||
return saved_page_size;
|
||||
}
|
||||
|
||||
void nand_deselect(void)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -765,4 +765,9 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned int nand_page_size(void)
|
||||
{
|
||||
return BYTES_PER_PAGE;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SPL_BUILD */
|
||||
|
|
|
@ -203,6 +203,11 @@ unsigned long nand_size(void)
|
|||
return SZ_2G;
|
||||
}
|
||||
|
||||
unsigned int nand_page_size(void)
|
||||
{
|
||||
return nfc_dev.nand.mtd.writesize;
|
||||
}
|
||||
|
||||
void nand_deselect(void)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -351,3 +351,8 @@ __used void nand_boot(void)
|
|||
|
||||
void nand_init(void) {}
|
||||
void nand_deselect(void) {}
|
||||
|
||||
unsigned int nand_page_size(void)
|
||||
{
|
||||
return CONFIG_SYS_NAND_PAGE_SIZE;
|
||||
}
|
||||
|
|
|
@ -295,6 +295,11 @@ int nand_default_bbt(struct mtd_info *mtd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned int nand_page_size(void)
|
||||
{
|
||||
return nand_to_mtd(&nand_chip)->writesize;
|
||||
}
|
||||
|
||||
void nand_deselect(void)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -174,3 +174,10 @@ void nand_init(void)
|
|||
|
||||
create_mtd_concat();
|
||||
}
|
||||
|
||||
unsigned int nand_page_size(void)
|
||||
{
|
||||
struct mtd_info *mtd = get_nand_dev_by_index(nand_curr_device);
|
||||
|
||||
return mtd ? mtd->writesize : 1;
|
||||
}
|
||||
|
|
|
@ -227,6 +227,11 @@ void nand_init(void)
|
|||
nand_chip.select_chip(mtd, 0);
|
||||
}
|
||||
|
||||
unsigned int nand_page_size(void)
|
||||
{
|
||||
return nand_to_mtd(&nand_chip)->writesize;
|
||||
}
|
||||
|
||||
/* Unselect after operation */
|
||||
void nand_deselect(void)
|
||||
{
|
||||
|
|
|
@ -524,9 +524,10 @@ static int nand_read_buffer(struct nfc_config *conf, uint32_t offs,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct nfc_config conf;
|
||||
|
||||
int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest)
|
||||
{
|
||||
static struct nfc_config conf = { };
|
||||
int ret;
|
||||
|
||||
ret = nand_detect_config(&conf, offs, dest);
|
||||
|
@ -536,6 +537,11 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest)
|
|||
return nand_read_buffer(&conf, offs, size, dest);
|
||||
}
|
||||
|
||||
unsigned int nand_page_size(void)
|
||||
{
|
||||
return conf.page_size;
|
||||
}
|
||||
|
||||
void nand_deselect(void)
|
||||
{
|
||||
struct sunxi_ccm_reg *const ccm =
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
extern void nand_init(void);
|
||||
unsigned long nand_size(void);
|
||||
unsigned int nand_page_size(void);
|
||||
|
||||
#include <linux/compat.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
|
|
Loading…
Add table
Reference in a new issue