Hi all, I am volunteering as a mentor for flashrom this year. I'm happy to mentor a variety of projects, this is just another suggestion. Some of the groundwork exists already, but AFAIK flashing with a host-connected microcontroller involved is still rather painful.
Anyway, here's a draft proposal.
*Abstract* The goal of this project is to help Flashrom prepare for future generations by re-thinking the notion of an "internal" programmer to elegantly incorporate product-specific procedures for coordinating the interactions between the host (where flashrom is run) and various microcontrollers in the system.
*Requirements* Student should have some experience using flashrom, familiarity with the codebase and in particular the "internal" programmer codepath. The student will must be comfortable re-factoring flashrom code. The student does not need datasheet-level knowledge of any particular chip (all that exists in code already), but must have some idea of how firmware ROMs are used in a modern x86 system so that a proper abstraction model can be implemented.
*Background* When Flashrom was started long ago, the "internal" programmer was much simpler. Most mainboards had exactly one master (the chipset or "southbridge") and one target (NOR flash memory connected via LPC/FWH or SPI bus). In general, desktop and servers machine only had one master interfacing with the flash memory chip so the programming model was simple as there were no possible access conflicts. About the only thing needed was to ensure GPIOs for write-protection and memory ranges were set properly.
However, laptops broke this model by incorporating an additional microcontroller, commonly known as the "embedded controller" or EC, which often share the same flash memory. Flashrom has always had difficulties with laptops, going so far as to force the user to use the option "force_I_want_a_brick". Modern desktop and server chipsets have begun incorporating yet another microcontroller (AMD IMC and Intel ME) and now Flashrom is suffering similar difficulties on desktops and servers which it has historically been reliable on.
*Details* Laptops broke the simple model due to the presence of secondary microcontrollers ("embedded controllers" or ECs for short). These are low-power SoCs which are often used for tasks such as power management, keyboard scanning, reading sensors, etc. and are usually conntected via LPC to the host chipset. They source power from the battery and run independently and constantly thus allowing laptops to respond to events such as keypress (e.g. power button on keyboard matrix rather than GPIO), lid open/close, etc. while the host is off or suspended. EC firmware is generally written for a particular mainboard or family of mainboards. There is generally no single firmware update procedure for a particular EC. So even if two different laptops use the same EC, the update procedure is likely to be different.
ECs may require frequent access to the ROM under normal operation due to loading code and data (many ECs have only hundreds of bytes of internal RAM). Additionally, they typically respond to several interrupt sources. In order to update the firmware of an EC we must make the EC enter an update mode to disable interrupts suspend normal operation (to avoid spurious access to the ROM). The firmware code for ECs is generally closed, though some vendors have made update procedures public.
To make matters more complicated, modern x86 chipsets often include yet another microcontroller such as Intel's Management Engine (ME) or AMD's Integrated Microcontroller (IMC). Similar to ECs, these are low-power microcontrollers which may run persistently and share the firmware ROM with the host chipset, thereby adding another master flashrom must coordinate with.
One added complexity brought about by Intel MEs is that certain regions of the firmware ROM may be protected from reads and/or writes from the host. Flashrom has always assumed that it can access the entire ROM which is no longer true on modern Intel systems. Mainboard-specific policy must be set so that Flashrom can alter or disable the protection (if ME update is required), ignore the ME region (if ME update can be ignored), or simply refuse to update at all (likely the default behavior).
*Milestones*
- Refactor internal programmer codepath so that mainboard-specific policies and procedures may override default behavior. This may improve upon the existing board_enable functionality, but will take a more proactive role in the read/write procedures rather than being only for enable/disable routines. This will handle things such as: - Microcontroller discovery (since EC/SuperIO IDs can conflict) - Abstraction of low-level interfaces (e.g. IO ranges used for communication) - Mainboard-specific protocol handling (ie special read/write routines for ECs) - Decisions such as what to do in case of a potentially non-fatal error (ME read/write access denied) - etc. - Incorporate EC code from ChromiumOS branch. Code will be tested on "known-working" production systems. - Improve the "-p internal" syntax so that internal targets can be specified by device class instead of bus, e.g. "-p internal:ec", "-p internal:host", "-p internal:imc", etc.