1# Timestamps 2 3## Introduction 4 5The aim of the timestamp library is to make it easier for different boards 6to save timestamps in cbmem / stash (until cbmem is brought up) by 7providing a simple API to initialize, add and sync timestamps. In order 8to make the timestamps persistent and accessible from the kernel, we 9need to ensure that all the saved timestamps end up in cbmem under 10the CBMEM_ID_TIMESTAMP tag. However, until the cbmem area is available, 11the timestamps can be saved to a SoC-defined \_timestamp region or in a 12local stage-specific stash. The work of identifying the right location for 13storing timestamps is done by the library and is not exposed to the user. 14 15Working of timestamp library from a user perspective can be outlined in 16the following steps: 171. Initialize the base time and reset cbmem timestamp area 182. Start adding timestamps 19 20Behind the scenes, the timestamp library takes care of: 211. Identifying the correct location for storing timestamps (cbmem or timestamp 22 region or local stash). 232. Once cbmem is up, ensure that all timestamps are synced from timestamp 24 region or local stash into the cbmem area. 253. Add a new cbmem timestamp area based on whether a reset of the cbmem 26 timestamp region is required or not. 27 28### Transition from cache to cbmem 29 30To move timestamps from the cache to cbmem (and initialize the cbmem area in 31the first place), we use the CBMEM_INIT_HOOK infrastructure of coreboot. 32 33When cbmem is initialized, the hook is called, which creates the area, 34copies all timestamps to cbmem and disables the cache. 35 36After such a transition, timestamp_init() must not be run again. 37 38 39## Data structures used 40 41The main structure that maintains information about the timestamp cache is: 42 43```c 44struct __packed timestamp_cache { 45 uint16_t cache_state; 46 struct timestamp_table table; 47 struct timestamp_entry entries[MAX_TIMESTAMP_CACHE]; 48}; 49``` 50 51### cache_state 52 53The state of the cache is maintained by `cache_state` attribute which can 54be any one of the following: 55 56```c 57enum { 58 TIMESTAMP_CACHE_UNINITIALIZED = 0, 59 TIMESTAMP_CACHE_INITIALIZED, 60 TIMESTAMP_CACHE_NOT_NEEDED, 61}; 62``` 63 64By default, if the cache is stored in local stash (bss area), then 65it will be reset to uninitialized state. However, if the cache is 66stored in timestamp region, then it might have garbage in any of the 67attributes. Thus, if the timestamp region is being used by any board, it is 68initialized to default values by the library. 69 70Once the cache is initialized, its state is set to 71`CACHE_INITIALIZED`. Henceforth, the calls to cache i.e. `timestamp_add` 72know that the state reflected is valid and timestamps can be directly 73saved in the cache. 74 75Once the cbmem area is up (i.e. call to `timestamp_sync_cache_to_cbmem`), 76we do not need to store the timestamps in local stash / timestamp area 77anymore. Thus, the cache state is set to `CACHE_NOT_NEEDED`, which allows 78`timestamp_add` to store all timestamps directly into the cbmem area. 79 80 81### table 82 83This field is represented by a structure which provides overall 84information about the entries in the timestamp area: 85 86```c 87struct timestamp_table { 88 uint64_t base_time; 89 uint32_t max_entries; 90 uint32_t num_entries; 91 struct timestamp_entry entries[0]; /* Variable number of entries */ 92} __packed; 93``` 94 95It indicates the base time for all timestamp entries, maximum number 96of entries that can be stored, total number of entries that currently 97exist and an entry structure to hold variable number of entries. 98 99 100### entries 101 102This field holds the details of each timestamp entry, up to a maximum 103of `MAX_TIMESTAMP_CACHE` which is defined as 16 entries. Each entry is 104defined by: 105 106```c 107struct timestamp_entry { 108 uint32_t entry_id; 109 uint64_t entry_stamp; 110} __packed; 111``` 112 113`entry_id` holds the timestamp id corresponding to this entry and 114`entry_stamp` holds the actual timestamp. 115 116 117For timestamps stored in the cbmem area, a `timestamp_table` is allocated 118with space for `MAX_TIMESTAMPS` equal to 30. Thus, the cbmem area holds 119`base_time`, `max_entries` (which is 30), current number of entries and the 120actual entries represented by `timestamp_entry`. 121 122 123## Function APIs 124 125### timestamp_init 126 127This function initializes the timestamp cache and should be run as early 128as possible. On platforms with SRAM, this might mean in bootblock, on 129x86 with its CAR backed memory in romstage, this means romstage before 130memory init. 131 132### timestamp_add 133 134This function accepts from user a timestamp id and time to record in the 135timestamp table. It stores the entry in the appropriate table in cbmem 136or `_timestamp` region or local stash. 137 138 139### timestamp_add_now 140 141This function calls `timestamp_add` with user-provided id and current time. 142 143 144## Use / Test Cases 145 146The following cases have been considered while designing the timestamp 147library. It is important to ensure that any changes made to this library satisfy 148each of the following use cases: 149 150### Case 1: Timestamp Region Exists (Fresh Boot / Resume) 151 152In this case, the library needs to call `timestamp_init` as early as possible to 153enable the timestamp cache. Once cbmem is available, the values will be 154transferred automatically. 155 156All regions are automatically reset on initialization. 157 158### Case 2: No timestamp region, fresh boot, cbmem_initialize called after timestamp_init 159 160`timestamp_init` will set up a local cache. cbmem must be initialized before that 161cache vanishes - as happens when jumping to the next stage. 162 163### Case 3: No timestamp region, fresh boot, cbmem_initialize called before timestamp_init 164 165This case is not supported right now, just don't call `timestamp_init` after 166`cbmem_initialize`. (Patches to make this more robust are welcome.) 167 168### Case 4: No timestamp region, resume, cbmem_initialize called after timestamp_init 169 170We always reset the cbmem region before using it, so pre-suspend timestamps 171will be gone. 172 173### Case 5: No timestamp region, resume, cbmem_initialize called before timestamp_init 174 175We always reset the cbmem region before using it, so pre-suspend timestamps 176will be gone. 177