[coreboot-gerrit] Patch set updated for coreboot: documentation: Add documentation for timestamp library

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Fri Jul 3 16:41:02 CEST 2015


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/10741

-gerrit

commit cdde2d65fa61de250e79cbf1f5e34f6dd5573f69
Author: Furquan Shaikh <furquan at google.com>
Date:   Fri Nov 14 11:57:00 2014 -0800

    documentation: Add documentation for timestamp library
    
    BUG=chrome-os-partner:32973
    BRANCH=None
    TEST=None
    
    Original-Change-Id: I4b184ffad6fcd93d63343a9bca34ad013e9d4263
    Original-Signed-off-by: Furquan Shaikh <furquan at google.com>
    Original-Reviewed-on: https://chromium-review.googlesource.com/229861
    Original-Tested-by: Furquan Shaikh <furquan at chromium.org>
    Original-Reviewed-by: Aaron Durbin <adurbin at chromium.org>
    Original-Commit-Queue: Furquan Shaikh <furquan at chromium.org>
    
    (cherry picked from commit 97e2a3ebd9552c2a91d9ea62be515059428631cb)
    Signed-off-by: Marc Jones <marc.jones at se-eng.com>
    
    Change-Id: I6ea7237f2fa749ce3a493f378f9937e642f3b678
---
 Documentation/timestamp_library.txt | 445 ++++++++++++++++++++++++++++++++++++
 1 file changed, 445 insertions(+)

