diff mbox series

[3/8] sunxi: SPL SPI: allow multiple boot attempt

Message ID 20221014030520.3067228-4-uwu@icenowy.me
State Deferred
Delegated to: Tom Rini
Headers show
Series SUNIV SPI NAND support in SPL | expand

Commit Message

Icenowy Zheng Oct. 14, 2022, 3:05 a.m. UTC
As we're going to add support for SPI NAND to this code, add code that
allows multiple boot attempts with different load offsets and functions.

To keep compatibility with loading raw binary on SPI NOR, a bool
parameter is used to allow booting without valid magic number when
booting with SPI NOR.

Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
---
 arch/arm/mach-sunxi/spl_spi_sunxi.c | 58 +++++++++++++++++++----------
 1 file changed, 38 insertions(+), 20 deletions(-)

Comments

Samuel Holland Jan. 14, 2023, 7:56 p.m. UTC | #1
On 10/13/22 22:05, Icenowy Zheng wrote:
> As we're going to add support for SPI NAND to this code, add code that
> allows multiple boot attempts with different load offsets and functions.
> 
> To keep compatibility with loading raw binary on SPI NOR, a bool
> parameter is used to allow booting without valid magic number when
> booting with SPI NOR.

So the issue is that when CONFIG_SPL_RAW_IMAGE_SUPPORT=y, then
spl_parse_image_header() will return 0 even when using the wrong NAND
parameters? I don't see a better solution, so:

Reviewed-by: Samuel Holland <samuel@sholland.org>
Tested-by: Samuel Holland <samuel@sholland.org> # Orange Pi Zero Plus

> Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
> ---
>  arch/arm/mach-sunxi/spl_spi_sunxi.c | 58 +++++++++++++++++++----------
>  1 file changed, 38 insertions(+), 20 deletions(-)
> 
> diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c
> index 88c15a3ee9..21be33a23f 100644
> --- a/arch/arm/mach-sunxi/spl_spi_sunxi.c
> +++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c
> @@ -340,8 +340,8 @@ static void spi0_read_data(void *buf, u32 addr, u32 len, u32 addr_len)
>  	}
>  }
>  
> -static ulong spi_load_read(struct spl_load_info *load, ulong sector,
> -			   ulong count, void *buf)
> +static ulong spi_load_read_nor(struct spl_load_info *load, ulong sector,
> +			       ulong count, void *buf)
>  {
>  	spi0_read_data(buf, sector, count, 3);
>  
> @@ -350,41 +350,59 @@ static ulong spi_load_read(struct spl_load_info *load, ulong sector,
>  
>  /*****************************************************************************/
>  
> -static int spl_spi_load_image(struct spl_image_info *spl_image,
> -			      struct spl_boot_device *bootdev)
> +static int spl_spi_try_load(struct spl_image_info *spl_image,
> +			    struct spl_boot_device *bootdev,
> +			    struct spl_load_info *load, u32 offset,
> +			    bool allow_raw)
>  {
>  	int ret = 0;
>  	struct legacy_img_hdr *header;
> -	uint32_t load_offset = sunxi_get_spl_size();
> -

nit: keep this blank line

>  	header = (struct legacy_img_hdr *)CONFIG_SYS_TEXT_BASE;
> -	load_offset = max_t(uint32_t, load_offset, CONFIG_SYS_SPI_U_BOOT_OFFS);
> -
> -	spi0_init();
>  
> -	spi0_read_data((void *)header, load_offset, 0x40, 3);
> +	if (load->read(load, offset, 0x40, (void *)header) == 0)
> +		return -EINVAL;
>  
>          if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
>  		image_get_magic(header) == FDT_MAGIC) {
> -		struct spl_load_info load;
>  
>  		debug("Found FIT image\n");
> -		load.dev = NULL;
> -		load.priv = NULL;
> -		load.filename = NULL;
> -		load.bl_len = 1;
> -		load.read = spi_load_read;
> -		ret = spl_load_simple_fit(spl_image, &load,
> -					  load_offset, header);
> +		ret = spl_load_simple_fit(spl_image, load,
> +					  offset, header);
>  	} else {
> +		if (!allow_raw && image_get_magic(header) != IH_MAGIC)
> +			return -EINVAL;
> +
>  		ret = spl_parse_image_header(spl_image, bootdev, header);
>  		if (ret)
>  			return ret;
>  
> -		spi0_read_data((void *)spl_image->load_addr,
> -			       load_offset, spl_image->size, 3);
> +		if (load->read(load, offset, spl_image->size,
> +			       (void *)spl_image->load_addr) == 0)
> +			ret = -EINVAL;
>  	}
>  
> +	return ret;
> +}
> +
> +static int spl_spi_load_image(struct spl_image_info *spl_image,
> +			      struct spl_boot_device *bootdev)
> +{
> +	int ret = 0;
> +	uint32_t load_offset = sunxi_get_spl_size();
> +	struct spl_load_info load;
> +
> +	load_offset = max_t(uint32_t, load_offset, CONFIG_SYS_SPI_U_BOOT_OFFS);
> +
> +	load.dev = NULL;
> +	load.priv = NULL;
> +	load.filename = NULL;
> +	load.bl_len = 1;
> +
> +	spi0_init();
> +
> +	load.read = spi_load_read_nor;
> +	ret = spl_spi_try_load(spl_image, bootdev, &load, load_offset, true);
> +
>  	spi0_deinit();
>  
>  	return ret;
Icenowy Zheng Jan. 15, 2023, 12:26 a.m. UTC | #2
于 2023年1月15日 GMT+08:00 上午3:56:08, Samuel Holland <samuel@sholland.org> 写到:
>On 10/13/22 22:05, Icenowy Zheng wrote:
>> As we're going to add support for SPI NAND to this code, add code that
>> allows multiple boot attempts with different load offsets and functions.
>> 
>> To keep compatibility with loading raw binary on SPI NOR, a bool
>> parameter is used to allow booting without valid magic number when
>> booting with SPI NOR.
>
>So the issue is that when CONFIG_SPL_RAW_IMAGE_SUPPORT=y, then
>spl_parse_image_header() will return 0 even when using the wrong NAND
>parameters? I don't see a better solution, so:

Good point, maybe the next patch needs to add some dependency
of raw image support to SPI NAND support option.

>
>Reviewed-by: Samuel Holland <samuel@sholland.org>
>Tested-by: Samuel Holland <samuel@sholland.org> # Orange Pi Zero Plus
>
>> Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
>> ---
>>  arch/arm/mach-sunxi/spl_spi_sunxi.c | 58 +++++++++++++++++++----------
>>  1 file changed, 38 insertions(+), 20 deletions(-)
>> 
>> diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c
>> index 88c15a3ee9..21be33a23f 100644
>> --- a/arch/arm/mach-sunxi/spl_spi_sunxi.c
>> +++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c
>> @@ -340,8 +340,8 @@ static void spi0_read_data(void *buf, u32 addr, u32 len, u32 addr_len)
>>  	}
>>  }
>>  
>> -static ulong spi_load_read(struct spl_load_info *load, ulong sector,
>> -			   ulong count, void *buf)
>> +static ulong spi_load_read_nor(struct spl_load_info *load, ulong sector,
>> +			       ulong count, void *buf)
>>  {
>>  	spi0_read_data(buf, sector, count, 3);
>>  
>> @@ -350,41 +350,59 @@ static ulong spi_load_read(struct spl_load_info *load, ulong sector,
>>  
>>  /*****************************************************************************/
>>  
>> -static int spl_spi_load_image(struct spl_image_info *spl_image,
>> -			      struct spl_boot_device *bootdev)
>> +static int spl_spi_try_load(struct spl_image_info *spl_image,
>> +			    struct spl_boot_device *bootdev,
>> +			    struct spl_load_info *load, u32 offset,
>> +			    bool allow_raw)
>>  {
>>  	int ret = 0;
>>  	struct legacy_img_hdr *header;
>> -	uint32_t load_offset = sunxi_get_spl_size();
>> -
>
>nit: keep this blank line
>
>>  	header = (struct legacy_img_hdr *)CONFIG_SYS_TEXT_BASE;
>> -	load_offset = max_t(uint32_t, load_offset, CONFIG_SYS_SPI_U_BOOT_OFFS);
>> -
>> -	spi0_init();
>>  
>> -	spi0_read_data((void *)header, load_offset, 0x40, 3);
>> +	if (load->read(load, offset, 0x40, (void *)header) == 0)
>> +		return -EINVAL;
>>  
>>          if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
>>  		image_get_magic(header) == FDT_MAGIC) {
>> -		struct spl_load_info load;
>>  
>>  		debug("Found FIT image\n");
>> -		load.dev = NULL;
>> -		load.priv = NULL;
>> -		load.filename = NULL;
>> -		load.bl_len = 1;
>> -		load.read = spi_load_read;
>> -		ret = spl_load_simple_fit(spl_image, &load,
>> -					  load_offset, header);
>> +		ret = spl_load_simple_fit(spl_image, load,
>> +					  offset, header);
>>  	} else {
>> +		if (!allow_raw && image_get_magic(header) != IH_MAGIC)
>> +			return -EINVAL;
>> +
>>  		ret = spl_parse_image_header(spl_image, bootdev, header);
>>  		if (ret)
>>  			return ret;
>>  
>> -		spi0_read_data((void *)spl_image->load_addr,
>> -			       load_offset, spl_image->size, 3);
>> +		if (load->read(load, offset, spl_image->size,
>> +			       (void *)spl_image->load_addr) == 0)
>> +			ret = -EINVAL;
>>  	}
>>  
>> +	return ret;
>> +}
>> +
>> +static int spl_spi_load_image(struct spl_image_info *spl_image,
>> +			      struct spl_boot_device *bootdev)
>> +{
>> +	int ret = 0;
>> +	uint32_t load_offset = sunxi_get_spl_size();
>> +	struct spl_load_info load;
>> +
>> +	load_offset = max_t(uint32_t, load_offset, CONFIG_SYS_SPI_U_BOOT_OFFS);
>> +
>> +	load.dev = NULL;
>> +	load.priv = NULL;
>> +	load.filename = NULL;
>> +	load.bl_len = 1;
>> +
>> +	spi0_init();
>> +
>> +	load.read = spi_load_read_nor;
>> +	ret = spl_spi_try_load(spl_image, bootdev, &load, load_offset, true);
>> +
>>  	spi0_deinit();
>>  
>>  	return ret;
>
diff mbox series

Patch

diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c
index 88c15a3ee9..21be33a23f 100644
--- a/arch/arm/mach-sunxi/spl_spi_sunxi.c
+++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c
@@ -340,8 +340,8 @@  static void spi0_read_data(void *buf, u32 addr, u32 len, u32 addr_len)
 	}
 }
 
