Martin L Roth has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/87186?usp=email )
Change subject: Documentation: Add Timestamp documentation ......................................................................
Documentation: Add Timestamp documentation
Change-Id: I6e4cc244edf6cc860cc66165173f134a30a81589 Signed-off-by: Martin Roth gaumless@gmail.com --- M Documentation/internals/index.md A Documentation/internals/timestamps.md 2 files changed, 338 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/86/87186/1
diff --git a/Documentation/internals/index.md b/Documentation/internals/index.md index 17dee55..2600069 100644 --- a/Documentation/internals/index.md +++ b/Documentation/internals/index.md @@ -12,3 +12,12 @@ coreboot devicetree language <devicetree_language.md>
``` + +## APIs + +```{toctree} +:maxdepth: 1 + +Timestamps <timestamps.md> + +``` diff --git a/Documentation/internals/timestamps.md b/Documentation/internals/timestamps.md new file mode 100644 index 0000000..82b7be8 --- /dev/null +++ b/Documentation/internals/timestamps.md @@ -0,0 +1,329 @@ +# coreboot Timestamp Implementation + + + +## Introduction + +Timestamps in coreboot are a critical feature for performance analysis, +debugging, and optimization of the boot process. They provide precise +timing information about various stages and operations during system +initialization, allowing developers to identify bottlenecks and optimize +boot performance. The timestamp system is designed to be lightweight, +accurate, and persistent across different boot stages. + + +## Background + +The timestamp implementation in coreboot has evolved over time to meet +the growing needs of firmware development and performance analysis. +Initially designed as a simple timing mechanism, it has grown into a +sophisticated system that: + +- Tracks boot stages and critical operations +- Supports multiple hardware platforms (x86, ARM, RISC-V) +- Provides persistent storage across boot stages +- Enables post-boot analysis of boot performance +- Integrates with vendor-specific firmware components + + +## Timestamp Architecture + +### Data Structures + +The timestamp system uses two main data structures: + +```c +struct timestamp_entry { + uint32_t entry_id; + int64_t entry_stamp; +} __packed; + +struct timestamp_table { + uint64_t base_time; + uint16_t max_entries; + uint16_t tick_freq_mhz; + uint32_t num_entries; + struct timestamp_entry entries[]; /* Variable number of entries */ +} __packed; +``` + +### Memory Layout + +Timestamps are stored in two locations during the boot process: + +1. **Cache Region**: Used during early boot stages (before CBMEM is + available) + - Located in the `timestamp` region defined in memlayout.ld + - Persists across stage transitions + - Limited to 192 entries by default (See `CONFIG_MAX_TIMESTAMP_CACHE_ENTRIES`) + +2. **CBMEM**: Used after CBMEM is initialized + - Provides persistent storage across warm reboots + - Supports more entries + - Automatically synchronized with cache region + + +### Storage Mechanism + +The timestamp system uses a two-phase storage approach: + +1. **Early Boot (ROMSTAGE_OR_BEFORE)**: + - Timestamps are stored in the cache region + - No CBMEM access required + - Limited to 192 entries (configurable via + `CONFIG_MAX_TIMESTAMP_CACHE_ENTRIES`) + +2. **Late Boot (After CBMEM)**: + - Timestamps are stored in CBMEM + - Cache region is synchronized to CBMEM + - Supports more entries + - Persists across warm reboots + + +## API Reference + +### Core Functions + +```c +void timestamp_init(uint64_t base); +``` +Initializes the timestamp system with a base time. Must be called once +in *one* of the `ENV_ROMSTAGE_OR_BEFORE` stages (e.g., bootblock, +romstage). On x86, this must occur before CAR (Cache-as-RAM) is torn +down if called in bootblock or separate romstage. + +```c +void timestamp_add(enum timestamp_id id, int64_t ts_time); +``` +Adds a new timestamp with the specified ID and time value. + +```c +void timestamp_add_now(enum timestamp_id id); +``` +Adds a new timestamp with the current time. + +```c +void timestamp_rescale_table(uint16_t N, uint16_t M); +``` +Applies a scaling factor N/M to all recorded timestamps. + +```c +uint32_t get_us_since_boot(void); +``` +Returns the time since boot in microseconds. + +```c +uint64_t timestamp_get(void); +``` +Returns the current raw timestamp value from the underlying hardware +timer. + +```c +uint64_t get_initial_timestamp(void); +``` +Returns the base_time stored in the timestamp table, representing the +reference point (initial timestamp) the system was initialized with. + +```c +int timestamp_tick_freq_mhz(void); +``` +Returns the timestamp tick frequency in MHz. + +### Timestamp IDs + +The system uses predefined timestamp IDs to mark various boot stages and +operations. These are organized in ranges: + +- 1-99: coreboot boot stages (e.g., `TS_ROMSTAGE_START`, `TS_RAMSTAGE_START`) +- 100-115: Miscellaneous coreboot operations (e.g., `TS_POSTCAR_START`, + `TS_DELAY_START`, `TS_READ_UCODE_START`) +- 500-600: Google/ChromeOS specific (e.g., `TS_VBOOT_START`, `TS_EC_SYNC_START`) +- 900-940: AMD specific (e.g., `TS_AGESA_INIT_EARLY_START`) +- 940-950: Intel ME specific (e.g., `TS_ME_INFORM_DRAM_START`) +- 950-989: Intel FSP specific (e.g., `TS_FSP_MEMORY_INIT_START`) +- 990-999: Intel ME specific (continued) (e.g., `TS_ME_ROM_START`) +- 1000+: Payload specific (e.g., Depthcharge: 1000-1199, ChromeOS + Hypervisor: 1200-1299) + +Refer to `src/commonlib/include/commonlib/timestamp_serialized.h` for +the complete list and descriptions. + + +## Configuration + +### Kconfig Options + +- `COLLECT_TIMESTAMPS`: Enable/disable timestamp collection +- `TIMESTAMPS_ON_CONSOLE`: Print timestamps to console during boot +- `MAX_TIMESTAMP_CACHE_ENTRIES`: Maximum entries in the early cache region + (default 192) + + +### Memory Layout + +The timestamp system requires a `timestamp` region in the memory layout: + +```ld +timestamp : { + _timestamp = .; + *(.timestamp) + . = ALIGN(8); + _etimestamp = .; +} +``` + +### Hardware Considerations + +- x86: Timestamps must be initialized before CAR (Cache-as-RAM) is + torn down if called from bootblock or separate romstage. +- ARM: No special considerations +- RISC-V: No special considerations + + +## Examples + +### Initializing Timestamps + +```c +void bootblock_mainboard_init(void) +{ + timestamp_init(timestamp_get()); +} +``` + +Note: `timestamp_get()` here provides the initial base time. + + +### Adding Custom Timestamps + +```c +void my_custom_function(void) +{ + timestamp_add_now(TS_DEVICE_INITIALIZE); + // ... perform initialization ... + timestamp_add_now(TS_DEVICE_DONE); +} +``` + +### Reading Timestamps + +```c +#include <cbmem.h> +#include <console/console.h> +#include <commonlib/timestamp_serialized.h> + +void analyze_timestamps(void) +{ + struct timestamp_table *ts_table = cbmem_find(CBMEM_ID_TIMESTAMP); + if (!ts_table) { + printk(BIOS_INFO, "Timestamp table not found in CBMEM.\n"); + return; + } + + printk(BIOS_INFO, "Timestamp Table Analysis:\n"); + printk(BIOS_INFO, " Base Time: %lld\n", ts_table->base_time); + printk(BIOS_INFO, " Tick Freq: %u MHz\n", ts_table->tick_freq_mhz); + printk(BIOS_INFO, " Entries: %u / %u\n", + ts_table->num_entries, ts_table->max_entries); + + for (int i = 0; i < ts_table->num_entries; i++) { + struct timestamp_entry *tse = &ts_table->entries[i]; + /* Convert raw timestamp to microseconds relative to base */ + uint64_t time_us = tse->entry_stamp - ts_table->base_time; + if (ts_table->tick_freq_mhz > 0) + time_us /= ts_table->tick_freq_mhz; + + printk(BIOS_INFO, " Entry %d: ID=%u, Raw=%lld, Rel Time=%llu us\n", + i, tse->entry_id, tse->entry_stamp, time_us); + } +} +``` + +## Best Practices + +1. **Initialization**: + - Initialize timestamps as early as possible + - Use a consistent base time across all stages + - Ensure proper memory region allocation + +2. **Adding Timestamps**: + - Use appropriate timestamp IDs + - Add timestamps for significant operations + - Keep timestamp frequency reasonable + - Avoid adding timestamps in performance-critical paths + +3. **Memory Management**: + - Be aware of the entry limit in early boot (default 192, check + `CONFIG_MAX_TIMESTAMP_CACHE_ENTRIES`) + - Monitor timestamp table usage via `cbmem -t` or custom code + - Handle potential overflow conditions if necessary + +4. **Platform-Specific Considerations**: + - Follow platform-specific initialization requirements + - Consider hardware timer limitations + - Account for platform-specific boot stages + +## Tools and Visualization + +### Built-in Tools + +- `cbmem -t`: Display timestamps from CBMEM +- `cbmem -c`: Display timestamps in chronological order +- `cbmem -1`: Display timestamps with relative times (microseconds) + +### External Tools + +- coreboot's timestamp analysis scripts (`util/timestamps/`) +- Custom visualization tools +- Performance analysis frameworks + + +## Troubleshooting + +### Common Issues + +1. **Missing Timestamps**: + - Check if `COLLECT_TIMESTAMPS` is enabled + - Verify memory region allocation + - Check initialization timing + +2. **Incorrect Times**: + - Verify base time initialization (`timestamp_init`) + - Check timer frequency calibration (`tick_freq_mhz` in table) + - Ensure proper scaling factors if `timestamp_rescale_table` is used + +3. **Table Overflow**: + - Monitor entry count (`num_entries` vs `max_entries` in table) + - Reduce timestamp frequency by adding fewer custom timestamps + - Increase cache size (`CONFIG_MAX_TIMESTAMP_CACHE_ENTRIES`) or CBMEM + size if possible + + +### Debugging Tips + +1. Enable `TIMESTAMPS_ON_CONSOLE` for real-time debugging +2. Use `cbmem -t` to verify timestamp collection +3. Check memory layout for proper `timestamp` region allocation +4. Verify timer initialization and calibration in platform code + + +## Future Development + +### Planned Improvements + +1. Enhanced visualization tools +2. Better integration with performance analysis frameworks +3. Support for more hardware platforms +4. Improved timestamp synchronization +5. Enhanced error handling and recovery + + +### Contributing + +Developers can contribute to the timestamp system by: + +1. Adding new timestamp IDs for platform-specific or generic operations +2. Improving timestamp analysis tools (e.g., `util/timestamps/`) +3. Enhancing documentation with more examples or platform details +4. Optimizing timestamp collection performance +5. Adding support for new hardware timer sources or platforms