From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1244 invoked by alias); 9 Oct 2009 08:27:14 -0000 Received: (qmail 1232 invoked by uid 22791); 9 Oct 2009 08:27:11 -0000 X-SWARE-Spam-Status: No, hits=-2.4 required=5.0 tests=AWL,BAYES_00,SPF_PASS X-Spam-Check-By: sourceware.org Received: from hagrid.ecoscentric.com (HELO mail.ecoscentric.com) (212.13.207.197) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 09 Oct 2009 08:27:05 +0000 Received: from localhost (hagrid.ecoscentric.com [127.0.0.1]) by mail.ecoscentric.com (Postfix) with ESMTP id 187E12F78011 for ; Fri, 9 Oct 2009 09:27:03 +0100 (BST) Received: from mail.ecoscentric.com ([127.0.0.1]) by localhost (hagrid.ecoscentric.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id CFrfN50jjOrt; Fri, 9 Oct 2009 09:27:00 +0100 (BST) Received: from [172.20.45.24] (callisto.impropriety.org.uk [90.155.95.198]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) (Authenticated sender: wry@ecoscentric.com) by mail.ecoscentric.com (Postfix) with ESMTP id E8AAF2F78014 for ; Fri, 9 Oct 2009 09:26:59 +0100 (BST) Message-ID: <4ACEF3D1.1090609@ecoscentric.com> Date: Fri, 09 Oct 2009 08:27:00 -0000 From: Ross Younger User-Agent: Mozilla-Thunderbird 2.0.0.22 (X11/20090707) MIME-Version: 1.0 To: ecos-devel@ecos.sourceware.org Subject: Re: NAND technical review References: <4AC6218C.20407@jifvik.org> <4ACB4B58.2040804@ecoscentric.com> <4ACC0722.9020601@jifvik.org> <4ACDF868.7050706@ecoscentric.com> In-Reply-To: <4ACDF868.7050706@ecoscentric.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact ecos-devel-help@ecos.sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: ecos-devel-owner@ecos.sourceware.org X-SW-Source: 2009-10/txt/msg00010.txt.bz2 (resend, having fallen foul of sourceware's spamtrap) Jonathan Larmour wrote: > > Good ONFI support should be the highest priority as that's the way > > everything is likely to go, although we do need the others too. Agreed. As the Samsung K9 is nearly ONFI already, adapting my driver is likely to be very quick; all other things being equal, I would just do this as and when there was a demand (and suitable hardware on my desk). > > Personally I would expect use as an interrupt line as the main role of > > the ready line. IMLE the overhead of sleeping and context switching is quite significant. In the drivers I've written to date, where there is a possiblity to use the ready line as an interrupt source I have provided this as an option in CDL. >> >> Theoretically, multiple chips could be >> >> hooked up in parallel to give something that looks like a 16 or 32-bit >> >> "wide" chip, but I have never encountered this in the NAND world [...] > > > > Have you found on-chip (SoC's) NAND controllers permit such a > > configuration? If not, I would assume that it's not an expected hardware > > configuration. Not on the small number of controllers I have looked at in detail. > > What problems would you see, if any, using your layer with the same > > controller and two completely different chips, of different geometry? > > Can you still have a common codebase with other (different) platforms? I don't see any issue: controllers don't IME care about the chip geometry, they just take care of the electrical side, and some calculate ECC in passing. For that matter I don't see an issue with a single controller on one board driving two chips of different geometries at once. > > Is anyone aware of NAND chips with different sized blocks? Analogous to > > bootblocks with NOR (I haven't, but others will undoubtedly have seen > > more parts than I). Although it's possible that even if they're not > > around or common now, they may be in future. I don't think there's a way to express such a chip in the ONFI chip interrogation logic, and such a chip would I think comprehensively break the Linux MTD layer into the bargain. > > Unfortunately from what I > > can tell neither layer would be able to support that directly, although > > I think it may be possible for the eCosCentric layer to allow the driver > > to pretend there is a different NAND chip. Do you think so too? Two chip drivers exposing different geometries but with essentially the same underlying access functions would probably do the trick. There would have to be careful address translation or partitioning between the two, and a single mutex protecting both devices in the chip driver layer, but I think it'd be a goer. >> >> 2. Application interface ----------------------------------------------- >> >> The basic operations required are reading a page, programming a page and >> >> erasing a block, and both layers provide these. > > > > However I believe Rutger's supports partial page writes (use of > > 'column'), whereas I don't believe eCosCentric's does. As covered in the other subthread, is this actually useful, and how to sort out the ECC? >> >> Rutger's layer has an extra hook in >> >> place where an application may explicitly request the use of cached reading >> >> and writing where the device supports this. > > > > That seems like a useful potential optimisation, exploiting underlying > > capabilities. Any reason you didn't implement this? > > > > I could also believe that NAND controllers can also optimise by doing > > multiple block reads, where this hint would also prove useful. Not particularly. Looking at cache-assisted read and program operations for multi-page operations is sitting on my TODO list, languishing :-). I would note in passing that YAFFS doesn't make use of these, preferring only to read and write single pages fully synchronously; this might be a worthwhile enhancement in dealing with larger files, though YAFFS's own internal NAND interface is strictly page-oriented at the moment and so this would require a bit of brain surgery - something best done in conjunction with Charles Manning, I think. > > Does your implementation _require_ a BBT in its current implementation? > > For simpler NAND usage, it may be overkill e.g. an application where the > > number of rewrites is very small, so the factory bad markers may be > > considered sufficient. I suppose it would be possible to provide a CDL option to switch the persistent BBT off if you really wanted to. Caution is required, though: after you have ever written to the chip, it can be impossible to distinguish a genuine factory-bad marker from application data in the OOB area that happens to resemble it. This can be worked around with very careful management of what the application puts into the OOB or by tweaking the OOB layout to simply avoid ever writing to the relevant byte(s). >> >> (a) Partitions > > [snip] >> >> R's interface does not have such a facility. It appears that, in the >> >> event >> >> that the flash is shared between two or more logical regions, it's up to >> >> higher-level code to be configured with the correct block ranges to use. > > > > In yours, the block ranges must be configured in CDL. Is there much > > difference? I can see an advantage in writing platform-independent test > > programs. But in applications within products possibly less so. I provide CDL for manual config, but have included a partition layout initialisation hook. If there was an on-chip partition table, all that's needed would be some code to go into that hook to interrogate it and translate to my layer's in-memory layout. This is admittedly not well documented, but hinted at by "Planning a port" (http://www.ecoscentric.com/ecospro/doc.cgi/html/ecospro-ref/nand-devs-writing.html) and should be readily apparent on examining code for existing chip drivers. > > Especially since the flash geometry, including size, can be > > programmatically queried. Flash geometry can only be programmatically queried up to a point in non-ONFI chips. Look at the k9_devinit function in k9fxx08x08.inl: while the ReadID response of Samsung chips encodes the page, block and spare area sizes, it doesn't tell you about the chip block count or overall size - you have to know based on the device identifier byte. Linux, for example, has a big table of these in drivers/mtd/nand/nand_ids.c. > > If there was to be a single firmware supporting multiple board > > revisions/configurations (as can definitely happen), which could include > > different sizes of NAND, I think R's implementation would be able to > > adapt better than E's, as the high-level program can divide up the sizes > > based on what it sees. I see no reason why E's wouldn't adapt just as well, given suitably written driver(s) and init hooks. >> >> (b) Dynamic memory allocation >> >> >> >> R's layer mandates the provision of malloc and free, or compatible >> >> functions. These must be provided to the cyg_nand_init() call. > > > > That's unfortunate - that limits its use in smaller boot loaders - a key > > application. > > >> >> E's doesn't; instead it declares a small number of static buffers. > > > > I assume everything is keyed off CYGNUM_NAND_PAGEBUFFER, and there are > > no other variables. Again I'm thinking of the scenario of single > > firmware - different board revs. Can you confirm? Chip drivers are expected to require in CDL that CYGNUM_NAND_PAGEBUFFER be large enough, and to set up a static byte array for their Bad Block Table. Efficiently supporting two differently-sized chips on a single board - I mean only allocating enough static space for the largest known BBT - would not be difficult. > > OTOH your implementation doesn't supports program verifies in the higher > > level anyway (I note your code comment about it being unnecessary as the > > device should report a successful program - your faith in correct > > hardware behaviour is considerable :-) ). Verifying after programming is also on my todo list :-) >> >> If multiple chips of different types are present in a build, E's model >> >> potentially duplicates code (though this could be worked around; also, an >> >> ONFI driver ought to be written). > > > > Worked around in a way likely to increase single-device footprint > > though. Shame about the lack of OFNI driver, although I guess the parts > > still aren't widely used which can't help. The Samsung K9 is close at > > least. As I said, when one lands on my desk I'll gladly get writing :-) > > In fact, because of the requirement for the > > drivers to call CYG_NAND_FUNS, it doesn't seem difficult at all to be > > backwardly compatible. Am I right? Nevertheless, it would be unfortunate > > to have an API which already needs its low level driver interface > > updating to a rev 2. Adding hardware ECC support and making the driver interface backwards-compatible turned out to break layering, so I chose to change the interface. It's a relatively straightforward change in that I have broken up page read and program operations into three: initialise, to read/write a stride of data (length chosen by the NAND layer to mesh with whatever ECC length is provided by the controller), and finalise. The flow inside my NAND layer for programming a page becomes: * Call chip driver to initialise the write (we expect it to send the command and address) * For each ECC-sized stride of data: ** If hardware ECC, call the ECC driver to tell it we're about to start a stride ** Call chip driver to write a stride of data ** If hardware ECC, call the ECC driver to get the ECC for the stride now completed and stash it away * If software ECC, compute it for the page * Finalise the spare layout using the ECC wherever it came from * Call chip driver to finalise the write, passing the final spare layout (we expect it to write the spare area and send the program-confirm command). I am not yet finished this work, but will update all my existing drivers when it is done. In a way, the drawn-out nature of this process has provided extra time for my state of the art to evolve ;-) > > Incidentally I note Rutger has a "Samsung" ECC implementation, whereas > > you support Samsung K9 chips, but use the normal ECC algorithm. Did > > Samsung change their practice? The "Samsung" ECC implementation has nothing to do with the underlying chip; it's just an algorithm whose details they published, I think in conjunction with some of the higher-level NAND-based products they ship which feature an FTL (USB sticks, SD cards, etc). There is in general no requirement to use any particular ECC algorithm with any particular chip; all the spec sheets tend to say is "use ECC". If I have understood the code correctly, Rutger provides two ECC algorithms: * nand_ecc.c implements the "standard" Linux MTD algorithm (indeed the code is lifted, with acknowledgement). This is an algorithm created by Toshiba, with a 256 byte data block and 22 bit ECC and the layer uses it by default where no other algorithm is provided. * io_nand_ecc_samsung.c provides a Samsung algorithm of the same parameters, used by the BlackFin board driver. My layer only provides the Linux MTD algorithm at the moment (also by lifting the code with acknowledgement). In passing I note that the 22 bits for 256 bytes algorithm is a bit wasteful of space as it's relative simple to add an extra pair of row-parity bits and have 24 bits of ECC for 512 bytes of data. If you were happy that the chip wouldn't suffer too many single-bit dropouts at once, and you decided you didn't want to worry about subpage support you could go for 26/1024 or 28/2048. Would you believe it, writing 24/512 (and perhaps 26/1024 and 28/2048) algorithms is also on my todo list ... > > Your documentation does appear very thorough and well-structured > > (although the Samsung and EA LPC2468 docs really should be broken out > > into their own packages). Rutger's does also seem fine though so I don't > > think there's a strong difference either way. The Samsung K9 is in its own (single-chapter) docs package as of a few weeks ago, and the board-specific bits for the EA LPC2468 have been moved into that HAL. > > [synth target] > > Bad block injection sounds like an extremely useful feature. I infer > > from the latter that we're now talking about many hours of testing? We are. We have run our YAFFS severe stress testing with bad block injection for over a week at a time. >> >> * Expansion of the device interface to better allow efficient hardware >> >> ECC support (in progress) > > > > Rough ETA? All I'm interested in knowing is whether the device interface > > changes for this are likely to be concluded within the timeframe of this > > discussion. It's part and parcel of the customer port that I'm currently working on, so "real soon now" - top of my priority list apart from this discussion ;-) With a following wind I would hope to be able to finish it up, synch my changes with the anoncvs side and push out maybe a week or so after I'm back from holiday. >> >> * Partition addressing: make addressing relative to the start of the >> >> partition, once and for all > > > > That's quite a major API change, which seems problematic to me. This is why it has to be worked out sooner rather than later, and is currently very close to the top of my todo list ;-). Bart in particular has been encouraging me to make this change for a while. >> >> * Part-page read support (would provide a big speed-up to parts of YAFFS2 >> >> inbandTags mode as needed by small-page devices like that on the >> >> STM3210E) > > > > Do you foresee this happening within any particular timeframe? Do you > > expect the changes to be backwardly compatible? No timescale as yet as it's relatively far down my todo list. I think support would require an addition to the device interface to support reading from a column address, not a break - so existing drivers would continue working. But I need to think about this a bit more when I get there, as it may require work on the YAFFS side, and it tickles the sleeping dragon that is support for ECC on part-pages. Cheers, Ross -- Embedded Software Engineer, eCosCentric Limited. Barnwell House, Barnwell Drive, Cambridge CB5 8UU, UK. Registered in England no. 4422071. www.ecoscentric.com