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