diff mbox series

[v3,4/8] m25p80: Add the mx25l25635f SFPD table

Message ID 20220722063602.128144-5-clg@kaod.org
State New
Headers show
Series m25p80: Add SFDP support | expand

Commit Message

Cédric Le Goater July 22, 2022, 6:35 a.m. UTC
The mx25l25635e and mx25l25635f chips have the same JEDEC id but the
mx25l25635f has more capabilities reported in the SFDP table. Support
for 4B opcodes is of interest because it is exploited by the Linux
kernel.

The SFDP table size is 0x200 bytes long. The mandatory table for basic
features is available at byte 0x30 and an extra Macronix specific
table is available at 0x60.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/block/m25p80_sfdp.h |  1 +
 hw/block/m25p80.c      |  2 ++
 hw/block/m25p80_sfdp.c | 68 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 71 insertions(+)

Comments

Francisco Iglesias Oct. 7, 2022, 2:44 p.m. UTC | #1
On [2022 Jul 22] Fri 08:35:58, Cédric Le Goater wrote:
> The mx25l25635e and mx25l25635f chips have the same JEDEC id but the
> mx25l25635f has more capabilities reported in the SFDP table. Support
> for 4B opcodes is of interest because it is exploited by the Linux
> kernel.
> 
> The SFDP table size is 0x200 bytes long. The mandatory table for basic
> features is available at byte 0x30 and an extra Macronix specific
> table is available at 0x60.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  hw/block/m25p80_sfdp.h |  1 +
>  hw/block/m25p80.c      |  2 ++
>  hw/block/m25p80_sfdp.c | 68 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 71 insertions(+)
> 
> diff --git a/hw/block/m25p80_sfdp.h b/hw/block/m25p80_sfdp.h
> index 0c46e669b335..87690a173c78 100644
> --- a/hw/block/m25p80_sfdp.h
> +++ b/hw/block/m25p80_sfdp.h
> @@ -18,6 +18,7 @@
>  extern uint8_t m25p80_sfdp_n25q256a(uint32_t addr);
>  
>  extern uint8_t m25p80_sfdp_mx25l25635e(uint32_t addr);
> +extern uint8_t m25p80_sfdp_mx25l25635f(uint32_t addr);
(optional -extern above)