-static ulong spi_load_read(struct spl_load_info *load, ulong sector,
-			   ulong count, void *buf)
+static ulong spi_load_read_nor(struct spl_load_info *load, ulong sector,
+			       ulong count, void *buf)
 {
 	spi0_read_data(buf, sector, count, 3);
 
@@ -350,41 +350,59 @@  static ulong spi_load_read(struct spl_load_info *load, ulong sector,
 
 /*****************************************************************************/
 
-static int spl_spi_load_image(struct spl_image_info *spl_image,
-			      struct spl_boot_device *bootdev)
+static int spl_spi_try_load(struct spl_image_info *spl_image,
+			    struct spl_boot_device *bootdev,
+			    struct spl_load_info *load, u32 offset,
+			    bool allow_raw)
 {
 	int ret = 0;
 	struct legacy_img_hdr *header;
-	uint32_t load_offset = sunxi_get_spl_size();
-
 	header = (struct legacy_img_hdr *)CONFIG_SYS_TEXT_BASE;
-	load_offset = max_t(uint32_t, load_offset, CONFIG_SYS_SPI_U_BOOT_OFFS);
-
-	spi0_init();
 
-	spi0_read_data((void *)header, load_offset, 0x40, 3);
+	if (load->read(load, offset, 0x40, (void *)header) == 0)
+		return -EINVAL;
 
         if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
 		image_get_magic(header) == FDT_MAGIC) {
-		struct spl_load_info load;
 
 		debug("Found FIT image\n");
-		load.dev = NULL;
-		load.priv = NULL;
-		load.filename = NULL;
-		load.bl_len = 1;
-		load.read = spi_load_read;
-		ret = spl_load_simple_fit(spl_image, &load,
-					  load_offset, header);
+		ret = spl_load_simple_fit(spl_image, load,
+					  offset, header);
 	} else {
+		if (!allow_raw && image_get_magic(header) != IH_MAGIC)
+			return -EINVAL;
+
 		ret = spl_parse_image_header(spl_image, bootdev, header);
 		if (ret)
 			return ret;
 
-		spi0_read_data((void *)spl_image->load_addr,
-			       load_offset, spl_image->size, 3);
+		if (load->read(load, offset, spl_image->size,
+			       (void *)spl_image->load_addr) == 0)
+			ret = -EINVAL;
 	}
 
+	return ret;
+}
+
+static int spl_spi_load_image(struct spl_image_info *spl_image,
+			      struct spl_boot_device *bootdev)
+{
+	int ret = 0;
+	uint32_t load_offset = sunxi_get_spl_size();
+	struct spl_load_info load;
+
+	load_offset = max_t(uint32_t, load_offset, CONFIG_SYS_SPI_U_BOOT_OFFS);
+
+	load.dev = NULL;
+	load.priv = NULL;
+	load.filename = NULL;
+	load.bl_len = 1;
+
+	spi0_init();
+
+	load.read = spi_load_read_nor;
+	ret = spl_spi_try_load(spl_image, bootdev, &load, load_offset, true);
+
 	spi0_deinit();
 
 	return ret;