There is a defect in basic design of flashrom. It leads to problems some developers are facing or going to face. A partial solution is proposed.
1. The Defect
struct flashchip {
/* ... */
int (*probe) (struct flashchip *flash); int (*erase) (struct flashchip *flash); int (*write) (struct flashchip *flash, uint8_t *buf); int (*read) (struct flashchip *flash, uint8_t *buf);
/* ... */
};
The struct specifies drivers for operations. It is a good design if the drivers deal with flash chips directly and provide interfaces for upper layer program to use. However, those drivers deal with every component in the communication chain. They do not fit into a structure storing information closely related to flash chips.
2. Problems
Supporting non-standard flash chips needs to write a new driver. It requires the developer to be familiar with the internals of flashrom.
Probe functions and IDs are seperated. They are associated by the flashchip structure. In nature, probe functions and IDs are questions and answers, and should be associated more closely. Seperated ID fields in struct flashchip are not very meaningful.
flashrom will probably have plugins in the future. Though chips are operated in the same way from the view of their host devices, there is not much useful information for plugins in struct flashchip.
3. Solution
We need an abstract specification of operations in struct flashchip, not actual code. If there have to be some information not related to flash chips, the less there is, the better.
Abstract operation specification for SPI flash chips:
/* BEGINNING OF SPECIFICATION */
struct cycles { u8 type; /* CYCLETYPE_PREOPCODE, CYCLETYPE_OPCODE, */ /* CYCLETYPE_ADDRESS, CYCLETYPE_DUMMY, */ /* CYCLETYPE_DATA_IN, CYCLETYPE_DATA_OUT */ u8 length; /* in bytes */ u8 value_type; /* VALUETYPE_VARIABLE, VALUETYPE_FIXED */ u32 value; };
struct cycles byte_read[] = {{CYCLETYPE_OPCODE, 1, VALUETYPE_FIXED, 0x3}, {CYCLETYPE_ADDRESS, 3, VALUETYPE_VARIABLE}, {CYCLETYPE_DATA_IN, 1, VALUETYPE_VARIABLE} };
struct cycles byte_program[] = {{CYCLETYPE_PREOPCODE, 1, VALUETYPE_FIXED, 0x6}, {CYCLETYPE_OPCODE, 1, VALUETYPE_FIXED, 0x2}, {CYCLETYPE_ADDRESS, 3, VALUETYPE_VARIABLE}, {CYCLETYPE_DATA_OUT, 1, VALUETYPE_VARIABLE} };
struct cycles SST25VF040B_probe_rdid[] = {{CYCLETYPE_OPCODE, 1, VALUETYPE_FIXED, 0x90}, {CYCLETYPE_ADDRESS, 3, VALUETYPE_FIXED, 0}, {CYCLETYPE_DATA_IN, 2, VALUETYPE_FIXED, 0xbf8d} };
struct cycles SST25VF040B_probe_jedec[] = {{CYCLETYPE_OPCODE, 1, VALUETYPE_FIXED, 0x9f}, {CYCLETYPE_DATA_IN, 3, VALUETYPE_FIXED, 0xbf258d} };
/* END OF SPECIFICATION */
Specifications for LPC and FWH flash chips will be different, but the point is abstraction.
Comments are appreciated.
New year's greetings, yu ning