diff options
author | Shawn Nematbakhsh <shawnn@chromium.org> | 2017-08-01 17:59:21 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-08-02 15:02:34 -0700 |
commit | ec99f3913791bfe1935735ddcda18bd29ffcfd18 (patch) | |
tree | 0b75a5b223870dc29d9dafef419b7462337f8516 /common/pd_log.c | |
parent | 7ed19ed220b795f9bc28832e7bddb891c383b4b2 (diff) | |
download | chrome-ec-ec99f3913791bfe1935735ddcda18bd29ffcfd18.tar.gz |
pd_log: Make PD logging more generic for general purpose logging
We can re-use our pd_log FIFO for other purposes, such as TPM logging.
Carve out event_log, a generic logging module which pd_log is compatible
with.
BUG=b:63760920
TEST=On kevin, verify PD logging is still functional and entries are
seen in dmesg.
BRANCH=None
Change-Id: I8e6ad6f93e9eebc676aca64652c60f81da471a94
Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/597314
Commit-Ready: Shawn N <shawnn@chromium.org>
Tested-by: Shawn N <shawnn@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'common/pd_log.c')
-rw-r--r-- | common/pd_log.c | 125 |
1 files changed, 10 insertions, 115 deletions
diff --git a/common/pd_log.c b/common/pd_log.c index 2acf7bf8f7..f0e9312117 100644 --- a/common/pd_log.c +++ b/common/pd_log.c @@ -5,87 +5,21 @@ #include "charge_manager.h" #include "console.h" -#include "hooks.h" +#include "event_log.h" #include "host_command.h" -#include "task.h" #include "timer.h" #include "usb_pd.h" #include "util.h" -/* Event log FIFO */ -#define UNIT_SIZE sizeof(struct ec_response_pd_log) -#define LOG_SIZE (CONFIG_USB_PD_LOG_SIZE/UNIT_SIZE) -static struct ec_response_pd_log __bss_slow log_events[LOG_SIZE]; -BUILD_ASSERT(POWER_OF_TWO(LOG_SIZE)); /* - * 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 - * pd_log_event(). Only one task is dequeuing events (host commands or VDM). - * When the FIFO is full, pd_log_event() will discard the oldest events, - * so "log_head" is incremented/decremented in a critical section since it is - * accessed from both pd_log_event() and pd_log_dequeue(). - * 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 pd_log_dequeue(). + * Ensure PD logging parameters are compatible with the generic logging + * framework that we're calling into. */ -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)) - -static void log_add_event(uint8_t type, uint8_t size_port, uint16_t data, - void *payload, uint32_t timestamp) -{ - struct ec_response_pd_log *r; - size_t payload_size = PD_LOG_SIZE(size_port); - size_t total_size = ENTRY_SIZE(payload_size); - size_t current_tail, first; - - /* --- critical section : reserve queue space --- */ - interrupt_disable(); - current_tail = log_tail_next; - log_tail_next = current_tail + total_size; - interrupt_enable(); - /* --- end of critical section --- */ - - /* Out of space : discard the oldest entry */ - while ((LOG_SIZE - (current_tail - log_head)) < total_size) { - struct ec_response_pd_log *oldest; - /* --- critical section : atomically free-up space --- */ - interrupt_disable(); - oldest = log_events + (log_head & (LOG_SIZE - 1)); - log_head += ENTRY_SIZE(PD_LOG_SIZE(oldest->size_port)); - interrupt_enable(); - /* --- end of critical section --- */ - } - - r = log_events + (current_tail & (LOG_SIZE - 1)); - - r->timestamp = timestamp; - r->type = type; - r->size_port = size_port; - r->data = data; - /* copy the payload into the FIFO */ - first = MIN(total_size - 1, (LOG_SIZE - - (current_tail & (LOG_SIZE - 1))) - 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; -} +BUILD_ASSERT(sizeof(struct ec_response_pd_log) == + sizeof(struct event_log_entry)); +BUILD_ASSERT(PD_LOG_SIZE_MASK == EVENT_LOG_SIZE_MASK); +BUILD_ASSERT(PD_LOG_TIMESTAMP_SHIFT == EVENT_LOG_TIMESTAMP_SHIFT); +BUILD_ASSERT(PD_EVENT_NO_ENTRY == EVENT_LOG_NO_ENTRY); void pd_log_event(uint8_t type, uint8_t size_port, uint16_t data, void *payload) @@ -95,45 +29,6 @@ void pd_log_event(uint8_t type, uint8_t size_port, log_add_event(type, size_port, data, payload, timestamp); } -static int pd_log_dequeue(struct ec_response_pd_log *r) -{ - uint32_t now = get_time().val >> PD_LOG_TIMESTAMP_SHIFT; - unsigned total_size, first; - struct ec_response_pd_log *entry; - size_t current_head; - -retry: - current_head = log_head; - /* The log FIFO is empty */ - if (log_tail == current_head) { - memset(r, 0, UNIT_SIZE); - r->type = PD_EVENT_NO_ENTRY; - return UNIT_SIZE; - } - - entry = log_events + (current_head & (LOG_SIZE - 1)); - total_size = ENTRY_SIZE(PD_LOG_SIZE(entry->size_port)); - first = MIN(total_size, LOG_SIZE - (current_head & (LOG_SIZE - 1))); - 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 --- */ - interrupt_disable(); - if (log_head != current_head) { /* our entry was thrown away */ - interrupt_enable(); - goto retry; - } - log_head += total_size; - interrupt_enable(); - /* --- end of critical section --- */ - - /* fixup the timestamp : number of milliseconds in the past */ - r->timestamp = now - r->timestamp; - - return total_size * UNIT_SIZE; -} - #ifdef HAS_TASK_HOSTCMD /* number of accessory entries we have queued since last check */ @@ -168,7 +63,7 @@ static int hc_pd_get_log_entry(struct host_cmd_handler_args *args) struct ec_response_pd_log *r = args->response; dequeue_retry: - args->response_size = pd_log_dequeue(r); + args->response_size = log_dequeue_event((struct event_log_entry *)r); /* if the MCU log no longer has entries, try connected accessories */ if (r->type == PD_EVENT_NO_ENTRY) { int i, res; @@ -230,7 +125,7 @@ int pd_vdm_get_log_entry(uint32_t *payload) struct ec_response_pd_log *r = (void *)&payload[1]; int byte_size; - byte_size = pd_log_dequeue(r); + byte_size = log_dequeue_event((struct event_log_entry *)r); return 1 + DIV_ROUND_UP(byte_size, sizeof(uint32_t)); } |