diff options
Diffstat (limited to 'common/event_log.c')
-rw-r--r-- | common/event_log.c | 186 |
1 files changed, 0 insertions, 186 deletions
diff --git a/common/event_log.c b/common/event_log.c deleted file mode 100644 index 95e44413bc..0000000000 --- a/common/event_log.c +++ /dev/null @@ -1,186 +0,0 @@ -/* Copyright 2017 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "common.h" -#include "console.h" -#include "event_log.h" -#include "hooks.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -/* Event log FIFO */ -#define UNIT_SIZE sizeof(struct event_log_entry) -#define UNIT_COUNT (CONFIG_EVENT_LOG_SIZE/UNIT_SIZE) -#define UNIT_COUNT_MASK (UNIT_COUNT - 1) -static struct event_log_entry __bss_slow log_events[UNIT_COUNT]; -BUILD_ASSERT(POWER_OF_TWO(UNIT_COUNT)); - -/* - * The FIFO pointers are defined as following : - * "log_head" is the next available event to dequeue. - * "log_tail" is marking the end of the FIFO content (after last committed - * event) - * "log_tail_next" is the next available spot to enqueue events. - * The pointers are not wrapped until they are used, so we don't need an extra - * entry to disambiguate between full and empty FIFO. - * - * For concurrency, several tasks might try to enqueue events in parallel with - * log_add_event(). Only one task is dequeuing events (host commands, VDM, - * TPM command handler). When the FIFO is full, log_add_event() will discard - * the oldest events, so "log_head" is incremented/decremented in a critical - * section since it is accessed from both log_add_event() and - * log_dequeue_event(). log_tail_next is also protected as several writers can - * race to add an event to the queue. - * When a writer is done adding its event, it is updating log_tail, - * so the event can be consumed by log_dequeue_event(). - */ -static size_t log_head; -static size_t log_tail; -static size_t log_tail_next; - -/* Size of one FIFO entry */ -#define ENTRY_SIZE(payload_sz) (1+DIV_ROUND_UP((payload_sz), UNIT_SIZE)) - -void log_add_event(uint8_t type, uint8_t size, uint16_t data, - void *payload, uint32_t timestamp) -{ - struct event_log_entry *r; - size_t payload_size = EVENT_LOG_SIZE(size); - size_t total_size = ENTRY_SIZE(payload_size); - size_t current_tail, first; - uint32_t lock_key; - - /* --- critical section : reserve queue space --- */ - lock_key = irq_lock(); - current_tail = log_tail_next; - log_tail_next = current_tail + total_size; - irq_unlock(lock_key); - /* --- end of critical section --- */ - - /* Out of space : discard the oldest entry */ - while ((UNIT_COUNT - (current_tail - log_head)) < total_size) { - struct event_log_entry *oldest; - /* --- critical section : atomically free-up space --- */ - lock_key = irq_lock(); - oldest = log_events + (log_head & UNIT_COUNT_MASK); - log_head += ENTRY_SIZE(EVENT_LOG_SIZE(oldest->size)); - irq_unlock(lock_key); - /* --- end of critical section --- */ - } - - r = log_events + (current_tail & UNIT_COUNT_MASK); - - r->timestamp = timestamp; - r->type = type; - r->size = size; - r->data = data; - /* copy the payload into the FIFO */ - first = MIN(total_size - 1, (UNIT_COUNT - - (current_tail & UNIT_COUNT_MASK)) - 1); - if (first) - memcpy(r->payload, payload, first * UNIT_SIZE); - if (first < total_size - 1) - memcpy(log_events, ((uint8_t *)payload) + first * UNIT_SIZE, - (total_size - first) * UNIT_SIZE); - /* mark the entry available in the queue if nobody is behind us */ - if (current_tail == log_tail) - log_tail = log_tail_next; -} - -int log_dequeue_event(struct event_log_entry *r) -{ - uint32_t now = get_time().val >> EVENT_LOG_TIMESTAMP_SHIFT; - unsigned int total_size, first; - struct event_log_entry *entry; - size_t current_head; - uint32_t lock_key; - -retry: - current_head = log_head; - /* The log FIFO is empty */ - if (log_tail == current_head) { - memset(r, 0, UNIT_SIZE); - r->type = EVENT_LOG_NO_ENTRY; - return UNIT_SIZE; - } - - entry = log_events + (current_head & UNIT_COUNT_MASK); - total_size = ENTRY_SIZE(EVENT_LOG_SIZE(entry->size)); - first = MIN(total_size, UNIT_COUNT - (current_head & UNIT_COUNT_MASK)); - memcpy(r, entry, first * UNIT_SIZE); - if (first < total_size) - memcpy(r + first, log_events, (total_size-first) * UNIT_SIZE); - - /* --- critical section : remove the entry from the queue --- */ - lock_key = irq_lock(); - if (log_head != current_head) { /* our entry was thrown away */ - irq_unlock(lock_key); - goto retry; - } - log_head += total_size; - irq_unlock(lock_key); - /* --- end of critical section --- */ - - /* fixup the timestamp : number of milliseconds in the past */ - r->timestamp = now - r->timestamp; - - return total_size * UNIT_SIZE; -} - -#ifdef CONFIG_CMD_DLOG -/* - * Display TPM event logs. - */ -static int command_dlog(int argc, char **argv) -{ - size_t log_cur; - const uint8_t * const log_events_end = - (uint8_t *)&log_events[UNIT_COUNT]; - - if (argc > 1) { - if (!strcasecmp(argv[1], "clear")) { - interrupt_disable(); - log_head = log_tail = log_tail_next = 0; - interrupt_enable(); - - return EC_SUCCESS; - } - /* Too many parameters */ - return EC_ERROR_PARAM1; - } - - ccprintf(" TIMESTAMP | TYPE | DATA | SIZE | PAYLOAD\n"); - log_cur = log_head; - while (log_cur != log_tail) { - struct event_log_entry *r; - uint8_t *payload; - uint32_t payload_bytes; - - r = &log_events[log_cur & UNIT_COUNT_MASK]; - payload_bytes = EVENT_LOG_SIZE(r->size); - log_cur += ENTRY_SIZE(payload_bytes); - - ccprintf("%10d %4d 0x%04X %4d ", r->timestamp, r->type, - r->data, payload_bytes); - - /* display payload if exists */ - payload = r->payload; - while (payload_bytes--) { - if (payload >= log_events_end) - payload = (uint8_t *)&log_events[0]; - - ccprintf("%02X", *payload); - payload++; - } - ccprintf("\n"); - } - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(dlog, - command_dlog, - "[clear]", - "Display/clear TPM event logs"); -#endif |