2014-01-13 09:03:07

by Boris BREZILLON

[permalink] [raw]
Subject: Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support

Hi Henrik,

On 11/01/2014 22:11, Henrik Nordström wrote:
> <bbrezillon> thanks for pointing out your documents
> <bbrezillon> I'm trying to get the NAND driver with HW ECC (and HW RND)
> without using DMA at all
>
> I tried many things but did not quite get the ECC reading command to
> return meaningful resuts. But should work somehow.
>
> <bbrezillon> do you have any other information I could use to do this ?
>
> Not really. There is no known code to look at using the nand controller
> without DMA. All allwinner code uses DMA even the boot ROM (BROM).
>
> <bbrezillon> For example, I wonder why there are 2 RAM sectors (the
> driver I found only make use of RAM0)
>
> I think it's used during DMA to fetch next sector while the previous one
> is transferred by DMA. But not sure.

Some feedback on my tests:

- I managed to get HW ECC working without any DMA transfer (using CMD = 01):
* I only tested the sequential ECC => ECC are stored between 2 data
blocks (1024 byte)
* Non sequential ECC should work if I store ECC bytes in the OOB area
too (I'll just have
to send RANDOM_OUT commands to move to the OOB area before sending
the ECC
cmd and another RANDOM_OUT to go back to the DATA area)

