summaryrefslogtreecommitdiff
path: root/Documentation/lib
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/lib')
-rw-r--r--Documentation/lib/abi-data-consumption.md25
-rw-r--r--Documentation/lib/index.md4
-rw-r--r--Documentation/lib/timestamp.md176
3 files changed, 204 insertions, 1 deletions
diff --git a/Documentation/lib/abi-data-consumption.md b/Documentation/lib/abi-data-consumption.md
new file mode 100644
index 0000000000..d162199cab
--- /dev/null
+++ b/Documentation/lib/abi-data-consumption.md
@@ -0,0 +1,25 @@
+# ABI data consumption
+
+This text describes the ABI coreboot presents to downstream users. Such
+users are payloads and/or operating systems. Therefore, this text serves
+at what can be relied on for downstream consumption. Anything not explicitly
+listed as consumable is subject to change without notice.
+
+## Background and Usage
+
+coreboot passes information to downstream users using coreboot tables. These
+table definitions can be found in
+`./src/commonlib/include/commonlib/coreboot_tables.h` and
+`./payloads/libpayload/include/coreboot_tables.h` respectively within coreboot
+and libpayload. One of the most vital and important pieces of information
+found within these tables is the memory map of the system indicating
+available and reserved memory.
+
+In 2009 cbmem was added to coreboot. The "CBMEM high table memory manager"
+serves a way for coreboot to bookkeep its own internal data. While some
+of this data may be exposed through the coreboot tables the data structures
+used to manage the data within the cbmem area is subject to change.
+
+Provided the above, if one needs a piece of data exposed to the OS
+or payload it should reside within the coreboot tables. If it isn't there
+then a code change will be required to add it to the coreboot tables.
diff --git a/Documentation/lib/index.md b/Documentation/lib/index.md
index 85e046079d..99b8061325 100644
--- a/Documentation/lib/index.md
+++ b/Documentation/lib/index.md
@@ -3,5 +3,7 @@
This section contains documentation about coreboot internal technical
information and libraries.
-# Structure and layout
+## Structure and layout
- [Flashmap and Flashmap Descriptor](flashmap.md)
+- [ABI data consumption](abi-data-consumption.md)
+- [Timestamps](timestamp.md)
diff --git a/Documentation/lib/timestamp.md b/Documentation/lib/timestamp.md
new file mode 100644
index 0000000000..d5dc8facf3
--- /dev/null
+++ b/Documentation/lib/timestamp.md
@@ -0,0 +1,176 @@
+# Timestamps
+
+## Introduction
+
+The aim of the timestamp library is to make it easier for different boards
+to save timestamps in cbmem / stash (until cbmem is brought up) by
+providing a simple API to initialize, add and sync timestamps. In order
+to make the timestamps persistent and accessible from the kernel, we
+need to ensure that all the saved timestamps end up in cbmem under
+the CBMEM_ID_TIMESTAMP tag. However, until the cbmem area is available,
+the timestamps can be saved to a SoC-defined \_timestamp region or in a
+local stage-specific stash. The work of identifying the right location for
+storing timestamps is done by the library and is not exposed to the user.
+
+Working of timestamp library from a user perspective can be outlined in
+the following steps:
+1. Initialize the base time and reset cbmem timestamp area
+2. Start adding timestamps
+
+Behind the scenes, the timestamp library takes care of:
+1. Identifying the correct location for storing timestamps (cbmem or timestamp
+ region or local stash).
+2. Once cbmem is up, ensure that all timestamps are synced from timestamp
+ region or local stash into the cbmem area.
+3. Add a new cbmem timestamp area based on whether a reset of the cbmem
+ timestamp region is required or not.
+
+### Transition from cache to cbmem
+
+To move timestamps from the cache to cbmem (and initialize the cbmem area in
+the first place), we use the CBMEM_INIT_HOOK infrastructure of coreboot.
+
+When cbmem is initialized, the hook is called, which creates the area,
+copies all timestamps to cbmem and disables the cache.
+
+After such a transition, timestamp_init() must not be run again.
+
+
+## Data structures used
+
+The main structure that maintains information about the timestamp cache is:
+
+```c
+struct __packed timestamp_cache {
+ uint16_t cache_state;
+ struct timestamp_table table;
+ struct timestamp_entry entries[MAX_TIMESTAMP_CACHE];
+};
+```
+
+### cache_state
+
+The state of the cache is maintained by `cache_state` attribute which can
+be any one of the following:
+
+```c
+enum {
+ TIMESTAMP_CACHE_UNINITIALIZED = 0,
+ TIMESTAMP_CACHE_INITIALIZED,
+ TIMESTAMP_CACHE_NOT_NEEDED,
+};
+```
+
+By default, if the cache is stored in local stash (bss area), then
+it will be reset to uninitialized state. However, if the cache is
+stored in timestamp region, then it might have garbage in any of the
+attributes. Thus, if the timestamp region is being used by any board, it is
+initialized to default values by the library.
+
+Once the cache is initialized, its state is set to
+`CACHE_INITIALIZED`. Henceforth, the calls to cache i.e. `timestamp_add`
+know that the state reflected is valid and timestamps can be directly
+saved in the cache.
+
+Once the cbmem area is up (i.e. call to `timestamp_sync_cache_to_cbmem`),
+we do not need to store the timestamps in local stash / timestamp area
+anymore. Thus, the cache state is set to `CACHE_NOT_NEEDED`, which allows
+`timestamp_add` to store all timestamps directly into the cbmem area.
+
+
+### table
+
+This field is represented by a structure which provides overall
+information about the entries in the timestamp area:
+
+```c
+struct timestamp_table {
+ uint64_t base_time;
+ uint32_t max_entries;
+ uint32_t num_entries;
+ struct timestamp_entry entries[0]; /* Variable number of entries */
+} __packed;
+```
+
+It indicates the base time for all timestamp entries, maximum number
+of entries that can be stored, total number of entries that currently
+exist and an entry structure to hold variable number of entries.
+
+
+### entries
+
+This field holds the details of each timestamp entry, upto a maximum
+of `MAX_TIMESTAMP_CACHE` which is defined as 16 entries. Each entry is
+defined by:
+
+```c
+struct timestamp_entry {
+ uint32_t entry_id;
+ uint64_t entry_stamp;
+} __packed;
+```
+
+`entry_id` holds the timestamp id corresponding to this entry and
+`entry_stamp` holds the actual timestamp.
+
+
+For timestamps stored in the cbmem area, a `timestamp_table` is allocated
+with space for `MAX_TIMESTAMPS` equal to 30. Thus, the cbmem area holds
+`base_time`, `max_entries` (which is 30), current number of entries and the
+actual entries represented by `timestamp_entry`.
+
+
+## Function APIs
+
+### timestamp_init
+
+This function initializes the timestamp cache and should be run as early
+as possible. On platforms with SRAM, this might mean in bootblock, on
+x86 with its CAR backed memory in romstage, this means romstage before
+memory init.
+
+### timestamp_add
+
+This function accepts from user a timestamp id and time to record in the
+timestamp table. It stores the entry in the appropriate table in cbmem
+or `_timestamp` region or local stash.
+
+
+### timestamp_add_now
+
+This function calls `timestamp_add` with user-provided id and current time.
+
+
+## Use / Test Cases
+
+The following cases have been considered while designing the timestamp
+library. It is important to ensure that any changes made to this library satisfy
+each of the following use cases:
+
+### Case 1: Timestamp Region Exists (Fresh Boot / Resume)
+
+In this case, the library needs to call `timestamp_init` as early as possible to
+enable the timestamp cache. Once cbmem is available, the values will be
+transferred automatically.
+
+All regions are automatically reset on initialization.
+
+### Case 2: No timestamp region, fresh boot, cbmem_initialize called after timestamp_init
+
+`timestamp_init` will set up a local cache. cbmem must be initialized before that
+cache vanishes - as happens when jumping to the next stage.
+
+### Case 3: No timestamp region, fresh boot, cbmem_initialize called before timestamp_init
+
+This case is not supported right now, just don't call `timestamp_init` after
+`cbmem_initialize`. (Patches to make this more robust are welcome.)
+
+### Case 4: No timestamp region, resume, cbmem_initialize called after timestamp_init
+
+We always reset the cbmem region before using it, so pre-suspend timestamps
+will be gone.
+
+### Case 5: No timestamp region, resume, cbmem_initialize called before timestamp_init
+
+We always reset the cbmem region before using it, so pre-suspend timestamps
+will be gone.