summaryrefslogtreecommitdiff
path: root/common/pd_log.c
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2017-08-01 17:59:21 -0700
committerchrome-bot <chrome-bot@chromium.org>2017-08-02 15:02:34 -0700
commitec99f3913791bfe1935735ddcda18bd29ffcfd18 (patch)
tree0b75a5b223870dc29d9dafef419b7462337f8516 /common/pd_log.c
parent7ed19ed220b795f9bc28832e7bddb891c383b4b2 (diff)
downloadchrome-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.c125
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));
}