- The HW RND (randomizer) works too, I'll just have to figure out how
this could be
mainlined:
* using a simple dt property to tell the controller it should enable
the randomizer
* provide an interface (like the nand_ecc_ctrl struct ) for other to
add their own
randomizer implementation (this was requested:
https://lkml.org/lkml/2013/12/13/154)


The most complicated part is the boot0 partition.

Tell me if I'm wrong, but here's what I understood from your work (and
yuq's work too):

boot 0 part properties:
- uses sequential ECC
- uses 1024 bytes ECC blocks
- boot0 code is stored only on the first ECC block of each page (1024
bytes + ecc bytes)
- boot0 code is stored on the first 64 pages of the first block
- boot0 uses HW randomizer with a specific rnd seed (0x4a80)

It's not that complicated to read/write from/to boot0, but it's a bit
more to mainline this
implementation:
- the nand chip must use the same ECC algorithm and ECC layout on the
whole flash
(no partition specific config available)
- you cannot mark some part of pages as unused => the nand driver will
write the
whole page, not just the first ECC block (1024 bytes)

I thought about manually creating an mtd device that fullfils these
needs (in case we
encounter the "allwinner,nandn-boot" property on a nand@X node), but I'm
not sure
this is the right approach.

Any ideas ?


Best Regards,

Boris
>
> Regards
> Henrik
>


2014-01-13 10:03:10

by Henrik Nordström

[permalink] [raw]
Subject: Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support

mån 2014-01-13 klockan 10:02 +0100 skrev boris brezillon:

> The most complicated part is the boot0 partition.

Not really. It's only a little different (sequential ECC, static
randomizer seed on every page).

> Tell me if I'm wrong, but here's what I understood from your work (and
> yuq's work too):
>
> boot 0 part properties:
> - uses sequential ECC

Yes

> - uses 1024 bytes ECC blocks

Seems to support a couple modes.

> - boot0 code is stored only on the first ECC block of each page (1024
> bytes + ecc bytes)

No, it reads a whole page at a time in sequental mode
(data,ecc,data,ecc,data,ecc,data,ecc...).

> - boot0 code is stored on the first 64 pages of the first block

boot0 is restricted in size by available memory size (24KB max).

iirc multiple blocks is tried until a valid one is found.

also I am pretty sure boot1 is stored using the same flash format, but
have not looked in detail at how boot0 reads boot1 as it's a detail of
boot0 software implementation and not needed when using u-boot.

> - boot0 uses HW randomizer with a specific rnd seed (0x4a80)

Yes.

> It's not that complicated to read/write from/to boot0, but it's a bit
> more to mainline this
> implementation:

Ah, yes. It's different.

But isn't there other SoCs having similar issue with NAND boot blocks?
Maybe some guidance can be found there?

Qiang Yu (yuq) selected to implement the sunxi boot area driver using a
custom character device in his attempt in writing a sunxi mtd driver.
That approach works, but can't comment on if it's the right approach or
not.

https://github.com/yuq/sunxi-nfc-mtd

> - the nand chip must use the same ECC algorithm and ECC layout on the
> whole flash
> (no partition specific config available)

iirc there is an interface for dynamically selecting ECC mode and other
parameers. Or maybe that's only u-boot mtd?

> - you cannot mark some part of pages as unused => the nand driver will
> write the
> whole page, not just the first ECC block (1024 bytes)

Not sure what you mean. Why would something be marked as unused? The
boot area is not a filesystem, it is a single linear blob (or two if
boot1 is in the same format, but mostly irrelevant).

> I thought about manually creating an mtd device that fullfils these
> needs (in case we
> encounter the "allwinner,nandn-boot" property on a nand@X node), but I'm
> not sure
> this is the right approach.

Would work, if you also can make sure the two do not stomp on each
others. Should be divided by NAND block range.

Regards
Henrik

2014-01-29 15:12:25

by Michal Suchanek

[permalink] [raw]
Subject: Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support

On 13 January 2014 10:02, boris brezillon <[email protected]> wrote:
> Hi Henrik,
>
>
> On 11/01/2014 22:11, Henrik Nordström wrote:
>>
>> <bbrezillon> thanks for pointing out your documents
>> <bbrezillon> I'm trying to get the NAND driver with HW ECC (and HW RND)
>> without using DMA at all
>>
>> I tried many things but did not quite get the ECC reading command to
>> return meaningful resuts. But should work somehow.
>>
>> <bbrezillon> do you have any other information I could use to do this ?
>>
>> Not really. There is no known code to look at using the nand controller
>> without DMA. All allwinner code uses DMA even the boot ROM (BROM).
>>
>> <bbrezillon> For example, I wonder why there are 2 RAM sectors (the
>> driver I found only make use of RAM0)
>>
>> I think it's used during DMA to fetch next sector while the previous one
>> is transferred by DMA. But not sure.
>
>
> Some feedback on my tests:
>
> - I managed to get HW ECC working without any DMA transfer (using CMD = 01):
> * I only tested the sequential ECC => ECC are stored between 2 data blocks
> (1024 byte)
> * Non sequential ECC should work if I store ECC bytes in the OOB area too
> (I'll just have
> to send RANDOM_OUT commands to move to the OOB area before sending the
> ECC
> cmd and another RANDOM_OUT to go back to the DATA area)
>
> - The HW RND (randomizer) works too, I'll just have to figure out how this
> could be
> mainlined:
> * using a simple dt property to tell the controller it should enable the
> randomizer
> * provide an interface (like the nand_ecc_ctrl struct ) for other to add
> their own
> randomizer implementation (this was requested:
> https://lkml.org/lkml/2013/12/13/154)
>
>
> The most complicated part is the boot0 partition.
>
> Tell me if I'm wrong, but here's what I understood from your work (and yuq's
> work too):
>
> boot 0 part properties:
> - uses sequential ECC
> - uses 1024 bytes ECC blocks
> - boot0 code is stored only on the first ECC block of each page (1024 bytes
> + ecc bytes)
> - boot0 code is stored on the first 64 pages of the first block
> - boot0 uses HW randomizer with a specific rnd seed (0x4a80)
>
> It's not that complicated to read/write from/to boot0, but it's a bit more
> to mainline this
> implementation:
> - the nand chip must use the same ECC algorithm and ECC layout on the whole
> flash
> (no partition specific config available)
> - you cannot mark some part of pages as unused => the nand driver will write
> the
> whole page, not just the first ECC block (1024 bytes)
>
> I thought about manually creating an mtd device that fullfils these needs
> (in case we
> encounter the "allwinner,nandn-boot" property on a nand@X node), but I'm not
> sure
> this is the right approach.
>
> Any ideas ?

Maybe if varying parameters on one MTD device is not acceptable you
could export parts of the flash as different MTD devices each with its
own parameters. Since the boot0 part is fixed size this should not
really be an issue. Existing MTD drivers that share hardware with
other devices exist - eg. the MTD driver which exports part of RAM as
MDT device.

I wonder if it would be good idea to make it possible to use the NAND
only for storage without a boot0 area. If this is selected by a DT
parameter as suggested changing the parameter will probably make the
NAND unreadable.

Thanks

Michal

>
>
> Best Regards,
>
> Boris
>
>>
>> Regards
>> Henrik
>>
>
> --
> You received this message because you are subscribed to the Google Groups
> "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/groups/opt_out.

2014-01-29 15:43:20

by Boris BREZILLON

[permalink] [raw]
Subject: Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support

Hello Michal,

On 29/01/2014 16:11, Michal Suchanek wrote:
> On 13 January 2014 10:02, boris brezillon <[email protected]> wrote:
>> Hi Henrik,
>>
>>
>> On 11/01/2014 22:11, Henrik Nordström wrote:
>>> <bbrezillon> thanks for pointing out your documents
>>> <bbrezillon> I'm trying to get the NAND driver with HW ECC (and HW RND)
>>> without using DMA at all
>>>
>>> I tried many things but did not quite get the ECC reading command to
>>> return meaningful resuts. But should work somehow.
>>>
>>> <bbrezillon> do you have any other information I could use to do this ?
>>>
>>> Not really. There is no known code to look at using the nand controller
>>> without DMA. All allwinner code uses DMA even the boot ROM (BROM).
>>>
>>> <bbrezillon> For example, I wonder why there are 2 RAM sectors (the
>>> driver I found only make use of RAM0)
>>>
>>> I think it's used during DMA to fetch next sector while the previous one
>>> is transferred by DMA. But not sure.
>>
>> Some feedback on my tests:
>>
>> - I managed to get HW ECC working without any DMA transfer (using CMD = 01):
>> * I only tested the sequential ECC => ECC are stored between 2 data blocks
>> (1024 byte)
>> * Non sequential ECC should work if I store ECC bytes in the OOB area too
>> (I'll just have
>> to send RANDOM_OUT commands to move to the OOB area before sending the
>> ECC
>> cmd and another RANDOM_OUT to go back to the DATA area)
>>
>> - The HW RND (randomizer) works too, I'll just have to figure out how this
>> could be
>> mainlined:
>> * using a simple dt property to tell the controller it should enable the
>> randomizer
>> * provide an interface (like the nand_ecc_ctrl struct ) for other to add
>> their own
>> randomizer implementation (this was requested:
>> https://lkml.org/lkml/2013/12/13/154)
>>
>>
>> The most complicated part is the boot0 partition.
>>
>> Tell me if I'm wrong, but here's what I understood from your work (and yuq's
>> work too):
>>
>> boot 0 part properties:
>> - uses sequential ECC
>> - uses 1024 bytes ECC blocks
>> - boot0 code is stored only on the first ECC block of each page (1024 bytes
>> + ecc bytes)
>> - boot0 code is stored on the first 64 pages of the first block
>> - boot0 uses HW randomizer with a specific rnd seed (0x4a80)
>>
>> It's not that complicated to read/write from/to boot0, but it's a bit more
>> to mainline this
>> implementation:
>> - the nand chip must use the same ECC algorithm and ECC layout on the whole
>> flash
>> (no partition specific config available)
>> - you cannot mark some part of pages as unused => the nand driver will write
>> the
>> whole page, not just the first ECC block (1024 bytes)
>>
>> I thought about manually creating an mtd device that fullfils these needs
>> (in case we
>> encounter the "allwinner,nandn-boot" property on a nand@X node), but I'm not
>> sure
>> this is the right approach.
>>
>> Any ideas ?
> Maybe if varying parameters on one MTD device is not acceptable you
> could export parts of the flash as different MTD devices each with its
> own parameters. Since the boot0 part is fixed size this should not
> really be an issue. Existing MTD drivers that share hardware with
> other devices exist - eg. the MTD driver which exports part of RAM as
> MDT device.

I considered this option (exposing 2 mtd devices which use the
same nand chip: one for the boot partition and the other one
for the remaining space).
I might give it a try.

For the moment I'm trying to use standard partitions and then
attach one of these partitions as a sunxi-nand-boot-interface.
Something similar to what UBI is doing when attaching to an MTD
device.

This way we can use the NAND as a standard MTD dev and when one
partition is attached as a sunxi-nand-boot-interface you can access
the boot0 partition using a char dev (/dev/snbi0 ?).
The sunxi-nand-boot-interface will provide the appropriate abstraction
to hide the specific boot0 layout...

What do you think ?

>
> I wonder if it would be good idea to make it possible to use the NAND
> only for storage without a boot0 area. If this is selected by a DT
> parameter as suggested changing the parameter will probably make the
> NAND unreadable.
Actually the NAND controller supports up to 8 chips. I guess only the
first one can be used as a boot device.
Reserving space for the boot partition on all of these chips is kind of
useless.
Moreover, we can't tell if the user wants to boot from the NAND or
from another storage (MMC for example), in this case we don't need
to expose the boot0 partition.


Best Regards,

Boris
>
> Thanks
>
> Michal
>
>>
>> Best Regards,
>>
>> Boris
>>
>>> Regards
>>> Henrik
>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "linux-sunxi" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected].
>> For more options, visit https://groups.google.com/groups/opt_out.

2014-01-29 16:09:07

by Michal Suchanek

[permalink] [raw]
Subject: Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support

On 29 January 2014 16:43, boris brezillon dev <[email protected]> wrote:
> Hello Michal,
>
>
> On 29/01/2014 16:11, Michal Suchanek wrote:
>>
>> On 13 January 2014 10:02, boris brezillon <[email protected]> wrote:
>>>
>>>
>>> boot 0 part properties:
>>> - uses sequential ECC
>>> - uses 1024 bytes ECC blocks
>>> - boot0 code is stored only on the first ECC block of each page (1024
>>> bytes
>>> + ecc bytes)
>>> - boot0 code is stored on the first 64 pages of the first block
>>> - boot0 uses HW randomizer with a specific rnd seed (0x4a80)
>>>
>>> It's not that complicated to read/write from/to boot0, but it's a bit
>>> more
>>> to mainline this
>>> implementation:
>>> - the nand chip must use the same ECC algorithm and ECC layout on the
>>> whole
>>> flash
>>> (no partition specific config available)
>>> - you cannot mark some part of pages as unused => the nand driver will
>>> write
>>> the
>>> whole page, not just the first ECC block (1024 bytes)
>>>
>>> I thought about manually creating an mtd device that fullfils these needs
>>> (in case we
>>> encounter the "allwinner,nandn-boot" property on a nand@X node), but I'm
>>> not
>>> sure
>>> this is the right approach.
>>>
>>> Any ideas ?
>>
>> Maybe if varying parameters on one MTD device is not acceptable you
>> could export parts of the flash as different MTD devices each with its
>> own parameters. Since the boot0 part is fixed size this should not
>> really be an issue. Existing MTD drivers that share hardware with
>> other devices exist - eg. the MTD driver which exports part of RAM as
>> MDT device.
>
>
> I considered this option (exposing 2 mtd devices which use the
> same nand chip: one for the boot partition and the other one
> for the remaining space).
> I might give it a try.
>
> For the moment I'm trying to use standard partitions and then
> attach one of these partitions as a sunxi-nand-boot-interface.
> Something similar to what UBI is doing when attaching to an MTD
> device.
>
> This way we can use the NAND as a standard MTD dev and when one
> partition is attached as a sunxi-nand-boot-interface you can access
> the boot0 partition using a char dev (/dev/snbi0 ?).
> The sunxi-nand-boot-interface will provide the appropriate abstraction
> to hide the specific boot0 layout...
>
> What do you think ?

If it works with MTD, sure.

The problem the two devices avoid is that with uniform parameters
across MTD device the boot0 partition is invalid.

>
>
>>
>> I wonder if it would be good idea to make it possible to use the NAND
>> only for storage without a boot0 area. If this is selected by a DT
>> parameter as suggested changing the parameter will probably make the
>> NAND unreadable.
>
> Actually the NAND controller supports up to 8 chips. I guess only the
> first one can be used as a boot device.
> Reserving space for the boot partition on all of these chips is kind of
> useless.

This actually depends on the BROM.

I did not read the BROM code so I don't know what it does.

> Moreover, we can't tell if the user wants to boot from the NAND or
> from another storage (MMC for example), in this case we don't need
> to expose the boot0 partition.

It's possible to use the NAND only for storage, sure.

However, a NAND on which the boo0 area is reserved would be unreadable
without reserving boot0 area in the driver, right?

The best we can tell is if user specified to reserve the area in the
DT. It might be possible to verify the boot0 area the same way BROM
does when booting from it. This might be nice option when you don't
know what you have on the chip and want to read it but most of the
time you will want to enforce bootable or non-bootable format when
writing the NAND.

Thanks

Michal

2014-01-29 16:55:57

by Boris BREZILLON

[permalink] [raw]
Subject: Re: [linux-sunxi] Re: [RFC PATCH 0/9] mtd: nand: add sunxi NAND Flash Controller support

On 29/01/2014 17:08, Michal Suchanek wrote:
> On 29 January 2014 16:43, boris brezillon dev <[email protected]> wrote:
>> Hello Michal,
>>
>>
>> On 29/01/2014 16:11, Michal Suchanek wrote:
>>> On 13 January 2014 10:02, boris brezillon <[email protected]> wrote:
>>>>
>>>> boot 0 part properties:
>>>> - uses sequential ECC
>>>> - uses 1024 bytes ECC blocks
>>>> - boot0 code is stored only on the first ECC block of each page (1024
>>>> bytes
>>>> + ecc bytes)
>>>> - boot0 code is stored on the first 64 pages of the first block
>>>> - boot0 uses HW randomizer with a specific rnd seed (0x4a80)
>>>>
>>>> It's not that complicated to read/write from/to boot0, but it's a bit
>>>> more
>>>> to mainline this
>>>> implementation:
>>>> - the nand chip must use the same ECC algorithm and ECC layout on the
>>>> whole
>>>> flash
>>>> (no partition specific config available)
>>>> - you cannot mark some part of pages as unused => the nand driver will
>>>> write
>>>> the
>>>> whole page, not just the first ECC block (1024 bytes)
>>>>
>>>> I thought about manually creating an mtd device that fullfils these needs
>>>> (in case we
>>>> encounter the "allwinner,nandn-boot" property on a nand@X node), but I'm
>>>> not
>>>> sure
>>>> this is the right approach.
>>>>
>>>> Any ideas ?
>>> Maybe if varying parameters on one MTD device is not acceptable you
>>> could export parts of the flash as different MTD devices each with its
>>> own parameters. Since the boot0 part is fixed size this should not
>>> really be an issue. Existing MTD drivers that share hardware with
>>> other devices exist - eg. the MTD driver which exports part of RAM as
>>> MDT device.
>>
>> I considered this option (exposing 2 mtd devices which use the
>> same nand chip: one for the boot partition and the other one
>> for the remaining space).
>> I might give it a try.
>>
>> For the moment I'm trying to use standard partitions and then
>> attach one of these partitions as a sunxi-nand-boot-interface.
>> Something similar to what UBI is doing when attaching to an MTD
>> device.
>>
>> This way we can use the NAND as a standard MTD dev and when one
>> partition is attached as a sunxi-nand-boot-interface you can access
>> the boot0 partition using a char dev (/dev/snbi0 ?).
>> The sunxi-nand-boot-interface will provide the appropriate abstraction
>> to hide the specific boot0 layout...
>>
>> What do you think ?
> If it works with MTD, sure.
>
> The problem the two devices avoid is that with uniform parameters
> across MTD device the boot0 partition is invalid.

Using partitions we would still have X char devices (X = number of MTD
partitions). But indeed, we need to provide a way to configure ECC and
randomizer specifically on each partition.

>
>>
>>> I wonder if it would be good idea to make it possible to use the NAND
>>> only for storage without a boot0 area. If this is selected by a DT
>>> parameter as suggested changing the parameter will probably make the
>>> NAND unreadable.
>> Actually the NAND controller supports up to 8 chips. I guess only the
>> first one can be used as a boot device.
>> Reserving space for the boot partition on all of these chips is kind of
>> useless.
> This actually depends on the BROM.
>
> I did not read the BROM code so I don't know what it does.
>
>> Moreover, we can't tell if the user wants to boot from the NAND or
>> from another storage (MMC for example), in this case we don't need
>> to expose the boot0 partition.
> It's possible to use the NAND only for storage, sure.
>
> However, a NAND on which the boo0 area is reserved would be unreadable
> without reserving boot0 area in the driver, right?

Not exactly: the NAND would still be readable but the blocks reserved for
boot0 (boot0 partition) won't be read correctly (ECC layout differs).
If you define a partition boot0 with the appropriate size and never access
it, the other partitions defined on the same NAND chip will work perfectly.

To solve this ECC config issue we might need to provide a way to configure
the ECC engine per partition and not on the whole NAND chip.

Moreover, IRC, BROM only uses 1K on each page of a given block to store
boot0 code and data.

And eventually the randomizer config (random seed) is specific for this
partition too.
Note that the current driver does not support randomization at all.
I'm still working on providing a generic framework to support HW and SW
randomization (in the same way HW and SW ECC are supported).

For all the reasons exposed above we need a specific handling for the boot0
partition. But I'd like to keep the NAND Flash controller driver as
simple and
as generic as possible.
I'd prefer adding a new driver for the sunxi boot0 partition handling than
adding this code in the sunxi_nand driver.
Atfer all, this boot partition has nothing to do with NAND, this is just
a specific
format for the sunxi BROM to load code from NAND to RAM, right ?

>
> The best we can tell is if user specified to reserve the area in the
> DT. It might be possible to verify the boot0 area the same way BROM
> does when booting from it. This might be nice option when you don't
> know what you have on the chip and want to read it but most of the
> time you will want to enforce bootable or non-bootable format when
> writing the NAND.
>
> Thanks
>
> Michal