>  
>  
>  #endif
> diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
> index 028b026d8ba2..6b120ce65212 100644
> --- a/hw/block/m25p80.c
> +++ b/hw/block/m25p80.c
> @@ -234,6 +234,8 @@ static const FlashPartInfo known_devices[] = {
>      { INFO("mx25l12855e", 0xc22618,      0,  64 << 10, 256, 0) },
>      { INFO6("mx25l25635e", 0xc22019,     0xc22019,  64 << 10, 512, 0),
>        .sfdp_read = m25p80_sfdp_mx25l25635e },
> +    { INFO6("mx25l25635f", 0xc22019,     0xc22019,  64 << 10, 512, 0),

I think I'm not seeing the extended id part in the datasheet I've found so
might be that you can switch to just INFO and _ext_id 0 above (might be the
same in the previous patch with the similar flash). Otherwise looks good to
me:

Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>


> +      .sfdp_read = m25p80_sfdp_mx25l25635f },
>      { INFO("mx25l25655e", 0xc22619,      0,  64 << 10, 512, 0) },
>      { INFO("mx66l51235f", 0xc2201a,      0,  64 << 10, 1024, ER_4K | ER_32K) },
>      { INFO("mx66u51235f", 0xc2253a,      0,  64 << 10, 1024, ER_4K | ER_32K) },
> diff --git a/hw/block/m25p80_sfdp.c b/hw/block/m25p80_sfdp.c
> index 6499c4c39954..70c13aea7c63 100644
> --- a/hw/block/m25p80_sfdp.c
> +++ b/hw/block/m25p80_sfdp.c
> @@ -82,3 +82,71 @@ static const uint8_t sfdp_mx25l25635e[] = {
>      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>  };
>  define_sfdp_read(mx25l25635e)
> +
> +static const uint8_t sfdp_mx25l25635f[] = {
> +    0x53, 0x46, 0x44, 0x50, 0x00, 0x01, 0x01, 0xff,
> +    0x00, 0x00, 0x01, 0x09, 0x30, 0x00, 0x00, 0xff,
> +    0xc2, 0x00, 0x01, 0x04, 0x60, 0x00, 0x00, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xe5, 0x20, 0xf3, 0xff, 0xff, 0xff, 0xff, 0x0f,
> +    0x44, 0xeb, 0x08, 0x6b, 0x08, 0x3b, 0x04, 0xbb,
> +    0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff,
> +    0xff, 0xff, 0x44, 0xeb, 0x0c, 0x20, 0x0f, 0x52,
> +    0x10, 0xd8, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0x00, 0x36, 0x00, 0x27, 0x9d, 0xf9, 0xc0, 0x64,
> +    0x85, 0xcb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xc2, 0xf5, 0x08, 0x0a,
> +    0x08, 0x04, 0x03, 0x06, 0x00, 0x00, 0x07, 0x29,
> +    0x17, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +};
> +define_sfdp_read(mx25l25635f);
> -- 
> 2.35.3
>
Cédric Le Goater Oct. 10, 2022, 6:23 a.m. UTC | #2
On 10/7/22 16:44, Francisco Iglesias wrote:
> On [2022 Jul 22] Fri 08:35:58, Cédric Le Goater wrote:
>> The mx25l25635e and mx25l25635f chips have the same JEDEC id but the
>> mx25l25635f has more capabilities reported in the SFDP table. Support
>> for 4B opcodes is of interest because it is exploited by the Linux
>> kernel.
>>
>> The SFDP table size is 0x200 bytes long. The mandatory table for basic
>> features is available at byte 0x30 and an extra Macronix specific
>> table is available at 0x60.
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>>   hw/block/m25p80_sfdp.h |  1 +
>>   hw/block/m25p80.c      |  2 ++
>>   hw/block/m25p80_sfdp.c | 68 ++++++++++++++++++++++++++++++++++++++++++
>>   3 files changed, 71 insertions(+)
>>
>> diff --git a/hw/block/m25p80_sfdp.h b/hw/block/m25p80_sfdp.h
>> index 0c46e669b335..87690a173c78 100644
>> --- a/hw/block/m25p80_sfdp.h
>> +++ b/hw/block/m25p80_sfdp.h
>> @@ -18,6 +18,7 @@
>>   extern uint8_t m25p80_sfdp_n25q256a(uint32_t addr);
>>   
>>   extern uint8_t m25p80_sfdp_mx25l25635e(uint32_t addr);
>> +extern uint8_t m25p80_sfdp_mx25l25635f(uint32_t addr);
> (optional -extern above)
> 
>>   
>>   
>>   #endif
>> diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
>> index 028b026d8ba2..6b120ce65212 100644
>> --- a/hw/block/m25p80.c
>> +++ b/hw/block/m25p80.c
>> @@ -234,6 +234,8 @@ static const FlashPartInfo known_devices[] = {
>>       { INFO("mx25l12855e", 0xc22618,      0,  64 << 10, 256, 0) },
>>       { INFO6("mx25l25635e", 0xc22019,     0xc22019,  64 << 10, 512, 0),
>>         .sfdp_read = m25p80_sfdp_mx25l25635e },
>> +    { INFO6("mx25l25635f", 0xc22019,     0xc22019,  64 << 10, 512, 0),
> 
> I think I'm not seeing the extended id part in the datasheet I've found so
> might be that you can switch to just INFO and _ext_id 0 above

This was added by commit 6bbe036f32dc ("m25p80: Return the JEDEC ID twice for
mx25l25635e") to fix a real breakage on HW.

Thanks,

C.


  (might be the
> same in the previous patch with the similar flash). Otherwise looks good to
> me:
> 
> Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
> 
> 
>> +      .sfdp_read = m25p80_sfdp_mx25l25635f },
>>       { INFO("mx25l25655e", 0xc22619,      0,  64 << 10, 512, 0) },
>>       { INFO("mx66l51235f", 0xc2201a,      0,  64 << 10, 1024, ER_4K | ER_32K) },
>>       { INFO("mx66u51235f", 0xc2253a,      0,  64 << 10, 1024, ER_4K | ER_32K) },
>> diff --git a/hw/block/m25p80_sfdp.c b/hw/block/m25p80_sfdp.c
>> index 6499c4c39954..70c13aea7c63 100644
>> --- a/hw/block/m25p80_sfdp.c
>> +++ b/hw/block/m25p80_sfdp.c
>> @@ -82,3 +82,71 @@ static const uint8_t sfdp_mx25l25635e[] = {
>>       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>>   };
>>   define_sfdp_read(mx25l25635e)
>> +
>> +static const uint8_t sfdp_mx25l25635f[] = {
>> +    0x53, 0x46, 0x44, 0x50, 0x00, 0x01, 0x01, 0xff,
>> +    0x00, 0x00, 0x01, 0x09, 0x30, 0x00, 0x00, 0xff,
>> +    0xc2, 0x00, 0x01, 0x04, 0x60, 0x00, 0x00, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xe5, 0x20, 0xf3, 0xff, 0xff, 0xff, 0xff, 0x0f,
>> +    0x44, 0xeb, 0x08, 0x6b, 0x08, 0x3b, 0x04, 0xbb,
>> +    0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff,
>> +    0xff, 0xff, 0x44, 0xeb, 0x0c, 0x20, 0x0f, 0x52,
>> +    0x10, 0xd8, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0x00, 0x36, 0x00, 0x27, 0x9d, 0xf9, 0xc0, 0x64,
>> +    0x85, 0xcb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xc2, 0xf5, 0x08, 0x0a,
>> +    0x08, 0x04, 0x03, 0x06, 0x00, 0x00, 0x07, 0x29,
>> +    0x17, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>> +};
>> +define_sfdp_read(mx25l25635f);
>> -- 
>> 2.35.3
>>
Michael Walle Oct. 10, 2022, 9:58 a.m. UTC | #3
Am 2022-10-10 08:23, schrieb Cédric Le Goater:
> On 10/7/22 16:44, Francisco Iglesias wrote:

>>> --- a/hw/block/m25p80.c
>>> +++ b/hw/block/m25p80.c
>>> @@ -234,6 +234,8 @@ static const FlashPartInfo known_devices[] = {
>>>       { INFO("mx25l12855e", 0xc22618,      0,  64 << 10, 256, 0) },
>>>       { INFO6("mx25l25635e", 0xc22019,     0xc22019,  64 << 10, 512, 
>>> 0),
>>>         .sfdp_read = m25p80_sfdp_mx25l25635e },
>>> +    { INFO6("mx25l25635f", 0xc22019,     0xc22019,  64 << 10, 512, 
>>> 0),
>> 
>> I think I'm not seeing the extended id part in the datasheet I've 
>> found so
>> might be that you can switch to just INFO and _ext_id 0 above
> 
> This was added by commit 6bbe036f32dc ("m25p80: Return the JEDEC ID 
> twice for
> mx25l25635e") to fix a real breakage on HW.

 From my experience, the ID has a particular length, at least three bytes
and if you read past that length for some (all?) devices the id bytes 
just
get repeated. I.e. the counter in the device will just wrap to offset 0
again. If you want to emulate the hardware correctly, you would have to
take that into consideration.
But I don't think it's worth it, OTOH there seems to be some broken
software which rely on that (undefined?) behavior.

-michael
Francisco Iglesias Oct. 10, 2022, 10:51 a.m. UTC | #4
Hi  Cedric,

On [2022 Oct 10] Mon 11:58:40, Michael Walle wrote:
> Am 2022-10-10 08:23, schrieb Cédric Le Goater:
> > On 10/7/22 16:44, Francisco Iglesias wrote:
> 
> > > > --- a/hw/block/m25p80.c
> > > > +++ b/hw/block/m25p80.c
> > > > @@ -234,6 +234,8 @@ static const FlashPartInfo known_devices[] = {
> > > >       { INFO("mx25l12855e", 0xc22618,      0,  64 << 10, 256, 0) },
> > > >       { INFO6("mx25l25635e", 0xc22019,     0xc22019,  64 << 10,
> > > > 512, 0),
> > > >         .sfdp_read = m25p80_sfdp_mx25l25635e },
> > > > +    { INFO6("mx25l25635f", 0xc22019,     0xc22019,  64 << 10,
> > > > 512, 0),

I think I missed the (ER_4K | ER_32K) flags above (in case we go for a v4 we 
can add it in). 

> > > 
> > > I think I'm not seeing the extended id part in the datasheet I've
> > > found so
> > > might be that you can switch to just INFO and _ext_id 0 above
> > 
> > This was added by commit 6bbe036f32dc ("m25p80: Return the JEDEC ID
> > twice for
> > mx25l25635e") to fix a real breakage on HW.
> 
> From my experience, the ID has a particular length, at least three bytes
> and if you read past that length for some (all?) devices the id bytes just
> get repeated. I.e. the counter in the device will just wrap to offset 0
> again. If you want to emulate the hardware correctly, you would have to
> take that into consideration.

If we decide to go with Michael's proposal above you can use '0' on the
'extended_id' and enable 's->data_read_loop = true' when reading the ID.

Best regards,
Francisco

> But I don't think it's worth it, OTOH there seems to be some broken
> software which rely on that (undefined?) behavior.
> 
> -michael
Cédric Le Goater Oct. 10, 2022, 3 p.m. UTC | #5
On 10/10/22 11:58, Michael Walle wrote:
> Am 2022-10-10 08:23, schrieb Cédric Le Goater:
>> On 10/7/22 16:44, Francisco Iglesias wrote:
> 
>>>> --- a/hw/block/m25p80.c
>>>> +++ b/hw/block/m25p80.c
>>>> @@ -234,6 +234,8 @@ static const FlashPartInfo known_devices[] = {
>>>>       { INFO("mx25l12855e", 0xc22618,      0,  64 << 10, 256, 0) },
>>>>       { INFO6("mx25l25635e", 0xc22019,     0xc22019,  64 << 10, 512, 0),
>>>>         .sfdp_read = m25p80_sfdp_mx25l25635e },
>>>> +    { INFO6("mx25l25635f", 0xc22019,     0xc22019,  64 << 10, 512, 0),
>>>
>>> I think I'm not seeing the extended id part in the datasheet I've found so
>>> might be that you can switch to just INFO and _ext_id 0 above
>>
>> This was added by commit 6bbe036f32dc ("m25p80: Return the JEDEC ID twice for
>> mx25l25635e") to fix a real breakage on HW.
> 
>  From my experience, the ID has a particular length, at least three bytes
> and if you read past that length for some (all?) devices the id bytes just
> get repeated. I.e. the counter in the device will just wrap to offset 0
> again. 
At the time, I did some specific tests on these mx25l25635e chips and
this how they behaved. I can not check anymore as I don't have access
to these systems.

> If you want to emulate the hardware correctly, you would have to
> take that into consideration.

But this is not the case for all chips, most return 0 and don't
wrap around. I just did on w25q512jvq and w25q256 chips with a 6.0.

> But I don't think it's worth it, OTOH there seems to be some broken
> software which rely on that (undefined?) behavior.

I can't really tell :/ The driver (kernel based Linux 2.6.28) reads
4 bytes and expect the last to be the Manufacturer id: 0xC2. That's
valid for this chip.

Setting an extended ID in the flash info is an alternative :

   { INFO("mx25l25635e", 0xc22019,     0xc200,  ...

which does not seem to break other machines using mx25l25635e, with
recent kernels at least.

To reproduce, grab :

   http://smbserver.frankfurt.de.velia.net/ipmi/SMT_X11_158.bin

Run :

   qemu-system-arm -M supermicrox11-bmc -nic user -drive file=./SMT_X11_158.bin,format=raw,if=mtd -nographic -serial mon:stdio
   ...
   BMC flash ID:0xc21920c2
    platform_flash: MX25L25635E (32768 Kbytes)
   Creating 7 MTD partitions on "spi0.0":
   ...

C.
Cédric Le Goater Oct. 10, 2022, 3:11 p.m. UTC | #6
On 10/10/22 12:51, Francisco Iglesias wrote:
> Hi  Cedric,
> 
> On [2022 Oct 10] Mon 11:58:40, Michael Walle wrote:
>> Am 2022-10-10 08:23, schrieb Cédric Le Goater:
>>> On 10/7/22 16:44, Francisco Iglesias wrote:
>>
>>>>> --- a/hw/block/m25p80.c
>>>>> +++ b/hw/block/m25p80.c
>>>>> @@ -234,6 +234,8 @@ static const FlashPartInfo known_devices[] = {
>>>>>        { INFO("mx25l12855e", 0xc22618,      0,  64 << 10, 256, 0) },
>>>>>        { INFO6("mx25l25635e", 0xc22019,     0xc22019,  64 << 10,
>>>>> 512, 0),
>>>>>          .sfdp_read = m25p80_sfdp_mx25l25635e },
>>>>> +    { INFO6("mx25l25635f", 0xc22019,     0xc22019,  64 << 10,
>>>>> 512, 0),
> 
> I think I missed the (ER_4K | ER_32K) flags above (in case we go for a v4 we
> can add it in).

sure.

>>>>
>>>> I think I'm not seeing the extended id part in the datasheet I've
>>>> found so
>>>> might be that you can switch to just INFO and _ext_id 0 above
>>>
>>> This was added by commit 6bbe036f32dc ("m25p80: Return the JEDEC ID
>>> twice for
>>> mx25l25635e") to fix a real breakage on HW.
>>
>>  From my experience, the ID has a particular length, at least three bytes
>> and if you read past that length for some (all?) devices the id bytes just
>> get repeated. I.e. the counter in the device will just wrap to offset 0
>> again. If you want to emulate the hardware correctly, you would have to
>> take that into consideration.
> 
> If we decide to go with Michael's proposal above you can use '0' on the
> 'extended_id' and enable 's->data_read_loop = true' when reading the ID.

This part :

             for (; i < SPI_NOR_MAX_ID_LEN; i++) {
                 s->data[i] = 0;
             }

will fill the remaining JEDEC ID bytes with zeros which is not what we
want for the mx25l25635e chip.

Thanks,
C.

> Best regards,
> Francisco
> 
>> But I don't think it's worth it, OTOH there seems to be some broken
>> software which rely on that (undefined?) behavior.
>>
>> -michael
>
diff mbox series

Patch

diff --git a/hw/block/m25p80_sfdp.h b/hw/block/m25p80_sfdp.h
index 0c46e669b335..87690a173c78 100644
--- a/hw/block/m25p80_sfdp.h
+++ b/hw/block/m25p80_sfdp.h
@@ -18,6 +18,7 @@ 
 extern uint8_t m25p80_sfdp_n25q256a(uint32_t addr);
 
 extern uint8_t m25p80_sfdp_mx25l25635e(uint32_t addr);
+extern uint8_t m25p80_sfdp_mx25l25635f(uint32_t addr);
 
 
 #endif
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 028b026d8ba2..6b120ce65212 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -234,6 +234,8 @@  static const FlashPartInfo known_devices[] = {
     { INFO("mx25l12855e", 0xc22618,      0,  64 << 10, 256, 0) },
     { INFO6("mx25l25635e", 0xc22019,     0xc22019,  64 << 10, 512, 0),
       .sfdp_read = m25p80_sfdp_mx25l25635e },
+    { INFO6("mx25l25635f", 0xc22019,     0xc22019,  64 << 10, 512, 0),
+      .sfdp_read = m25p80_sfdp_mx25l25635f },
     { INFO("mx25l25655e", 0xc22619,      0,  64 << 10, 512, 0) },
     { INFO("mx66l51235f", 0xc2201a,      0,  64 << 10, 1024, ER_4K | ER_32K) },
     { INFO("mx66u51235f", 0xc2253a,      0,  64 << 10, 1024, ER_4K | ER_32K) },
diff --git a/hw/block/m25p80_sfdp.c b/hw/block/m25p80_sfdp.c
index 6499c4c39954..70c13aea7c63 100644
--- a/hw/block/m25p80_sfdp.c
+++ b/hw/block/m25p80_sfdp.c
@@ -82,3 +82,71 @@  static const uint8_t sfdp_mx25l25635e[] = {
     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 };
 define_sfdp_read(mx25l25635e)
+
+static const uint8_t sfdp_mx25l25635f[] = {
+    0x53, 0x46, 0x44, 0x50, 0x00, 0x01, 0x01, 0xff,
+    0x00, 0x00, 0x01, 0x09, 0x30, 0x00, 0x00, 0xff,
+    0xc2, 0x00, 0x01, 0x04, 0x60, 0x00, 0x00, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xe5, 0x20, 0xf3, 0xff, 0xff, 0xff, 0xff, 0x0f,
+    0x44, 0xeb, 0x08, 0x6b, 0x08, 0x3b, 0x04, 0xbb,
+    0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff,
+    0xff, 0xff, 0x44, 0xeb, 0x0c, 0x20, 0x0f, 0x52,
+    0x10, 0xd8, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0x00, 0x36, 0x00, 0x27, 0x9d, 0xf9, 0xc0, 0x64,
+    0x85, 0xcb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xc2, 0xf5, 0x08, 0x0a,
+    0x08, 0x04, 0x03, 0x06, 0x00, 0x00, 0x07, 0x29,
+    0x17, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+};
+define_sfdp_read(mx25l25635f);