diff --git a/Documentation/timestamp_library.txt b/Documentation/timestamp_library.txt
new file mode 100644
index 0000000..b157c6f
--- /dev/null
+++ b/Documentation/timestamp_library.txt
@@ -0,0 +1,445 @@
+=========================== Table of Contents ==================================
+Introduction
+
+Data structures used
+	cache_state
+	cbmem_state
+	table
+	entries
+
+Internal Functions
+	timestamp_cache_init
+	timestamp_cache_get
+	timestamp_alloc_cbmem_table
+	timestamp_table_get
+	timestamp_add_table_entry
+
+Function APIs
+	timestamp_early_init
+	timestamp_init
+	timestamp_add
+	timestamp_add_now
+	timestamp_sync
+
+Use / Test Cases
+	Case 1: Timestamp Region Exists
+	Case 2: No timestamp region, fresh boot, cbmem_initialize called after
+	timestamp_init
+	Case 3: No timestamp region, fresh boot, cbmem_initialize called before
+	timestamp_init
+	Case 4: No timestamp region, resume, cbmem_initialize called after
+	timestamp_init
+	Case 5: No timestamp region, resume, cbmem_initialize called before
+	timestamp_init
+
+
+============================== Introduction ====================================
+
+	The aim of 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 area under the CBMEM_ID_TIMESTAMP
+tag. However, until the cbmem area is available, the timestamps can be saved to
+board/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 _timestamp cache (if any used)
+2. Initialize the base time and reset cbmem timestamp area
+3. Start adding timestamps
+
+	Steps 1) and 2) above can be performed in a single API call as explained
+in later sections. 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 cbmem timestamp
+region is required / not.
+
+========================== Data structures used ================================
+
+	The main structure that maintains information about the timestamp cache
+is:
+struct __attribute__((__packed__)) timestamp_cache {
+        uint16_t cache_state;
+        uint16_t cbmem_state;
+        struct timestamp_table table;
+        struct timestamp_entry entries[MAX_TIMESTAMP_CACHE];
+};
+
+1. cache_state
+	The state of the cache is maintained by cache_state attribute which can
+be any one of the following:
+
+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
+_timestamp region is being used by any board, it is important to call
+timestamp_early_init which provides the initialization of timestamp cache.
+
+	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.
+
+	When cbmem area is up (i.e. call to cbmem_initialize), 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 cbmem area.
+
+
+2. cbmem_state
+	This attribute indicates if we need to reset the timestamp area in
+cbmem. This needs to be done for fresh boot (when there is no timestamp area
+allocated in cbmem) or during resume (to clean out timestamps from earlier
+boot). This can be set to any one of the following values:
+
+enum {
+        TIMESTAMP_CBMEM_RESET_NOT_REQD = 0,
+        TIMESTAMP_CBMEM_RESET_REQD,
+};
+
+	If _timestamp region is being used, the call to timestamp_early_init
+sets this field to reset_reqd. If this region is not being used, then instead
+the call to timestamp_init sets this field to reset_reqd. Thus, when cbmem
+initialization is complete, the timestamp library ensures that the cbmem
+timestamp area is properly set as per the value of this attribute and resets
+this field to reset_not_reqd. In case of resume path, this field would be set
+accordingly by timestamp_early_init  / timestamp_init thus ensuring that
+timestamps from earlier boot dont float around into current boot logs. Also,
+during early ramstage, when cbmem is not yet up, local stash would be used which
+is in the bss area and thus this field is set to reset_not_reqd (unless
+timestamp_init is called before or after cbmem_intiialize). Hence, when ramstage
+brings up cbmem and syncs timestamps, the cbmem timestamp area is not reset. If
+ramstage is the first stage where timestamp_init is called, then the cbmem area
+is accordingly reset in timestamp_sync  or timestamp_init based on the order in
+which calls are made. Details are explained in the use cases towards the end.
+
+
+3. table
+	This field is represented by a structure which provides overall
+information  about the entries in the timestamp area:
+
+struct timestamp_table {
+        uint64_t        base_time;
+        uint32_t        max_entries;
+        uint32_t        num_entries;
+        struct timestamp_entry entries[0]; /* Variable number of entries */
+} __attribute__((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.
+
+
+4. 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:
+
+struct timestamp_entry {
+        uint32_t        entry_id;
+        uint64_t        entry_stamp;
+} __attribute__((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.
+
+
+========================== Internal Functions ==================================
+
+1. timestamp_cache_init
+	Initializes the timestamp cache to a known state by setting num_entries
+to 0, base_entries to MAX_TIMESTAMP_CACHE, base_time to caller-provided base,
+cache_state to TIMESTAMP_CACHE_INITIALIZED and cbmem_state to caller-provided
+state.
+
+
+2.  timestamp_cache_get
+	This function returns a pointer to timestamp cache. It basically
+identifies what cache to use based on following parameters:
+a. If __PRE_RAM__ is true i.e. we are in pre-ramstage step and _timestamp region
+is provided, use _timestamp region.
+b. Otherwise use local stash
+
+	If using _timestamp region, it ensures that the size of the region is
+big enough to hold all of timestamp_cache structure and MAX_TIMESTAMP_CACHE
+timestamp entries. Once the location of cache is decided, it checks to see if
+cache is not yet initialized, and calls timestamp_cache_init if required.
+
+
+3. timestamp_alloc_cbmem_table
+	This function exists only in romstage and ramstage since only these two
+stages access cbmem area. It allocates a new table for MAX_TIMESTAMPS number of
+entries in the cbmem area using CBMEM_ID_TIMESTAMP tag. It also resets the
+base_time and num_entries to 0.
+
+
+4. timestamp_table_get
+	This function returns a pointer to the timestamp table. Based on the
+value of cache_state in timestamp_cache, it provides a pointer either to the
+cache (in stash or _timestamp region) or the cbmem timestamp table. If a pointer
+to the cbmem timestamp table is returned, it checks to see if cbmem_state
+indicates a reset of the cbmem timestamp area. If required, it makes a call to
+timestamp_alloc_cbmem_table.
+
+
+5. timestamp_add_table_entry
+	This function adds a new entry to the timestamp table obtained by making
+a call to timestamp_table_get. It sets the id based on user-provided id and the
+stamp is set to user-provided time - table base time. This is to normalize all
+the timestamps.
+
+
+============================= Function APIs ====================================
+
+1. timestamp_early_init
+	It is essential to call this function only if _timestamp region is being
+used. This should be the first call made to the timestamp library. Since
+_timestamp region can contain arbitary values in the different fields of the
+cache, this function initializes the fields properly by calling
+timestamp_cache_init with the cache pointer, user-provided base time and
+cbmem_state as TIMESTAMP_CBMEM_RESET_REQD. This will provide an indication that
+cbmem timestamp area needs to be added (in case of fresh boot) or reset to 0
+entries(in case of resume).
+
+
+2. timestamp_init
+	It is essential to call this function before any call to timestamp_add
+is made. In case of _timestamp region being used, only a call to
+timestamp_early_init is required. In all other cases, it is essential to call
+timestamp_init to set the cbmem_state to TIMESTAMP_CBMEM_RESET_REQD. This will
+provide an indication that cbmem timestamp area needs to be added (in case of
+fresh boot) or reset to 0 entries(in case of resume).
+
+
+3. timestamp_add
+	This function accepts from user a timestamp id and time to record in the
+timestamp table. Based on the table provided by timestamp_table_get, it stores
+the entry in the appropriate table in cbmem or _timestamp region or local
+stash.
+
+
+4. timestamp_add_now
+	This function calls timestamp_add with user-provided id and current
+time.
+
+
+5. timestamp_sync
+	This is one of the most important functions required to ensure the
+proper functioning of the timestamp library across cbmem, _timestamp region and
+local stash with minimal interference for the user. It is important to note that
+this function is called only by cbmem_initialize to ensure that once the cbmem
+area is ready, we automatically sync all the timestamps saved in the cache to
+cbmem area. Thus, the user never has to call the timestamp_sync function.
+
+	This function checks to see if the cache state indicates that a cbmem
+reset of timestamp area is required or no timestamp area exists in cbmem at
+all. In that case, it allocates a new cbmem area by calling
+timestamp_alloc_cbmem_table.
+
+	Otherwise, it uses cbmem_find to use the timestamp area in cbmem. It
+then uses timestamp_add_table_entry to move all the entries from cache to cbmem
+area. Here, two cases can occur with respect to the base time subtraction:
+
+a. Newly added cbmem table will have a base time of 0. Thus, no adjustments are
+required for the timestamps being added from cache to cbmem table.
+
+b. Timestamps added to cache before ramstage: In this case, the base time in
+cache table will be 0 and timestamp_add_table_entry will take care of
+subtracting the correct base_time. Finally, it resets the timestamp cache to:
+
+        cache_state: TIMESTAMP_CACHE_NOT_NEEDED
+        cbmem_state: TIMESTAMP_CBMEM_RESET_NOT_REQD
+        num_entries: 0
+
+	Also, the base_time in cbmem table is update if it is currently zero
+indicating that it needs to inherit base time from cache table since
+cbmem table might be newly allocated.
+
+
+============================= 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)
+
+
+1. timestamp_early_init is called to setup the cache state and cbmem_state is
+set to reset_reqd. These properties are set in the timestamp cache which is part
+of _timestamp region.
+
+2. <Any number of timestamp_add / timestamp_add_now> : All saved in _timestamp
+region
+
+3. Once cbmem_initiliaze is complete, it calls timestamp_sync, which checks the
+_timestamp region to check the cbmem_state field. Since it says reset_reqd, a
+new area for timestamp is setup in cbmem by calling cbmem_add. The value of
+cbmem_state is set to reset_not_reqd in _timestamp region cache.
+
+4. After entering ramstage, the local stash acts as the timestamp cache. Since
+it is in BSS area, the cache_state field is set to uninitialized and cbmem_state
+field is set to reset_not_reqd.
+
+5. On any call to timestamp_add / timestamp_add_now, it initializes the cache
+and sets cache_state field to initialized whereas cbmem_state is still set to
+reset_not_reqd.
+
+6. Once cbmem_initiliaze is complete, it calls timestamp_sync, which checks the
+local stash to check the cbmem_state field. Since it says reset_not_reqd, it
+uses cbmem_find to find already allocated timestamp area in cbmem. If none is
+found, it allocates a new one.
+
+7. <Any number of calls to timestamp_add / timestamp_add_now> : All saved in
+cbmem
+
+
+Case 2: No timestamp region, fresh boot, cbmem_initialize called after
+timestamp_init
+
+1. Since timestamp_init is called before cbmem_initialize, it will set the cache
+field attributes to: cache_state as initialized and cbmem_state as
+reset_reqd. This ensures that timestamp_sync sets up a new cbmem area for
+timestamps.
+
+2. < Any number of calls to timestamp_add / timestamp_add_now> : All saved in
+stash
+
+3. Once cbmem_initiliaze is complete, it calls timestamp_sync, which checks the
+stash cache to check the cbmem_state field. Since it says reset_reqd, a new area
+for timestamp is setup in cbmem by calling cbmem_add. The value of cbmem_state
+is set to reset_not_reqd in stash cache.
+
+4. After entering ramstage, a new local stash acts as the timestamp cache. Since
+it is in BSS area, the cache_state field is set to uninitialized and cbmem_state
+field is set to reset_not_reqd.
+
+5. On any call to timestamp_add / timestamp_add_now, it initializes the cache
+and sets cache_state field to initialized whereas cbmem_state is still set to
+reset_not_reqd.
+
+6. Once cbmem_initiliaze is complete, it calls timestamp_sync, which checks the
+local stash to check the cbmem_state field. Since it says reset_not_reqd, it
+uses cbmem_find to find already allocated timestamp area in cbmem. If none is
+found, it allocates a new one.
+
+7. <Any number of calls to timestamp_add / timestamp_add_now> : All saved in
+cbmem
+
+
+Case 3: No timestamp region, fresh boot, cbmem_initialize called before
+timestamp_init
+
+1. Since cbmem_initialize is called before timestamp_init, it will call
+timestamp_sync which checks local stash to check for cbmem_state field. Since,
+cbmem_state says no_reset_reqd, it uses cbmem_find to look for a timestamp area
+in cbmem. Since, it is a fresh boot, none will be found and it uses cbmem_add to
+create a new area on cbmem.
+
+2. timestamp_init is called, which sets local cache state to reset required. It
+then calls timestamp_table_get which sees that cache_state is cache_not_needed
+and cbmem_state is reset_reqd. Thus, it calls timestamp_alloc_cbmem_table to
+reset the cbmem area which is as good as no change in the state of cbmem
+area. Then, the cbmem_state is set to reset_not_reqd.
+
+3. <Any number of calls to timestamp_add / timestamp_add_now> : All saved in
+cbmem
+
+4. After entering ramstage, a new local stash acts as the timestamp cache. Since
+it is in BSS area, the cache_state field is set to uninitialized and cbmem_state
+field is set to reset_not_reqd.
+
+5. On any call to timestamp_add / timestamp_add_now, it initializes the cache
+and sets cache_state field to initialized whereas cbmem_state is still set to
+reset_not_reqd.
+
+6. Once cbmem_initiliaze is complete, it calls timestamp_sync, which checks the
+local stash to check the cbmem_state field. Since it says reset_not_reqd, it
+uses cbmem_find to find already allocated timestamp area in cbmem. If none is
+found, it allocates a new one.
+
+7. <Any number of calls to timestamp_add / timestamp_add_now> : All saved in
+cbmem
+
+
+Case 4: No timestamp region, resume, cbmem_initialize called after
+timestamp_init
+
+1. Since timestamp_init is called before cbmem_initialize, it will set the cache
+field attributes to: cache_state as initialized and cbmem_state as reset_reqd.
+
+2. < Any number of calls to timestamp_add / timestamp_add_now> : All saved in
+stash
+
+3. Once cbmem_initiliaze is complete, it calls timestamp_sync, which checks the
+stash cache to check the cbmem_state field. Since it says reset_reqd,
+timestamp_sync resets cbmem area to num_entries=0, thus flushing timestamps from
+earlier boot. The value of cbmem_state is set to reset_not_reqd in stash cache.
+
+4. After entering ramstage, a new local stash acts as the timestamp cache. Since
+it is in BSS area, the cache_state field is set to uninitialized and cbmem_state
+field is set to reset_not_reqd.
+
+5. On any call to timestamp_add / timestamp_add_now, it initializes the cache
+and sets cache_state field to initialized whereas cbmem_state is still set to
+reset_not_reqd.
+
+6. Once cbmem_initiliaze is complete, it calls timestamp_sync, which checks the
+local stash to check the cbmem_state field. Since it says reset_not_reqd, it
+uses cbmem_find to find already allocated timestamp area in cbmem. If none is
+found, it allocates a new one.
+
+7. <Any number of calls to timestamp_add / timestamp_add_now> : All saved in
+cbmem
+
+
+Case 5: No timestamp region, resume, cbmem_initialize called before
+timestamp_init
+
+1. Since cbmem_initialize is called before timestamp_init, it will call
+timestamp_sync which checks local stash to check for cbmem_state field. Since,
+cbmem_state says no_reset_reqd, it uses cbmem_find to look for a timestamp area
+in cbmem. Since, it is resume, it will find the older cbmem timestamp area from
+earlier boot. However, nothing is added to cbmem area since timestamp_add /
+timestamp_add_now is expected to be used only after call to timestamp_init.
+
+2. timestamp_init is called, which sets local cache state to reset required. It
+then calls timestamp_table_get which sees that cache_state is cache_not_needed
+and cbmem_state is reset_reqd. Thus, it calls timestamp_alloc_cbmem_table to
+reset the cbmem area which sets num_entries to 0. Thus, flushing timestamps from
+earlier boot. Then, the cbmem_state is set to reset_not_reqd.
+
+3. <Any number of calls to timestamp_add / timestamp_add_now> : All saved in
+cbmem
+
+4. After entering ramstage, a new local stash acts as the timestamp cache. Since
+it is in BSS area, the cache_state field is set to uninitialized and cbmem_state
+field is set to reset_not_reqd.
+
+5. On any call to timestamp_add / timestamp_add_now, it initializes the cache
+and sets cache_state field to initialized whereas cbmem_state is still set to
+reset_not_reqd.
+
+6. Once cbmem_initiliaze is complete, it calls timestamp_sync, which checks the
+local stash to check the cbmem_state field. Since it says reset_not_reqd, it
+uses cbmem_find to find already allocated timestamp area in cbmem. If none is
+found, it allocates a new one.
+
+7. <Any number of calls to timestamp_add / timestamp_add_now> : All saved in
+cbmem



More information about the coreboot-gerrit mailing list