lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <86d79a51-d7d9-897e-9a4a-590987270e05@linaro.org>
Date:   Wed, 29 Mar 2023 18:22:35 +0100
From:   Tudor Ambarus <tudor.ambarus@...aro.org>
To:     michael@...le.cc, pratyush@...nel.org
Cc:     miquel.raynal@...tlin.com, richard@....at,
        Takahiro.Kuwano@...ineon.com, bacem.daassi@...ineon.com,
        linux-mtd@...ts.infradead.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH v4 06/11] mtd: spi-nor: Parse BFPT to determine the 4-Byte
 Address Mode methods



On 3/22/23 06:40, Tudor Ambarus wrote:
> BFPT[DWORD(16)] defines the methods to enter and exit the 4-Byte Address
> Mode. Parse BFPT to determine the method. Will rename the methods with
> generic names in a further patch, to keep things trackable in this one.>

I forgot to update the commit message, will respin.

> Some regressions may be introduced by this patch, because the
> params->set_4byte_addr_mode method that was set either in
> spi_nor_init_default_params() or later overwritten in default_init() hooks,
> may now be overwritten with a different value based on the BFPT data. If
> that's the case, the fix is to introduce a post_bfpt fixup hook where one
> should fix the wrong BFPT info.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@...aro.org>
> ---
>  drivers/mtd/spi-nor/sfdp.c    | 11 +++++++++++
>  drivers/mtd/spi-nor/sfdp.h    | 28 ++++++++++++++++++++++++++++
>  drivers/mtd/spi-nor/winbond.c | 11 ++++++++++-
>  3 files changed, 49 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c
> index 298ab5e53a8c..63b2810cf75e 100644
> --- a/drivers/mtd/spi-nor/sfdp.c
> +++ b/drivers/mtd/spi-nor/sfdp.c
> @@ -438,6 +438,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
>  	size_t len;
>  	int i, cmd, err;
>  	u32 addr, val;
> +	u32 dword;
>  	u16 half;
>  	u8 erase_mask;
>  
> @@ -607,6 +608,16 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
>  		break;
>  	}
>  
> +	dword = bfpt.dwords[SFDP_DWORD(16)] & BFPT_DWORD16_4B_ADDR_MODE_MASK;
> +	if (sfdp_bits_set(dword, BFPT_DWORD16_4B_ADDR_MODE_BRWR))
> +		params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode_brwr;
> +	else if (sfdp_bits_set(dword, BFPT_DWORD16_4B_ADDR_MODE_WREN_EN4B_EX4B))
> +		params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode_wren_en4b_ex4b;
> +	else if (sfdp_bits_set(dword, BFPT_DWORD16_4B_ADDR_MODE_EN4B_EX4B))
> +		params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode_en4b_ex4b;
> +	else
> +		dev_dbg(nor->dev, "BFPT: 4-Byte Address Mode method is not recognized or not implemented\n");
> +
>  	/* Soft Reset support. */
>  	if (bfpt.dwords[SFDP_DWORD(16)] & BFPT_DWORD16_SWRST_EN_RST)
>  		nor->flags |= SNOR_F_SOFT_RESET;
> diff --git a/drivers/mtd/spi-nor/sfdp.h b/drivers/mtd/spi-nor/sfdp.h
> index 500659b35655..a4b5fe795f18 100644
> --- a/drivers/mtd/spi-nor/sfdp.h
> +++ b/drivers/mtd/spi-nor/sfdp.h
> @@ -16,6 +16,8 @@
>  /* SFDP DWORDS are indexed from 1 but C arrays are indexed from 0. */
>  #define SFDP_DWORD(i)		((i) - 1)
>  
> +#define sfdp_bits_set(dword, mask)		(((dword) & (mask)) == (mask))

