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)
src/soc/intel/common/block/cpu/car/cache_as_ram.S is a candidate which hard codes all post codes (instead of using post_codes.h) and that file alone already uses more than your 16 propsed postcodes for bootblock (I think). Since bootblock is kind of relying on post codes for proper debug (since serial output may not be available at that time), it would make sense to use more post codes for bootblock I guess.
On Wed, Nov 16, 2022, 17:23 Martin Roth via coreboot coreboot@coreboot.org wrote:
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)
coreboot mailing list -- coreboot@coreboot.org To unsubscribe send an email to coreboot-leave@coreboot.org
On Wed, Nov 16, 2022 at 9:23 AM Martin Roth via coreboot coreboot@coreboot.org wrote:
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.
A while ago I did look into the topic of post codes a bit and wrote a script to summarize all usages of post_code(), the post code macros, and usages of raw hex values. I've since tweaked it and have uploaded a patch to Gerrit [1]. Hopefully it will help track down where and what postcodes are currently used throughout the tree. Also of note is that there are a number of post code macros in src/soc/amd/common/psp_verstage/include/psp_verstage.h, which also sometimes conflict with other codes (something made very clear in the output of my script)
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
FSP does seem to have some of its own internal multibyte post codes (refer to the FSP integration guides) so that might conflict with these ranges, but I guess post codes issued by coreboot before and after an FSP call would help differentiate these.
Sindhoor Tilak also seems to have done some work on post codes a few years ago [2], though it may not apply to the current state of the tree and probably now has post code values that conflict with Martin's suggestions.
Cheers, Nicholas
[1] https://review.coreboot.org/c/coreboot/+/69712 [2] https://review.coreboot.org/q/owner:sindhoor%2540sin9yt.net