[flashrom] [PATCH] Add support for SFDP (JESD216).
Carl-Daniel Hailfinger
c-d.hailfinger.devel.2006 at gmx.net
Wed Feb 8 01:17:04 CET 2012
Am 07.02.2012 23:23 schrieb Stefan Tauner:
> On Wed, 01 Feb 2012 00:03:34 +0100
> Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net> wrote:
>
>> Am 31.01.2012 06:59 schrieb Stefan Tauner:
>>> […]
>>> todo:
>>> - handle programmers which have a problem with the dummy bytes needed
>> AMD SB[678]x0 SPI has a way to specify sending one dummy byte between
>> write and read, IIRC it is called DropOneClkOnRead or somthing like
>> that. Quite a few other SPI masters have the one-dummy-byte
>> functionality as well. This needs to be implemented in a generic way (I
>> have a totally bitrotted patch for it), but it should not hold back this
>> patch.
> what about simulating the dummy byte by reading one additional byte in
> the beginning instead of writing one? due to SPI's underlying principle
> of shifting bits in and out of master and slave simultaneously this
> should give us the same effect, but eases working around programmer
> limitations.
Right. The direction is a don't-care thing for dummy bytes. Maybe just
add a FIXME comment that we should handle dummy bytes explicitly later.
>>> […]
>>> +typedef int (erasefunc_t)(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
>> I believe that typedef to be pretty unreadable, but I see that avoiding
>> the typedef would probably be even worse.
> yes :) see http://patchwork.coreboot.org/patch/3492/ ... *shiver*
Now that you point me to the alternative, I have to say that I think the
typedef is less readable (at least the typedef definition itself).
>>> […]
>>> + .read = spi_chip_read,
>>> + .page_size = 256, /* ? */
>> Argh, page_size comes to bite us again. Did I already send my "kill most
>> uses of page_size" patch?
> afaics no
Yes, it's still in beta. But I can send it anyway so people can review
it mercilessly.
>>> + /* FIXME: some vendor extensions define this */
>>> + .voltage = {},
>>> + /* Everything below will be set by the probing function. */
>>> + .write = NULL,
>>> + .total_size = 0,
>>> + .feature_bits = 0,
>>> + .block_erasers = {},
>>> + },
>>>
>>> {
>>> .vendor = "Unknown",
>>> diff --git a/flashchips.h b/flashchips.h
>>> index 03efb86..1f2a8ca 100644
>>> --- a/flashchips.h
>>> +++ b/flashchips.h
>>> @@ -36,6 +36,7 @@
>>>
>>> #define GENERIC_MANUF_ID 0xffff /* Check if there is a vendor ID */
>>> #define GENERIC_DEVICE_ID 0xffff /* Only match the vendor ID */
>>> +#define SFDP_DEVICE_ID 0xfffe
>> Side note: Should we move PROGMANUF_ID and its companion from the bottom
>> of the file to this location to have generic match IDs in one place?
> yes and i took the opportunity to do that right away, chunks now looks
> like this (i also changed the hex characters to upper case like in the
> rest of the file):
>
> -#define GENERIC_MANUF_ID 0xffff /* Check if there is a vendor ID */
> -#define GENERIC_DEVICE_ID 0xffff /* Only match the vendor ID */
> -#define SFDP_DEVICE_ID 0xfffe
> +#define GENERIC_MANUF_ID 0xFFFF /* Check if there is a vendor ID */
> +#define GENERIC_DEVICE_ID 0xFFFF /* Only match the vendor ID */
> +#define SFDP_DEVICE_ID 0xFFFE
> +#define PROGMANUF_ID 0xFFFE /* dummy ID for opaque chips behind a programmer */
> +#define PROGDEV_ID 0x01 /* dummy ID for opaque chips behind a programmer */
Thanks!
>>>
>>> #define ALLIANCE_ID 0x52 /* Alliance Semiconductor */
>>> #define ALLIANCE_AS29F002B 0x34
>>> diff --git a/flashrom.c b/flashrom.c
>>> index ee68344..84fb3fc 100644
>>> --- a/flashrom.c
>>> +++ b/flashrom.c
>>>
>>> […]
>>> +/* FIXME: eventually something similar like this but more generic should be
>>> + * available to split up spi commands. use that then instead */
>>> +static int spi_sfdp(struct flashctx *flash, uint32_t address, uint8_t *buf, int len)
>>> +{
>>> + /* FIXME: this is wrong. */
>>> + int maxstep = 8;
>> Yes, maxstep should be a programmer-specific setting. However, with our
>> current infrastructure there is no way to fix this easily.
>>
>>
>>> + int ret = 0;
>>> + while (len > 0) {
>>> + int step = min(len, maxstep);
>>> + ret = spi_sfdp_wrapper(flash, address, buf, step);
>>> + if (ret)
>> Actually, there is probably a way to determine optimal size for those
>> SFDP requests: Check if ret indicates a "command too long" error and
>> reduce maxstep by one in that case, then retry. Such code is not exactly
>> pretty and I'm not sure if all SPI masters have such a differentiated
>> error code reporting.
> i have made this table from a code review:
> https://docs.google.com/spreadsheet/ccc?key=0Ag1Kfbw63vWfdGFYWk5qSG4xYXhwQktDUzdmNmc0WVE&hl=en_US#gid=0
Thanks.
> the only SPI programmer that has a small upper bound on the number of
> bytes to send/receive and that does not report SPI_INVALID_LENGTH is
> dediprog. it has the checks in place but just returns 1, so this is
> easily fixable.
>
> The code would probably be quite complex for little gain in speed
> (if at all), so i would say that just using a small packet size
> (readcnt = 8) is the best solution until we support the more
> restrictive programmers/for now.
Hm OK. Not really happy, but we can always do this with a followup
patch. Just add a FIXME comment.
>>> +{
>>> + uint32_t total_size = f->total_size * 1024;
>>> + int i;
>>> + erasefunc_t *erasefn = spi_get_erasefn_from_opcode(opcode);
>>> + if (erasefn == NULL)
>>> + return 1;
>>> + for (i = 0; i < NUM_ERASEFUNCTIONS; i++) {
>>> + struct block_eraser *eraser = &f->block_erasers[i];
>>> + if (eraser->eraseblocks[0].size != 0 || !eraser->block_erase)
>>> + continue;
>>> + eraser->block_erase = erasefn;
>>> + eraser->eraseblocks[0].size = bsize;
>>> + eraser->eraseblocks[0].count = total_size/bsize;
>>> + msg_cdbg2(" Block eraser %d: %d x %d B with opcode "
>>> + "0x%02x\n", i, total_size/bsize, bsize,
>>> + opcode);
>>> + return 0;
>>> + }
>>> + msg_cinfo("%s: Not enough space to store another eraser (i=%d)."
>> msg_cerr?
> that's the question :)
> my rationale is: if there are already MAX erasers, we can continue
> without a problem but it would be nice to increase the limit if someone
> reports it. msg_cinfo will guarantee that normal users will see this,
> so no need for msg_cerr.
> there are good arguments for msg_cerr too... if we move this function
> to spi25.c i'd vote for err, if it stays in sfdp.c i dont really care.
msg_cinfo it is, then.
Regards,
Carl-Daniel
--
http://www.hailfinger.org/
More information about the flashrom
mailing list