s/sfdp_bits_set/sfdp_mask_check> +
>  /* Basic Flash Parameter Table */
>  
>  /* JESD216 rev D defines a Basic Flash Parameter Table of 20 DWORDs. */
> @@ -89,6 +91,32 @@ struct sfdp_bfpt {
>  #define BFPT_DWORD15_QER_SR2_BIT1_NO_RD		(0x4UL << 20)
>  #define BFPT_DWORD15_QER_SR2_BIT1		(0x5UL << 20) /* Spansion */
>  
> +#define BFPT_DWORD16_EN4B_MASK			GENMASK(31, 24)
> +#define BFPT_DWORD16_EN4B_ALWAYS_4B		BIT(30)
> +#define BFPT_DWORD16_EN4B_4B_OPCODES		BIT(29)
> +#define BFPT_DWORD16_EN4B_16BIT_NV_CR		BIT(28)
> +#define BFPT_DWORD16_EN4B_BRWR			BIT(27)
> +#define BFPT_DWORD16_EN4B_WREAR			BIT(26)
> +#define BFPT_DWORD16_EN4B_WREN_EN4B		BIT(25)
> +#define BFPT_DWORD16_EN4B_EN4B			BIT(24)
> +#define BFPT_DWORD16_EX4B_MASK			GENMASK(18, 14)
> +#define BFPT_DWORD16_EX4B_16BIT_NV_CR		BIT(18)
> +#define BFPT_DWORD16_EX4B_BRWR			BIT(17)
> +#define BFPT_DWORD16_EX4B_WREAR			BIT(16)
> +#define BFPT_DWORD16_EX4B_WREN_EX4B		BIT(15)
> +#define BFPT_DWORD16_EX4B_EX4B			BIT(14)
> +#define BFPT_DWORD16_4B_ADDR_MODE_MASK			\
> +	(BFPT_DWORD16_EN4B_MASK | BFPT_DWORD16_EX4B_MASK)
> +#define BFPT_DWORD16_4B_ADDR_MODE_16BIT_NV_CR		\
> +	(BFPT_DWORD16_EN4B_16BIT_NV_CR | BFPT_DWORD16_EX4B_16BIT_NV_CR)
> +#define BFPT_DWORD16_4B_ADDR_MODE_BRWR			\
> +	(BFPT_DWORD16_EN4B_BRWR | BFPT_DWORD16_EX4B_BRWR)
> +#define BFPT_DWORD16_4B_ADDR_MODE_WREAR			\
> +	(BFPT_DWORD16_EN4B_WREAR | BFPT_DWORD16_EX4B_WREAR)
> +#define BFPT_DWORD16_4B_ADDR_MODE_WREN_EN4B_EX4B	\
> +	(BFPT_DWORD16_EN4B_WREN_EN4B | BFPT_DWORD16_EX4B_WREN_EX4B)
> +#define BFPT_DWORD16_4B_ADDR_MODE_EN4B_EX4B		\
> +	(BFPT_DWORD16_EN4B_EN4B | BFPT_DWORD16_EX4B_EX4B)
>  #define BFPT_DWORD16_SWRST_EN_RST		BIT(12)
>  
>  #define BFPT_DWORD18_CMD_EXT_MASK		GENMASK(30, 29)
> diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c
> index 9cea241c204b..a1b387accc07 100644
> --- a/drivers/mtd/spi-nor/winbond.c
> +++ b/drivers/mtd/spi-nor/winbond.c
> @@ -218,13 +218,22 @@ static const struct spi_nor_otp_ops winbond_nor_otp_ops = {
>  
>  static void winbond_nor_default_init(struct spi_nor *nor)
>  {
> -	nor->params->set_4byte_addr_mode = winbond_nor_set_4byte_addr_mode;
>  }

I should have got ridden of default_init entirely, it's now an empty
function.
>  
>  static void winbond_nor_late_init(struct spi_nor *nor)
>  {
>  	if (nor->params->otp.org->n_regions)
>  		nor->params->otp.ops = &winbond_nor_otp_ops;
> +
> +	/*
> +	 * Winbond seems to require that the Extended Address Register to be set
> +	 * to zero when exiting the 4-Byte Address Mode, at least for W25Q256FV.
> +	 * This requirement is not described in the JESD216 SFDP standard, thus
> +	 * it is Winbond specific. Since we do not know if other Winbond flashes
> +	 * have the same requirement, play safe and overwrite the method parsed
> +	 * from BFPT, if any.
> +	 */
> +	nor->params->set_4byte_addr_mode = winbond_nor_set_4byte_addr_mode;
>  }
>  
>  static const struct spi_nor_fixups winbond_nor_fixups = {

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