]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
spl: nand: Set bl_len to page size
authorSean Anderson <seanga2@gmail.com>
Sat, 4 Nov 2023 20:37:44 +0000 (16:37 -0400)
committerTom Rini <trini@konsulko.com>
Thu, 16 Nov 2023 17:43:48 +0000 (12:43 -0500)
Since commit 34793598c83 ("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>
13 files changed:
common/spl/spl_nand.c
drivers/mtd/nand/raw/am335x_spl_bch.c
drivers/mtd/nand/raw/atmel_nand.c
drivers/mtd/nand/raw/denali_spl.c
drivers/mtd/nand/raw/fsl_ifc_spl.c
drivers/mtd/nand/raw/lpc32xx_nand_mlc.c
drivers/mtd/nand/raw/mt7621_nand_spl.c
drivers/mtd/nand/raw/mxc_nand_spl.c
drivers/mtd/nand/raw/mxs_nand_spl.c
drivers/mtd/nand/raw/nand.c
drivers/mtd/nand/raw/nand_spl_simple.c
drivers/mtd/nand/raw/sunxi_nand_spl.c
include/nand.h

index 5b6932bf7e07caf8ebe58495edb3627273e8e79d..57a7a1a73b98d4ffb54d8a23edcb4b7ccdd70ac5 100644 (file)
@@ -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);
index fb9c623f5615a42c91a97aa3c4e89e5292004ce1..6831af98b73b46e8971ee26938945db8bcd8f4b8 100644 (file)
@@ -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)
 {
index 83320112952ce8024986a2cf96f7611ba4838b5b..6d94e7af38e9af1ca002ea142e03c812134aa64d 100644 (file)
@@ -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)
index 690279c9976bc3da4bdb04ec2884ff9466789090..165a23312cb59cf6955804972eb2c8db4376635a 100644 (file)
@@ -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) {}
index c67065eaf8cad392c857eb7dd118278663c494d4..69d26f1f79abb89700a740c4201e116664e8fa64 100644 (file)
@@ -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)
 {
 }
index ac2e669d46b38a0f678027b2cd92fc228fda7f9d..f8ae216d56c659a9c36db566c57bd6033b9bff11 100644 (file)
@@ -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 */
index 114fc8b7ceaca78e6c72fd4c65cdd241a66b0649..a2be9ba80e0ad5a2f508448e77c0f15fa2e5b5f5 100644 (file)
@@ -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)
 {
 }
index 81ceb12103bd8af345d99199e7983131a4476ed5..a855c9987f803e452b1c3469c2eeeb8e703c5a02 100644 (file)
@@ -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;
+}
index 300662994cf22a0d252164ec17c3f725ad33e5c9..f7d3f02f85a040cd0ceed0412276c295b8f2782d 100644 (file)
@@ -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)
 {
 }
index eacd99c4e2756abf41fcda476acaef468f1f0c3c..4da4143879084fc35102985f54fc191a3faea5e2 100644 (file)
@@ -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;
+}
index bbdb76d6b75ba6c29c201d9707efb47a50bbb02c..80d6e0e1e4efa27f451a003af6b8bb32771021ac 100644 (file)
@@ -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)
 {
index 6de0b0a35545958a063151493485c7b9ec628a1e..c9b8c78ed7523a53b6d0bb253af66a4c1a8dcc9b 100644 (file)
@@ -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 =
index 70c1286ccb406e3a801f882ef43b5ffe2afd956f..c1d7533aaac9876b8aa80201bf5a19f9c3938827 100644 (file)
@@ -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>