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 | |
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>
-rw-r--r-- | board/chell/board.h | 1 | ||||
-rw-r--r-- | board/coral/board.h | 1 | ||||
-rw-r--r-- | board/dingdong/board.h | 3 | ||||
-rw-r--r-- | board/elm/board.h | 1 | ||||
-rw-r--r-- | board/eve/board.h | 1 | ||||
-rw-r--r-- | board/fizz/board.h | 1 | ||||
-rw-r--r-- | board/glados/board.h | 1 | ||||
-rw-r--r-- | board/hoho/board.h | 3 | ||||
-rw-r--r-- | board/kahlee/board.h | 1 | ||||
-rw-r--r-- | board/kevin/board.h | 1 | ||||
-rw-r--r-- | board/nefario/board.h | 1 | ||||
-rw-r--r-- | board/oak/board.h | 1 | ||||
-rw-r--r-- | board/poppy/board.h | 1 | ||||
-rw-r--r-- | board/reef/board.h | 1 | ||||
-rw-r--r-- | board/reef_it8320/board.h | 1 | ||||
-rw-r--r-- | board/rowan/board.h | 1 | ||||
-rw-r--r-- | board/ryu/board.h | 1 | ||||
-rw-r--r-- | board/samus_pd/board.h | 1 | ||||
-rw-r--r-- | board/scarlet/board.h | 1 | ||||
-rw-r--r-- | board/wheatley/board.h | 1 | ||||
-rw-r--r-- | board/zinger/board.h | 3 | ||||
-rw-r--r-- | board/zoombini/board.h | 1 | ||||
-rw-r--r-- | common/build.mk | 2 | ||||
-rw-r--r-- | common/event_log.c | 127 | ||||
-rw-r--r-- | common/pd_log.c | 125 | ||||
-rw-r--r-- | include/config.h | 4 | ||||
-rw-r--r-- | include/ec_commands.h | 6 | ||||
-rw-r--r-- | include/event_log.h | 35 |
28 files changed, 186 insertions, 141 deletions
diff --git a/board/chell/board.h b/board/chell/board.h index 4c73cc6c64..3bfdd273e9 100644 --- a/board/chell/board.h +++ b/board/chell/board.h @@ -77,7 +77,6 @@ #define CONFIG_USB_PD_CUSTOM_VDM #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 512 #define CONFIG_USB_PD_PORT_COUNT 2 #define CONFIG_USB_PD_TCPM_TCPCI #define CONFIG_USB_PD_TRY_SRC diff --git a/board/coral/board.h b/board/coral/board.h index db6ccf0ace..ff4dc0dfb3 100644 --- a/board/coral/board.h +++ b/board/coral/board.h @@ -83,7 +83,6 @@ #define CONFIG_USB_PD_DISCHARGE #define CONFIG_USB_PD_DISCHARGE_TCPC #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 512 #define CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT TYPEC_RP_3A0 #define CONFIG_USB_PD_PORT_COUNT 2 #define CONFIG_USB_PD_QUIRK_SLOW_CC_STATUS diff --git a/board/dingdong/board.h b/board/dingdong/board.h index 5f22ef5b08..dc134f6507 100644 --- a/board/dingdong/board.h +++ b/board/dingdong/board.h @@ -38,7 +38,8 @@ #define CONFIG_USB_PD_IDENTITY_SW_VERS 1 #define CONFIG_USB_PD_VBUS_DETECT_NONE #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 256 +#undef CONFIG_EVENT_LOG_SIZE +#define CONFIG_EVENT_LOG_SIZE 256 #define CONFIG_USB_PD_PORT_COUNT 1 #define CONFIG_USB_PD_TCPC #define CONFIG_USB_PD_TCPM_STUB diff --git a/board/elm/board.h b/board/elm/board.h index 5fda2789a4..7df3c18c57 100644 --- a/board/elm/board.h +++ b/board/elm/board.h @@ -93,7 +93,6 @@ #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 512 #define CONFIG_USB_PD_PORT_COUNT 1 #define CONFIG_USB_PD_TCPM_MUX diff --git a/board/eve/board.h b/board/eve/board.h index 538b20371c..705b12efed 100644 --- a/board/eve/board.h +++ b/board/eve/board.h @@ -162,7 +162,6 @@ #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 512 #define CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT TYPEC_RP_3A0 #define CONFIG_USB_PD_PORT_COUNT 2 #define CONFIG_USB_PD_QUIRK_SLOW_CC_STATUS diff --git a/board/fizz/board.h b/board/fizz/board.h index 991b906b08..81930d204d 100644 --- a/board/fizz/board.h +++ b/board/fizz/board.h @@ -95,7 +95,6 @@ #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 512 #define CONFIG_USB_PD_PORT_COUNT 1 #define CONFIG_USB_PD_QUIRK_SLOW_CC_STATUS #define CONFIG_USB_PD_VBUS_DETECT_GPIO diff --git a/board/glados/board.h b/board/glados/board.h index 1017ae8721..4ed3186b06 100644 --- a/board/glados/board.h +++ b/board/glados/board.h @@ -77,7 +77,6 @@ #define CONFIG_USB_PD_CUSTOM_VDM #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 512 #define CONFIG_USB_PD_PORT_COUNT 2 #define CONFIG_USB_PD_TCPM_TCPCI #define CONFIG_USB_PD_TRY_SRC diff --git a/board/hoho/board.h b/board/hoho/board.h index 79f769ae0e..748f777499 100644 --- a/board/hoho/board.h +++ b/board/hoho/board.h @@ -43,7 +43,8 @@ #define CONFIG_USB_PD_IDENTITY_HW_VERS 1 #define CONFIG_USB_PD_IDENTITY_SW_VERS 1 #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 256 +#undef CONFIG_EVENT_LOG_SIZE +#define CONFIG_EVENT_LOG_SIZE 256 #define CONFIG_USB_PD_PORT_COUNT 1 #define CONFIG_USB_PD_TCPC #define CONFIG_USB_PD_TCPM_STUB diff --git a/board/kahlee/board.h b/board/kahlee/board.h index 5012c0b3a0..7fc9c8e33c 100644 --- a/board/kahlee/board.h +++ b/board/kahlee/board.h @@ -67,7 +67,6 @@ #define CONFIG_USB_PD_DISCHARGE #define CONFIG_USB_PD_DISCHARGE_TCPC #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 512 #define CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT TYPEC_RP_3A0 #define CONFIG_USB_PD_PORT_COUNT 2 #define CONFIG_USB_PD_QUIRK_SLOW_CC_STATUS diff --git a/board/kevin/board.h b/board/kevin/board.h index 7b4e6e3024..199cdee103 100644 --- a/board/kevin/board.h +++ b/board/kevin/board.h @@ -126,7 +126,6 @@ #define CONFIG_USB_PD_DISCHARGE_GPIO #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 512 #define CONFIG_USB_PD_PORT_COUNT 2 #define CONFIG_USB_PD_TCPM_FUSB302 #define CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT TYPEC_RP_3A0 diff --git a/board/nefario/board.h b/board/nefario/board.h index 5332b1dc1f..636b392a6f 100644 --- a/board/nefario/board.h +++ b/board/nefario/board.h @@ -114,7 +114,6 @@ #define CONFIG_USB_PD_DISCHARGE_GPIO #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 512 #define CONFIG_USB_PD_PORT_COUNT 2 #define CONFIG_USB_PD_TCPM_FUSB302 #define CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT TYPEC_RP_3A0 diff --git a/board/oak/board.h b/board/oak/board.h index 61eeebf703..432b1454d1 100644 --- a/board/oak/board.h +++ b/board/oak/board.h @@ -97,7 +97,6 @@ #define CONFIG_USB_PD_CUSTOM_VDM #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 512 #define CONFIG_USB_PD_PORT_COUNT 2 #define CONFIG_USB_PD_TCPM_TCPCI #define CONFIG_USB_PD_TRY_SRC diff --git a/board/poppy/board.h b/board/poppy/board.h index 841ce21bf2..5fda50466c 100644 --- a/board/poppy/board.h +++ b/board/poppy/board.h @@ -143,7 +143,6 @@ #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 512 #define CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT TYPEC_RP_3A0 #define CONFIG_USB_PD_PORT_COUNT 2 #define CONFIG_USB_PD_QUIRK_SLOW_CC_STATUS diff --git a/board/reef/board.h b/board/reef/board.h index b9b613d654..f2af983408 100644 --- a/board/reef/board.h +++ b/board/reef/board.h @@ -86,7 +86,6 @@ #define CONFIG_USB_PD_DISCHARGE #define CONFIG_USB_PD_DISCHARGE_TCPC #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 512 #define CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT TYPEC_RP_3A0 #define CONFIG_USB_PD_PORT_COUNT 2 #define CONFIG_USB_PD_QUIRK_SLOW_CC_STATUS diff --git a/board/reef_it8320/board.h b/board/reef_it8320/board.h index 67066a0675..fb308a0cca 100644 --- a/board/reef_it8320/board.h +++ b/board/reef_it8320/board.h @@ -75,7 +75,6 @@ #define CONFIG_USB_PD_DISCHARGE #define CONFIG_USB_PD_DISCHARGE_GPIO #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 512 #define CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT TYPEC_RP_3A0 #define CONFIG_USB_PD_PORT_COUNT 2 #define CONFIG_USB_PD_QUIRK_SLOW_CC_STATUS diff --git a/board/rowan/board.h b/board/rowan/board.h index 859d9a3cb3..12d4e382c8 100644 --- a/board/rowan/board.h +++ b/board/rowan/board.h @@ -97,7 +97,6 @@ #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 512 #define CONFIG_USB_PD_PORT_COUNT 1 #define CONFIG_USB_PD_TCPM_MUX diff --git a/board/ryu/board.h b/board/ryu/board.h index 390086cdec..1aec3945fa 100644 --- a/board/ryu/board.h +++ b/board/ryu/board.h @@ -42,7 +42,6 @@ #define CONFIG_USB_PD_FLASH_ERASE_CHECK #define CONFIG_USB_PD_INTERNAL_COMP #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 512 #define CONFIG_USB_PD_LOW_POWER #define CONFIG_USB_PD_PORT_COUNT 1 #define CONFIG_USB_PD_TCPC diff --git a/board/samus_pd/board.h b/board/samus_pd/board.h index 36938bda0c..e85fb61a1b 100644 --- a/board/samus_pd/board.h +++ b/board/samus_pd/board.h @@ -60,7 +60,6 @@ #define CONFIG_USB_PD_FLASH_ERASE_CHECK #define CONFIG_USB_PD_INTERNAL_COMP #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 512 #define CONFIG_USB_PD_PORT_COUNT 2 #define CONFIG_USB_PD_TCPC #define CONFIG_USB_PD_TCPM_STUB diff --git a/board/scarlet/board.h b/board/scarlet/board.h index bc3810f7ad..dafe40a5de 100644 --- a/board/scarlet/board.h +++ b/board/scarlet/board.h @@ -97,7 +97,6 @@ #define CONFIG_USB_PD_DISCHARGE_GPIO #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 512 #define CONFIG_USB_PD_PORT_COUNT 1 #define CONFIG_USB_PD_TCPM_FUSB302 #define CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT TYPEC_RP_3A0 diff --git a/board/wheatley/board.h b/board/wheatley/board.h index 18ec83897b..4c5fdbd55f 100644 --- a/board/wheatley/board.h +++ b/board/wheatley/board.h @@ -76,7 +76,6 @@ #define CONFIG_USB_PD_CUSTOM_VDM #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 512 #define CONFIG_USB_PD_PORT_COUNT 2 #define CONFIG_USB_PD_TCPM_TCPCI #define CONFIG_USB_PD_TRY_SRC diff --git a/board/zinger/board.h b/board/zinger/board.h index 1b11447614..b8480f7328 100644 --- a/board/zinger/board.h +++ b/board/zinger/board.h @@ -58,7 +58,8 @@ #undef CONFIG_USB_PD_DUAL_ROLE #undef CONFIG_USB_PD_INTERNAL_COMP #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 256 +#undef CONFIG_EVENT_LOG_SIZE +#define CONFIG_EVENT_LOG_SIZE 256 #define CONFIG_USB_PD_LOW_POWER_IDLE_WHEN_CONNECTED #define CONFIG_USB_PD_PORT_COUNT 1 #define CONFIG_USB_PD_TCPC diff --git a/board/zoombini/board.h b/board/zoombini/board.h index 966fbce42d..f76595ea11 100644 --- a/board/zoombini/board.h +++ b/board/zoombini/board.h @@ -70,7 +70,6 @@ #define CONFIG_USB_PD_PORT_COUNT 3 #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_LOG_SIZE 512 /* TODO(aaboagye): What about CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT? */ #define CONFIG_USB_PD_VBUS_DETECT_TCPC #define CONFIG_USB_PD_TCPM_PS8805 diff --git a/common/build.mk b/common/build.mk index d533f8fb9b..1d6d16f812 100644 --- a/common/build.mk +++ b/common/build.mk @@ -113,7 +113,7 @@ common-$(CONFIG_USB_CHARGER)+=usb_charger.o common-$(CONFIG_USB_PORT_POWER_DUMB)+=usb_port_power_dumb.o common-$(CONFIG_USB_PORT_POWER_SMART)+=usb_port_power_smart.o common-$(CONFIG_USB_POWER_DELIVERY)+=usb_pd_protocol.o usb_pd_policy.o -common-$(CONFIG_USB_PD_LOGGING)+=pd_log.o +common-$(CONFIG_USB_PD_LOGGING)+=event_log.o pd_log.o common-$(CONFIG_USB_PD_TCPC)+=usb_pd_tcpc.o common-$(CONFIG_USB_UPDATE)+=usb_update.o update_fw.o common-$(CONFIG_VBOOT_EC)+=vboot/vboot.o diff --git a/common/event_log.c b/common/event_log.c new file mode 100644 index 0000000000..8da9c31ceb --- /dev/null +++ b/common/event_log.c @@ -0,0 +1,127 @@ +/* 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 "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 LOG_SIZE (CONFIG_EVENT_LOG_SIZE/UNIT_SIZE) +static struct event_log_entry __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 + * 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; + + /* --- 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 event_log_entry *oldest; + /* --- critical section : atomically free-up space --- */ + interrupt_disable(); + oldest = log_events + (log_head & (LOG_SIZE - 1)); + log_head += ENTRY_SIZE(EVENT_LOG_SIZE(oldest->size)); + interrupt_enable(); + /* --- end of critical section --- */ + } + + r = log_events + (current_tail & (LOG_SIZE - 1)); + + r->timestamp = timestamp; + r->type = type; + r->size = size; + 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; +} + +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; + +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 & (LOG_SIZE - 1)); + total_size = ENTRY_SIZE(EVENT_LOG_SIZE(entry->size)); + 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; +} 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)); } diff --git a/include/config.h b/include/config.h index 5f3b4c0bcb..c241fb2657 100644 --- a/include/config.h +++ b/include/config.h @@ -2445,8 +2445,8 @@ /* Record main PD events in a circular buffer */ #undef CONFIG_USB_PD_LOGGING -/* The size in bytes of the FIFO used for PD events logging */ -#undef CONFIG_USB_PD_LOG_SIZE +/* The size in bytes of the FIFO used for event logging */ +#define CONFIG_EVENT_LOG_SIZE 512 /* Save power by waking up on VBUS rather than polling CC */ #define CONFIG_USB_PD_LOW_POWER diff --git a/include/ec_commands.h b/include/ec_commands.h index 30427dfafa..67d026118f 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -4041,7 +4041,11 @@ struct __ec_align2 ec_params_charge_port_override { int16_t override_port; /* Override port# */ }; -/* Read (and delete) one entry of PD event log */ +/* + * Read (and delete) one entry of PD event log. + * TODO(crbug.com/751742): Make this host command more generic to accommodate + * future non-PD logs that use the same internal EC event_log. + */ #define EC_CMD_PD_GET_LOG_ENTRY 0x0115 struct __ec_align4 ec_response_pd_log { diff --git a/include/event_log.h b/include/event_log.h new file mode 100644 index 0000000000..45b10a3a2d --- /dev/null +++ b/include/event_log.h @@ -0,0 +1,35 @@ +/* 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. + */ + +#ifndef __CROS_EC_EVENT_LOG_H +#define __CROS_EC_EVENT_LOG_H + +struct event_log_entry { + uint32_t timestamp; /* relative timestamp in milliseconds */ + uint8_t type; /* event type, caller-defined */ + uint8_t size; /* [7:5] caller-def'd [4:0] payload size in bytes */ + uint16_t data; /* type-defined data payload */ + uint8_t payload[0]; /* optional additional data payload: 0..16 bytes */ +} __packed; + +#define EVENT_LOG_SIZE_MASK 0x1f +#define EVENT_LOG_SIZE(size) ((size) & EVENT_LOG_SIZE_MASK) + +/* The timestamp is the microsecond counter shifted to get about a ms. */ +#define EVENT_LOG_TIMESTAMP_SHIFT 10 /* 1 LSB = 1024us */ +/* Returned in the "type" field, when there is no entry available */ +#define EVENT_LOG_NO_ENTRY 0xff + +/* Add an entry to the event log. */ +void log_add_event(uint8_t type, uint8_t size, uint16_t data, + void *payload, uint32_t timestamp); + +/* + * Remove and return an entry from the event log, if available. + * Returns size of log entry *r. + */ +int log_dequeue_event(struct event_log_entry *r); + +#endif /* __CROS_EC_EVENT_LOG_H */ |