[flashrom] [PATCH 0/6] Initial status register and access protection infrastructure

Stefan Tauner stefan.tauner at alumni.tuwien.ac.at
Fri Jul 29 20:37:49 CEST 2016


On Wed,  6 Jul 2016 01:57:59 +0530
Hatim Kanchwala <hatim at hatimak.me> wrote:

> Following patches add new infrastructure for status register(s) and
> locking/unlocking of access protection. Detailed points for
> explaining each patch are included within them. 
> 
> Some general thoughts -
> - The code has a lot TODOs and FIXMEs (most of which I have addressed
> to myself). They are short-term targets and represent the
> work-in-progress nature of the patches. Future revisions will resolve
> them.
> - There are a lot of comments. Eventually much of that will be
> relocated to documentation and wiki, so comments in future revisions
> will shrink.

I don't see a need to do so. Most of what I have seen so far belongs to
the code and not the wiki. Maybe the howto on adding a flash chip
should be expanded in the wiki though... when this patch set is
completed.

> - Some CLI code is borrowed from the ChromiumOS fork
> (https://chromium.googlesource.com/chromiumos/third_party/flashrom/).
> IMO, the exact words to use for the options is subjective.

Let's postpone the CLI discussion altogether. My stance on this in
general is that we might not need/want to support all features in the
"classic" CLI.

> - The names for struct status_register and struct wp defines (in
> statusreg_layouts.c and writeprotect_layouts.c respectively) are not
> very creative and tend to be long. I couldn't come up with a generic
> scheme that captures most of the information regarding it. You are
> welcome to offer creative suggestions ;)
> 
> Further work -
> - Read and write "configuration" registers (a lot of Spansion chips
> have those)
> - Add tested/untested status for new infrastructure similar to what
> we have for chips (like TEST_PREW, etc.)
>   - write protection modes
>   - protection ranges

Updating the status bits is already a massive time sink I do not intend
to dig even deeper. However, making it more obvious to developers which
chips need further work (similar to util/list_yet_unsupported_chips.sh)
might be useful. This can even be in the form of -L or -z output,
however it should only indicate if an implementation is available and
gather this information implicitly from pointers etc. without any
dedicated TESTED_* flags. That way maintenance costs are minimal.

> - Access protection for non-SPI chips (pointed to by Stefan over IRC)

We definitely want at least a proof of concept that includes support
for that before we finish the general API of SRs and WPs.

> - Reuse layouts for locking/unlocking (pointed to by Stafan and David
> over IRC)

I deem this a CLI aspect.

> - Handling WPS bit (a couple of GigaDevice chips have this)
> - Exotic chips (mostly Atmel, now Adesto, chips fall under this
> category)

Adding support for a AT45DB chip might be useful to see how generic the
new API is (or need to be). Their wicked configurations helped me in
the past to iron out some completely unrelated bugs. I have not checked
if they support any WP scheme though.


Now to the patches themselves... this is obviously no in-depth review.
Too many superficial things came up and need to be sorted out/discussed
first.

 - Don't use char for bytes or integral/countable types like in char
   pos_bit(...)

 - Don't use C99 loop variable declarations because this leads to
   compile errors with old compilers. The alternative is to use -std=c99
   but we are not ready to do that yet.

 - static struct range ranges[LEN_RANGES] in writeprotect.c

   Doesn't this explode if multiple chip definitions are matched in
   probes? In any case you should definitely not return pointers to
   local variables even if they are static. This is very bad API design
   because it is not obvious to the caller that the data pointed to
   might be changed outside of its control (cf. strtok and others that
   used to use an internal static buffer as well but have been
   superseded by re-entrant variants)

 - Initially I was skeptical about the use of pointers to pre-defined
   structures for the SR and WP definitions. I proposed that myself but
   only because the alternative shown in the first PoC seemed to be even
   worse. Looking at the code I felt that it it might disperse the chip
   definitions too much. 
   I have then played a bit with your code and compared the binary
   sizes of 0.9.9, your patches and my "fix" on top. I replaced the
   pointer to the struct status_register in struct flashchip with
   direct struct instances. These are the results:

	0.9.9
	   text	   data	    bss	    dec	    hex	filename
	 517381	   2268	  11712	 531361	  81ba1	flashrom

	hatim:
	   text	   data	    bss	    dec	    hex	filename
	 554373	  11228	  12256	 577857	  8d141	flashrom

	stefanct:
	   text	   data	    bss	    dec	    hex	filename
	 637037	   6812	  12256	 656105	  a02e9	flashrom

   Your implementation adds about 40kB while the direct instantiation
   in my try adds almost 120kB. However, this is a maximum because the
   space for all structs is already pre-allocated and "initialized" in
   the image whereas for your implementation further structs would need
   to be added and only space for the pointers are reserved.
   Additionally, your data section would add to run-time memory usage.

   With that in mind I think technically it does not make much sense to
   separate the definitions. However, this is only one aspect. One
   other is to provide means to share information. We naturally do this
   by sharing function pointers and there it has been a huge success
   because it allows us to easily spot and exploit similarities between
   chip families. So the separation itself is probably a good thing and
   I think you went into the right direction with it.

   But maybe we can improve on the space requirements of the structs
   themselves because they are really huge in comparison to the
   remaining data in struct flashchip. For example:
   enum status_register_bit layout[MAX_STATUS_REGISTERS + 1][8]
   would cost us 8*4*sizeof(int) bytes per chip/status register
   definitoin with most compilers, i.e. 50 kB for 400 SR definitions and
   32-bit integers.
   I tend to ignore this mostly because that's not that much for
   ordinary systems but e.g. WLAN routers are still stuck with a few MB
   of flash and there these 50 kB could be spent better. However, since
   we share these definitions in your implementation a lot it should be
   way less than these 50 kB... but if you can think of an approach
   that uses less memory without making the code much more complicated
   I am all for it. Maybe we could use some feature_bits to indicate
   the number of SRs of the respective chip and can get rid of the +1
   at least?

 - The function prototypes you added to chipdrivers.h should be moved
   to the respective header files.

 - Some of the _generic functions in writeprotect are not really that
   generic. They almost only deal with SPI-specific behavior and should
   neither be named so generically and possibly not even reside in that
   module but spi25_statusreg.c instead. Please try to better abstract
   the generic WP API (as used by the function pointers) from the
   SPI-specific implementations.
   BTW we might get away without any print and print_wp_mode function
   pointers because they should simply print the generic
   representation, no? So spi_prettyprint_status_register_generic for
   example might actually be an actual generic function to be moved to
   a more general file (it currently resides in spi25_statusreg.c).

 - Please comment:
   static char const *bit_string[3][32]
   uint8_t convention = 1, multiple = 0

 - Please exploit and refine our dummy programmer to test the status
   register and OTP implementations of at least some variations.
   Especially simulating the latter makes sense in regression testing
   for obvious reasons :)

 - Many of above generic statements apply to OTP as well, e.g.
   the print_status pointer might be superfluous.

 - What about OTP in non-SPI chips? Have you researched that yet? I
   can't remember seeing that anywhere but in new chip generations I
   would not be surprised if there is support for it.

Don't despair due to the amount of criticism you might perceive. In
general I think you are doing a very good job! I am fully aware that the
goal of implementing all of this in a generic way is not easy but it
is necessary to make it maintainable in the future. Thanks for your
work!

Hope that helps a bit and please let me know if anything is unclear. I
also might have not grasp everything and might be wrong on some points.
Don't hesitate to correct me in that case :)
-- 
Kind regards/Mit freundlichen Grüßen, Stefan Tauner




More information about the flashrom mailing list