timestamp: Keep the timestamp table in the FWDB.
Change-Id: Ie1cb4e79a2f0f47947c6619a243f835d6fd32a22
diff --git a/src/arch/x86/amd64/handoff/uefi.c b/src/arch/x86/amd64/handoff/uefi.c
index 051e793..b667720 100644
--- a/src/arch/x86/amd64/handoff/uefi.c
+++ b/src/arch/x86/amd64/handoff/uefi.c
@@ -25,6 +25,7 @@
#include "arch/x86/amd64/handoff/handoff.h"
#include "base/fwdb.h"
#include "base/memory.h"
+#include "base/timestamp.h"
#include "uefi/uefi.h"
extern EFI_SYSTEM_TABLE *_uefi_handoff_system_table;
diff --git a/src/base/Kconfig b/src/base/Kconfig
index d91d372..778d71c 100644
--- a/src/base/Kconfig
+++ b/src/base/Kconfig
@@ -27,3 +27,7 @@
config MAX_MEM_RANGES
int "Max number of memory ranges"
default 32
+
+config MAX_TIMESTAMPS
+ int "Max number of timestamps in the timestamp table"
+ default 60
diff --git a/src/base/timestamp.c b/src/base/timestamp.c
index 71aef04..da0979d 100644
--- a/src/base/timestamp.c
+++ b/src/base/timestamp.c
@@ -16,49 +16,83 @@
*/
#include <stdint.h>
+#include <stdio.h>
#include <sysinfo.h>
+#include "base/fwdb.h"
#include "base/init_funcs.h"
#include "base/time.h"
#include "base/timestamp.h"
#include "drivers/timer/timer.h"
-struct timestamp_entry {
- uint32_t entry_id;
- uint64_t entry_stamp;
-} __attribute__((packed));
+static TimestampTable *timestamp_table;
-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));
-
-static struct timestamp_table *ts_table;
-
-static int timestamp_init(void)
+static int timestamp_table_max_entries(TimestampTable *table, size_t size)
{
- ts_table = get_sysinfo()->tstamp_table;
+ size_t entries_size = size - offsetof(TimestampTable, entries);
+ return entries_size / sizeof(TimestampEntry);
+}
+
+static void timestamp_table_init(TimestampTable *table, size_t size)
+{
+ table->base_time = 0;
+ table->max_entries = timestamp_table_max_entries(table, size);
+ table->num_entries = 0;
+}
+
+static int timestamp_table_install(void)
+{
+ if (timestamp_table) {
+ printf("Timestamp table is already initialized.\n");
+ return 1;
+ }
+
+ FwdbEntry default_entry = {
+ .size = offsetof(TimestampTable, entries) +
+ CONFIG_MAX_TIMESTAMPS * sizeof(TimestampEntry),
+ };
+ FwdbEntry entry;
+ if (fwdb_access("timestamp table", &entry, &default_entry))
+ return 1;
+ TimestampTable *table = (TimestampTable *)entry.ptr;
+ if (!table->max_entries)
+ timestamp_table_init(table, entry.size);
+
+ int max_entries = timestamp_table_max_entries(table, entry.size);
+ if (table->max_entries > max_entries) {
+ printf("Timestamp table max entries too high.\n");
+ return 1;
+ }
+
+ if (table->num_entries > table->max_entries) {
+ printf("Timestamp table over filled.\n");
+ return 1;
+ }
+
+ timestamp_table = table;
+
timestamp_add_now(TS_START);
return 0;
}
-INIT_FUNC_TIMESTAMP(timestamp_init)
+INIT_FUNC_TIMESTAMP(timestamp_table_install)
-void timestamp_add(enum timestamp_id id, uint64_t ts_time)
+void timestamp_add(TimestampId id, uint64_t time)
{
- struct timestamp_entry *tse;
+ TimestampEntry *tse;
- if (!ts_table || (ts_table->num_entries == ts_table->max_entries))
+ if (!timestamp_table ||
+ (timestamp_table->num_entries ==
+ timestamp_table->max_entries)) {
return;
+ }
- tse = &ts_table->entries[ts_table->num_entries++];
- tse->entry_id = id;
- tse->entry_stamp = ts_time - ts_table->base_time;
+ tse = ×tamp_table->entries[timestamp_table->num_entries++];
+ tse->id = id;
+ tse->stamp = time - timestamp_table->base_time;
}
-void timestamp_add_now(enum timestamp_id id)
+void timestamp_add_now(TimestampId id)
{
if (CONFIG_TIMESTAMP_RAW)
timestamp_add(id, timer_raw_value());
diff --git a/src/base/timestamp.h b/src/base/timestamp.h
index 045dedf..aee7b73 100644
--- a/src/base/timestamp.h
+++ b/src/base/timestamp.h
@@ -20,7 +20,19 @@
#include <stdint.h>
-enum timestamp_id {
+typedef struct __attribute__((packed)) {
+ uint32_t id;
+ uint64_t stamp;
+} TimestampEntry;
+
+typedef struct __attribute__((packed)) {
+ uint64_t base_time;
+ uint32_t max_entries;
+ uint32_t num_entries;
+ TimestampEntry entries[0]; // Variable number of entries.
+} TimestampTable;
+
+typedef enum {
// Depthcharge entry IDs start at 1000.
TS_START = 1000,
@@ -37,9 +49,9 @@
TS_CROSSYSTEM_DATA = 1100,
TS_START_KERNEL = 1101
-};
+} TimestampId;
-void timestamp_add(enum timestamp_id id, uint64_t ts_time);
-void timestamp_add_now(enum timestamp_id id);
+void timestamp_add(TimestampId id, uint64_t time);
+void timestamp_add_now(TimestampId id);
#endif /* __BASE_TIMESTAMP_H__ */
diff --git a/src/module/handoff/coreboot.c b/src/module/handoff/coreboot.c
index bf8731e..28fa042 100644
--- a/src/module/handoff/coreboot.c
+++ b/src/module/handoff/coreboot.c
@@ -34,6 +34,7 @@
#include "base/fwdb.h"
#include "base/memory.h"
+#include "base/timestamp.h"
#include "drivers/framebuffer/framebuffer.h"
#include "vboot/util/vboot_handoff.h"
@@ -150,6 +151,14 @@
{
struct cb_cbmem_tab *const cbmem = (struct cb_cbmem_tab *)ptr;
info->tstamp_table = (void *)(uintptr_t)cbmem->cbmem_tab;
+
+ TimestampTable *table = (void *)(uintptr_t)cbmem->cbmem_tab;
+ FwdbEntry timestamp_table_entry = {
+ .ptr = table,
+ .size = offsetof(TimestampTable, entries) +
+ table->max_entries * sizeof(TimestampEntry),
+ };
+ fwdb_access("timestamp table", NULL, ×tamp_table_entry);
}
static void cb_parse_cbmem_cons(unsigned char *ptr, struct sysinfo_t *info)