Hi Mark,
allow me to explain. You may want to run away screaming and I can't blame you.
page_size is a historical concept in flashrom created when flashrom was an ad-hoc collection of flashing routines for maybe 5 chips. It had a number of different meanings depending on the chip with no clear rules whatsoever. We even abused it for erase block sizes and block locking. It doesn't help that datasheets have verying definitions of the meaning of page size as well.
A flash chip has certain write/erase/read properties, and those differ between NAND and NOR flash. Right now flashrom only supports NOR flash with certain characteristics (power-of-two sizes for min write size / max write size / chip size). The growing pains start with Atmel AT45* chips which are different.
Properties of a flash chip: - Total size (Must be a multiple of 1024 bytes right now, easily fixable.) - Erase block sizes (Arbitrary sizes and multiple erase methods are supported for that, no need to change anything.) - Addressing -- Address size (3-byte vs. 4-byte addresses for SPI flash. Patches exist, have to be reviewed.) -- Address space contiguousness (Does the address space have holes? Are holes present in the read result if someone does a read/write from address A to B with an address space hole in the middle?) -- Address granularity (Can individual bytes be addressed directly or is there a need for sub-addresses like byte selection for old 16-bit word parallel flash?) - Reading -- Maximum read size -- Minimum read size (Can individual bytes be read from the chip like for most NOR flash?) - Writing (Multiple write methods, characteristics below are per-method.) -- Maximum write size in one meta-command (Meta-command is a single command for unrelated write commands or group of related write commands for stuff like AAI with a begin and end command.) -- Maximum (or fixed) write size in one sub-command (Sub-command is a single command for unrelated write commands or a single command for stuff like AAI.) -- Minimum write size (Minimum number of bits/bytes to be written so that no undefined results happen.) -- Write wraparound (Whether writes starting in the middle of a "page" wrap around to the start of the page, this is avoided in flashrom code and thus not relevant here.) - Block locking (Not directly relevant to this discussion except that we abused page_size for that in the past.) - Command set (Not relevant except for commands needed for above properties.) - Buses (Not relevant here.) - Voltage (Not relevant here.) - Timing (Not relevant here.)
At various times during flashrom development, page_size has been used for pretty much every single item listed above. Some strange uses remain.
Let me illustrate the properties above with a few sample chips:
ST/Numonyx/Micron M25P32: (no surprises) - Total size: 4096 kByte - Erase block sizes: 64 kByte for command 0xd8, 4 MByte for command 0xc7 - Addressing -- Address size: 3-Byte -- Address space contiguousness: No holes -- Address granularity: Direct Byte access - Reading -- Minimum read size: 1 Byte -- Maximum read size: unlimited - Writing: Only one write method: Page write -- Maximum write size in one meta-command: 256 Bytes -- Maximum (or fixed) write size in one sub-command: 256 Bytes -- Minimum write size: 1 Byte
Micron N25Q256: (4-byte addresses) - Total size: 32 MByte - Erase block sizes: 4 kByte for command 0x20, 64 kByte for command 0xd8, 32 MByte for command 0xc7 - Addressing -- Address size: 3-byte with Extended Address register for upper bit or 4-byte, switchable with Flag Status Register and/or command set -- Address space contiguousness: No holes -- Address granularity: Direct byte access - Reading -- Minimum read size: 1 byte -- Maximum read size: unlimited (unless non-default wrap mode is active) - Writing: -- Maximum write size in one meta-command: 256 Bytes -- Maximum (or fixed) write size in one sub-command: 256 Bytes -- Minimum write size: 1 Byte
Atmel AT45DB041D (256-byte page mode): - Total size: 512 kByte - Erase block sizes: 256 Byte for command 0x81, 2 kByte for command 0x50, 2/64 kByte for command 0x7c (not all regions erasable), 512 kByte for command 0xc794809a - Addressing -- Address size: 3-byte -- Address space contiguousness: No holes -- Address granularity: Direct byte access (other options exist) - Reading -- Minimum read size: 1 Byte -- Maximum read size: unlimited - Writing: -- Maximum write size in one meta-command: 256 Bytes -- Maximum (or fixed) write size in one sub-command: 256 Bytes -- Minimum write size: 256 Bytes (unusual for other SPI chips)
Atmel AT45DB041D (264-byte page mode): - Total size: 528 kByte - Erase block sizes: 264 Byte for command 0x81, 2112 Byte for command 0x50, 2112/67584 Byte for command 0x7c (not all regions erasable), 528 kByte for command 0xc794809a - Addressing -- Address size: 3-byte -- Address space contiguousness: With holes -- Address granularity: Direct byte access (other options exist) - Reading -- Minimum read size: 1 Byte (mind the holes in address space) -- Maximum read size: unlimited (mind the holes in address space for initial address, but the read result will have no holes even for reads spanning holes) - Writing: -- Maximum write size in one meta-command: 264 Bytes -- Maximum (or fixed) write size in one sub-command: 264 Bytes -- Minimum write size: 264 Bytes (unusual for other SPI chips)
SST SST25VF016B: (AAI) - Total size: 2048 kByte - Erase block sizes: 4 kByte for command 0x20, 32 kByte for command 0x52, 64 kByte for command 0xd8, 2 MByte for commands 0x60/0xc7 - Addressing -- Address size: 3-Byte -- Address space contiguousness: No holes -- Address granularity: Direct Byte access - Reading -- Minimum read size: 1 Byte -- Maximum read size: unlimited - Writing: Write method: Byte write -- Maximum write size in one meta-command: 1 Byte -- Maximum (or fixed) write size in one sub-command: 1 Byte -- Minimum write size: 1 Byte - Writing: Write method: AAI write -- Maximum write size in one meta-command: 2097152 Bytes (chip size) -- Maximum (or fixed) write size in one sub-command: 2 Bytes -- Minimum write size: 2 Bytes
The "write_granularity" we have in our tree is the minimum write size. Depending on the datasheet author, "page size" can be a minimum write size, maximum write size, minimum read size, maximum read size or largest contiguous chunk in the address space.
The most prudent thing would probably be to rename chip->gran to chip->write_min_size, as well as add veriables chip->write_max_size and chip->address_holes_after (264 bytes for AT45DB041D in 264-byte page mode). We'll also need a function chip->linear_to_physical_address function.
I'll try to answer your questions below.
Am 28.03.2013 11:41 schrieb Mark Marshall:
I'm currently struggling to understand what the write granularity is for and how it interacts with the page size? I'm also a little confused by flashrom's use of page size?
I am mainly interested in SPI flash chips. For most SPI chips the "page size" is 256 bytes. I have a chip where the page size is 512 bytes.
The "page size" is the amount that writes using the PP command have to be chunked by. So "spi_nbyte_program" must be used to write no more than "page size" bytes and must not cross a "page size" boundary.
Yes. With my new terminology, this would be write_max_size instead of page_size.
So far this all makes sense, apart from the "spi_chip_write_256" function, which should be named "spi_chip_write_page"? (as all chips currently have a page size of 256 this is correct at the moment, but I'm about to add one that doesn't).
Correct.
I think that the "chunksize" parameter in spi_write_chunked is to do with possible restrictions of some programmer hardware? This also makes sense, apart from all of the comments which are very out of date?
Yes.
According to the manuals of the SPI Flash chips I've looked at, when using the PP command you can program any part of a page, and the correct thing will happen (1's can only be written to 0's). So I don't see how this matches up with "write granularity", which claims that the other bytes in the granularity region will be "undefined"?
If you can write a single byte multiple times as long as you never try to set a 0 bit to 1, you have 1-bit granularity. If you can write a single byte just once, you have 1-byte granularity. If you can only write multiple bytes at once (e.g. 264 bytes for AT45* in some modes) and non-written bytes of a "page" end up undefined, you have n-byte granularity.
Is write granularity for something else?
No, it's just really complicated.
Is there a post somewhere that I missed that explains all of this?
No post anywhere, and your mail prompted me to write something up.
Hope it helped.
Regards, Carl-Daniel