The current state of the coreboot postcodes is a mess. There’s no good way to give anyone a postcode table. The post_code() function is called with direct hardcoded values all over the codebase. The post_codes.h file is disorganized with values being added without regard for being contiguous or ordered. As an example, despite using hexadecimal values, console post codes go from 0x39 to 0x40.
We can do better than this.
Proposal -------- The postcodes should be better organized and standardized. Each stage should have its own block of postcodes, and they should be easily recognizable as a flow from early coreboot to late coreboot. common between blocks: - bootblock - verstage - romstage - postcar - ramstage - smm
We should have blocks of postcodes for different sections as well. - SoC/CPU/Chipset - Mainboard - Drivers
- A set of debug-specific postcodes that may be used in any area, but may not be enabled by default, but only by user request. - The debug and driver post codes should have identifiers to show what section of the codebase they're coming from. - Finally, there should be small section of uncontrolled values that can be used anywhere that doesn’t have an already allocated specific value.
Additional Improvements ----------------------- - Postcodes should be able to be included in the timestamp table so we can grab timestamps for individual postcodes. - Specific Postcodes should have associated text names, similar to the timestamps, and should have a decode tool. - Multi-byte postcodes should be implemented for platforms that support them.
Proposed postcode ranges ------------------------
``` * 0x00 : unregulated - 0x00 is not a good postcode. * * 0x01 - 0x07 : coreboot startup code & common * 0x08 - 0x0b : coreboot console * 0x0c - 0x0f : <RESERVED> * * 0x10 - 0x1f : coreboot bootblock * 0x20 - 0x2f : coreboot romstage * 0x30 - 0x33 : postcar * 0x34 - 0x3f : coreboot ramstage * 0x40 - 0x4f : coreboot ramstage hardwaremain boot stages * * 0x50 - 0x5f : Mainboard specific - Each mainboard can use as it chooses * 0x60 - 0x6f : SOC specific - Each SoC/CPU/Chipset can use as it chooses * * 0x70 : Driver/SuperIO ID, followed by ID byte * 0x71 - 0x7f : Driver/SuperIO specific - Can use as the device chooses * * 0x80 - 0x87 : ACPI postcodes * 0x88 - 0x8f : Unregulated - may be used anywhere for any purpose. * 0x90 - 0x9f : Vendorcode calls: FSP, AGESA, etc. * * 0xa0 - 0xaf : <RESERVED> * 0xb0 - 0xbf : <RESERVED> * * 0xc0 - 0xca : <RESERVED> * * 0xcb : coreboot identifier - used when returning from FSP, AGESA, etc * * 0xcc - 0xcf : <RESERVED> * * 0xd0 - 0xdf : Debug postcodes - never enabled by default. * * 0xe0 - 0xef : Errors * 0xf0 - 0xf7 : SMM * 0xf8 - 0xfe : end of coreboot code - resume and the like. * 0xff : coreboot finished - jump to payload ```
Driver/SuperIO/Debug IDs ------------------------
Because there are many drivers, and a single board can use multiple of the drivers, we want a way to know which device is putting out postcodes. To handle this, the driver, superIO, or debug section should emit a DRIVER_ID_FOLLOWS or DEBUG_ID_FOLLOWS postcode, followed by the actual ID code.
The ID code would currently be a single byte, with the bytes 0xf0 - 0xff being reserved as page and continue bytes. The continue bytes would tell the code that the ID is on a secondary or later page - See the method used by the SPD to identify Manufacturers as a similar concept. 0xF0 - 0xFE would each point to a page of 240 possible drivers, and 0xff would tell the code to look for the next level of pages, which would follow the same pattern.
The driver IDs and debug IDs would all be contained in separate header files.
This would allow for the area to be uniquely identified by a tool.
Postcode rules --------------
- Don’t use postcodes other than the debug postcodes in loops. Spewing out postcodes isn’t helpful. - Don’t output bare numbers, a macro in post_codes.h must be used. A linter will be set up to look the macros and will give an error if it’s not one of the postcode files. - All postcode output should be able to be identified by an automatic parser tool (with the exception of unregulated codes)