summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorFurquan Shaikh <furquan@chromium.org>2017-11-14 18:51:42 -0800
committerchrome-bot <chrome-bot@chromium.org>2017-11-21 18:53:35 -0800
commitc9cd870600b12123dddc88814446327337557369 (patch)
treee1e24ad901e91e98831b38c1ccd315cb272b9a6a /common
parent0da531fae0099080b7dd472ade0788c18162cc19 (diff)
downloadchrome-ec-c9cd870600b12123dddc88814446327337557369.tar.gz
host_events: Bump up host events and masks to 64-bit
With the upcoming change to add a new command to get/set/clear host events and masks, it seems to be the right time to bump up the host events and masks to 64-bit. We are already out of available host events. This change opens up at least 32 bits for new host events. Old EC commands to operate on host events/masks will still deal with lower 32-bits of the events/mask. On the other hand, the new command being added will take care of the entire 64-bit events/masks. This ensures that old BIOS and kernel versions can still work with the newer EC versions. BUG=b:69329196 BRANCH=None TEST=make -j buildall. Verified: 1. hostevent set 0x4000 ==> Sets correct bit in host events 2. hostevent clear 0x4000 ==> Clears correct bit in host events 3. Kernel is able to query and read correct host event bits from EC. Verified using evtest. 4. Coreboot is able to read correct wake reason from EC. Verified using mosys eventlog list. Change-Id: Idcb24ea364ac6c491efc2f8dd9e29a9df6149e07 Signed-off-by: Furquan Shaikh <furquan@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/770925 Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/ec_features.c6
-rw-r--r--common/host_command.c2
-rw-r--r--common/host_event_commands.c184
-rw-r--r--common/keyboard_mkbp.c14
-rw-r--r--common/util.c39
5 files changed, 197 insertions, 48 deletions
diff --git a/common/ec_features.c b/common/ec_features.c
index c37649954f..49d5db4f63 100644
--- a/common/ec_features.c
+++ b/common/ec_features.c
@@ -115,7 +115,11 @@ uint32_t get_feature_flags0(void)
uint32_t get_feature_flags1(void)
{
- uint32_t result = EC_FEATURE_MASK_1(EC_FEATURE_UNIFIED_WAKE_MASKS);
+ uint32_t result = EC_FEATURE_MASK_1(EC_FEATURE_UNIFIED_WAKE_MASKS)
+#ifdef CONFIG_HOST_EVENT64
+ | EC_FEATURE_MASK_1(EC_FEATURE_HOST_EVENT64)
+#endif
+ ;
#ifdef CONFIG_EC_FEATURE_BOARD_OVERRIDE
result = board_override_feature_flags1(result);
#endif
diff --git a/common/host_command.c b/common/host_command.c
index 961706fea2..bd397a6616 100644
--- a/common/host_command.c
+++ b/common/host_command.c
@@ -411,7 +411,7 @@ static void host_command_init(void)
#ifdef CONFIG_HOSTCMD_EVENTS
host_set_single_event(EC_HOST_EVENT_INTERFACE_READY);
- CPRINTS("hostcmd init 0x%x", host_get_events());
+ HOST_EVENT_CPRINTS("hostcmd init", host_get_events());
#endif
}
diff --git a/common/host_event_commands.c b/common/host_event_commands.c
index 8a67822bf7..9da08c892c 100644
--- a/common/host_event_commands.c
+++ b/common/host_event_commands.c
@@ -5,7 +5,6 @@
/* Host event commands for Chrome EC */
-#include "atomic.h"
#include "common.h"
#include "console.h"
#include "hooks.h"
@@ -13,12 +12,31 @@
#include "lpc.h"
#include "mkbp_event.h"
#include "system.h"
+#include "task.h"
#include "util.h"
/* Console output macros */
#define CPUTS(outstr) cputs(CC_EVENTS, outstr)
#define CPRINTS(format, args...) cprints(CC_EVENTS, format, ## args)
+/*
+ * This is used to avoid 64-bit shifts which might require a new library
+ * function.
+ */
+#define HOST_EVENT_32BIT_MASK(x) (1UL << ((x) - 1))
+static void host_event_set_bit(host_event_t *ev, uint8_t bit)
+{
+ uint32_t *ptr = (uint32_t *)ev;
+
+ *ev = 0;
+#ifdef CONFIG_HOST_EVENT64
+ if (bit >= 32)
+ *(ptr + 1) = HOST_EVENT_32BIT_MASK(bit - 32);
+ else
+#endif
+ *ptr = HOST_EVENT_32BIT_MASK(bit);
+}
+
#ifdef CONFIG_LPC
#define LPC_SYSJUMP_TAG 0x4c50 /* "LP" */
@@ -54,23 +72,23 @@
EC_HOST_EVENT_MASK(EC_HOST_EVENT_MKBP) | \
EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY_HW_REINIT))
-static uint32_t lpc_host_events;
-static uint32_t lpc_host_event_mask[LPC_HOST_EVENT_COUNT];
+static host_event_t lpc_host_events;
+static host_event_t lpc_host_event_mask[LPC_HOST_EVENT_COUNT];
-void lpc_set_host_event_mask(enum lpc_host_event_type type, uint32_t mask)
+void lpc_set_host_event_mask(enum lpc_host_event_type type, host_event_t mask)
{
lpc_host_event_mask[type] = mask;
lpc_update_host_event_status();
}
-uint32_t lpc_get_host_event_mask(enum lpc_host_event_type type)
+host_event_t lpc_get_host_event_mask(enum lpc_host_event_type type)
{
return lpc_host_event_mask[type];
}
-static uint32_t lpc_get_all_host_event_masks(void)
+static host_event_t lpc_get_all_host_event_masks(void)
{
- uint32_t or_mask = 0;
+ host_event_t or_mask = 0;
int i;
for (i = 0; i < LPC_HOST_EVENT_COUNT; i++)
@@ -79,7 +97,7 @@ static uint32_t lpc_get_all_host_event_masks(void)
return or_mask;
}
-static void lpc_set_host_event_state(uint32_t events)
+static void lpc_set_host_event_state(host_event_t events)
{
if (events == lpc_host_events)
return;
@@ -88,22 +106,25 @@ static void lpc_set_host_event_state(uint32_t events)
lpc_update_host_event_status();
}
-uint32_t lpc_get_host_events_by_type(enum lpc_host_event_type type)
+host_event_t lpc_get_host_events_by_type(enum lpc_host_event_type type)
{
return lpc_host_events & lpc_get_host_event_mask(type);
}
-uint32_t lpc_get_host_events(void)
+host_event_t lpc_get_host_events(void)
{
return lpc_host_events;
}
int lpc_get_next_host_event(void)
{
+ host_event_t ev;
int evt_idx = __builtin_ffs(lpc_host_events);
- if (evt_idx)
- host_clear_events(1 << (evt_idx - 1));
+ if (evt_idx) {
+ host_event_set_bit(&ev, evt_idx);
+ host_clear_events(ev);
+ }
return evt_idx;
}
@@ -124,10 +145,10 @@ DECLARE_HOOK(HOOK_SYSJUMP, lpc_sysjump_save_mask, HOOK_PRIO_DEFAULT);
*/
static int lpc_post_sysjump_restore_mask(void)
{
- const uint32_t *prev_mask;
+ const host_event_t *prev_mask;
int size, version;
- prev_mask = (const uint32_t *)system_get_jump_tag(LPC_SYSJUMP_TAG,
+ prev_mask = (const host_event_t *)system_get_jump_tag(LPC_SYSJUMP_TAG,
&version, &size);
if (!prev_mask || size != sizeof(lpc_host_event_mask) ||
(version != LPC_SYSJUMP_VERSION &&
@@ -139,7 +160,7 @@ static int lpc_post_sysjump_restore_mask(void)
return version == LPC_SYSJUMP_VERSION;
}
-uint32_t __attribute__((weak)) lpc_override_always_report_mask(void)
+host_event_t __attribute__((weak)) lpc_override_always_report_mask(void)
{
return LPC_HOST_EVENT_ALWAYS_REPORT_DEFAULT_MASK;
}
@@ -178,18 +199,58 @@ void lpc_s3_resume_clear_masks(void)
*
* Setting an event sets both copies. Copies are cleared separately.
*/
-static uint32_t events;
-static uint32_t events_copy_b;
+static host_event_t events;
+static host_event_t events_copy_b;
+
+static void host_events_atomic_or(host_event_t *e, host_event_t m)
+{
+ uint32_t *ptr = (uint32_t *)e;
+
+ atomic_or(ptr, (uint32_t)m);
+#ifdef CONFIG_HOST_EVENT64
+ atomic_or(ptr + 1, (uint32_t)(m >> 32));
+#endif
+}
+
+static void host_events_atomic_clear(host_event_t *e, host_event_t m)
+{
+ uint32_t *ptr = (uint32_t *)e;
+
+ atomic_clear(ptr, (uint32_t)m);
+#ifdef CONFIG_HOST_EVENT64
+ atomic_clear(ptr + 1, (uint32_t)(m >> 32));
+#endif
+}
+
+#if !defined(CONFIG_LPC) && defined(CONFIG_MKBP_EVENT)
+static void host_events_send_mkbp_event(host_event_t e)
+{
+#ifdef CONFIG_HOST_EVENT64
+ /*
+ * If event bits in the upper 32-bit are set, indicate 64-bit host
+ * event.
+ */
+ if (!(uint32_t)e)
+ mkbp_send_event(EC_MKBP_EVENT_HOST_EVENT64);
+ else
+#endif
+ mkbp_send_event(EC_MKBP_EVENT_HOST_EVENT);
+}
+#endif
-uint32_t host_get_events(void)
+host_event_t host_get_events(void)
{
return events;
}
-void host_set_events(uint32_t mask)
+void host_set_events(host_event_t mask)
{
/* ignore host events the rest of board doesn't care about */
+#ifdef CONFIG_HOST_EVENT64
+ mask &= CONFIG_HOST_EVENT64_REPORT_MASK;
+#else
mask &= CONFIG_HOST_EVENT_REPORT_MASK;
+#endif
#ifdef CONFIG_LPC
/*
@@ -207,43 +268,63 @@ void host_set_events(uint32_t mask)
if (!((events & mask) != mask || (events_copy_b & mask) != mask))
return;
- CPRINTS("event set 0x%08x", mask);
+ HOST_EVENT_CPRINTS("event set", mask);
- atomic_or(&events, mask);
- atomic_or(&events_copy_b, mask);
+ host_events_atomic_or(&events, mask);
+ host_events_atomic_or(&events_copy_b, mask);
#ifdef CONFIG_LPC
lpc_set_host_event_state(events);
#else
- *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) = events;
+ *(host_event_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) = events;
#ifdef CONFIG_MKBP_EVENT
#ifdef CONFIG_MKBP_USE_HOST_EVENT
#error "Config error: MKBP must not be on top of host event"
#endif
- mkbp_send_event(EC_MKBP_EVENT_HOST_EVENT);
+ host_events_send_mkbp_event(events);
#endif /* CONFIG_MKBP_EVENT */
#endif /* !CONFIG_LPC */
}
-void host_clear_events(uint32_t mask)
+void host_set_single_event(enum host_event_code event)
+{
+ host_event_t ev = 0;
+
+ host_event_set_bit(&ev, event);
+ host_set_events(ev);
+}
+
+int host_is_event_set(enum host_event_code event)
+{
+ host_event_t ev = 0;
+
+ host_event_set_bit(&ev, event);
+ return events & ev;
+}
+
+void host_clear_events(host_event_t mask)
{
/* ignore host events the rest of board doesn't care about */
+#ifdef CONFIG_HOST_EVENT64
+ mask &= CONFIG_HOST_EVENT64_REPORT_MASK;
+#else
mask &= CONFIG_HOST_EVENT_REPORT_MASK;
+#endif
/* return early if nothing changed */
if (!(events & mask))
return;
- CPRINTS("event clear 0x%08x", mask);
+ HOST_EVENT_CPRINTS("event clear", mask);
- atomic_clear(&events, mask);
+ host_events_atomic_clear(&events, mask);
#ifdef CONFIG_LPC
lpc_set_host_event_state(events);
#else
- *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) = events;
+ *(host_event_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) = events;
#ifdef CONFIG_MKBP_EVENT
- mkbp_send_event(EC_MKBP_EVENT_HOST_EVENT);
+ host_events_send_mkbp_event(events);
#endif
#endif /* !CONFIG_LPC */
}
@@ -251,13 +332,26 @@ void host_clear_events(uint32_t mask)
#ifndef CONFIG_LPC
static int host_get_next_event(uint8_t *out)
{
- uint32_t event_out = events;
+ uint32_t event_out = (uint32_t)events;
memcpy(out, &event_out, sizeof(event_out));
- atomic_clear(&events, event_out);
- *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) = events;
+ host_events_atomic_clear(&events, event_out);
+ *(host_event_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) = events;
return sizeof(event_out);
}
DECLARE_EVENT_SOURCE(EC_MKBP_EVENT_HOST_EVENT, host_get_next_event);
+
+#ifdef CONFIG_HOST_EVENT64
+static int host_get_next_event64(uint8_t *out)
+{
+ host_event_t event_out = events;
+
+ memcpy(out, &event_out, sizeof(event_out));
+ host_events_atomic_clear(&events, event_out);
+ *(host_event_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) = events;
+ return sizeof(event_out);
+}
+DECLARE_EVENT_SOURCE(EC_MKBP_EVENT_HOST_EVENT64, host_get_next_event64);
+#endif
#endif
/**
@@ -266,13 +360,13 @@ DECLARE_EVENT_SOURCE(EC_MKBP_EVENT_HOST_EVENT, host_get_next_event);
* @param mask Event bits to clear (use EC_HOST_EVENT_MASK()).
* Write 1 to a bit to clear it.
*/
-static void host_clear_events_b(uint32_t mask)
+static void host_clear_events_b(host_event_t mask)
{
/* Only print if something's about to change */
if (events_copy_b & mask)
- CPRINTS("event clear B 0x%08x", mask);
+ HOST_EVENT_CPRINTS("event clear B", mask);
- atomic_clear(&events_copy_b, mask);
+ host_events_atomic_clear(&events_copy_b, mask);
}
/**
@@ -295,7 +389,7 @@ static int command_host_event(int argc, char **argv)
/* Handle sub-commands */
if (argc == 3) {
char *e;
- int i = strtoi(argv[2], &e, 0);
+ host_event_t i = strtoul(argv[2], &e, 0);
if (*e)
return EC_ERROR_PARAM2;
@@ -321,16 +415,16 @@ static int command_host_event(int argc, char **argv)
}
/* Print current SMI/SCI status */
- ccprintf("Events: 0x%08x\n", host_get_events());
- ccprintf("Events-B: 0x%08x\n", events_copy_b);
+ HOST_EVENT_CCPRINTF("Events: ", host_get_events());
+ HOST_EVENT_CCPRINTF("Events-B: ", events_copy_b);
#ifdef CONFIG_LPC
- ccprintf("SMI mask: 0x%08x\n",
+ HOST_EVENT_CCPRINTF("SMI mask: ",
lpc_get_host_event_mask(LPC_HOST_EVENT_SMI));
- ccprintf("SCI mask: 0x%08x\n",
+ HOST_EVENT_CCPRINTF("SCI mask: ",
lpc_get_host_event_mask(LPC_HOST_EVENT_SCI));
- ccprintf("Wake mask: 0x%08x\n",
+ HOST_EVENT_CCPRINTF("Wake mask: ",
lpc_get_host_event_mask(LPC_HOST_EVENT_WAKE));
- ccprintf("Always report mask: 0x%08x\n",
+ HOST_EVENT_CCPRINTF("Always report mask: ",
lpc_get_host_event_mask(LPC_HOST_EVENT_ALWAYS_REPORT));
#endif
return EC_SUCCESS;
@@ -348,7 +442,7 @@ static int host_event_get_smi_mask(struct host_cmd_handler_args *args)
{
struct ec_response_host_event_mask *r = args->response;
- r->mask = lpc_get_host_event_mask(LPC_HOST_EVENT_SMI);
+ r->mask = (uint32_t)lpc_get_host_event_mask(LPC_HOST_EVENT_SMI);
args->response_size = sizeof(*r);
return EC_RES_SUCCESS;
@@ -361,7 +455,7 @@ static int host_event_get_sci_mask(struct host_cmd_handler_args *args)
{
struct ec_response_host_event_mask *r = args->response;
- r->mask = lpc_get_host_event_mask(LPC_HOST_EVENT_SCI);
+ r->mask = (uint32_t)lpc_get_host_event_mask(LPC_HOST_EVENT_SCI);
args->response_size = sizeof(*r);
return EC_RES_SUCCESS;
@@ -374,7 +468,7 @@ static int host_event_get_wake_mask(struct host_cmd_handler_args *args)
{
struct ec_response_host_event_mask *r = args->response;
- r->mask = lpc_get_host_event_mask(LPC_HOST_EVENT_WAKE);
+ r->mask = (uint32_t)lpc_get_host_event_mask(LPC_HOST_EVENT_WAKE);
args->response_size = sizeof(*r);
return EC_RES_SUCCESS;
diff --git a/common/keyboard_mkbp.c b/common/keyboard_mkbp.c
index 2e1806abec..ffe5aefa92 100644
--- a/common/keyboard_mkbp.c
+++ b/common/keyboard_mkbp.c
@@ -100,6 +100,11 @@ static int get_data_size(enum ec_mkbp_event e)
case EC_MKBP_EVENT_KEY_MATRIX:
return KEYBOARD_COLS;
+#ifdef CONFIG_HOST_EVENT64
+ case EC_MKBP_EVENT_HOST_EVENT64:
+ return sizeof(uint64_t);
+#endif
+
case EC_MKBP_EVENT_HOST_EVENT:
case EC_MKBP_EVENT_BUTTON:
case EC_MKBP_EVENT_SWITCH:
@@ -475,10 +480,17 @@ static int mkbp_get_info(struct host_cmd_handler_args *args)
break;
#endif
case EC_MKBP_EVENT_HOST_EVENT:
- r->host_event = host_get_events();
+ r->host_event = (uint32_t)host_get_events();
args->response_size = sizeof(r->host_event);
break;
+#ifdef CONFIG_HOST_EVENT64
+ case EC_MKBP_EVENT_HOST_EVENT64:
+ r->host_event64 = host_get_events();
+ args->response_size = sizeof(r->host_event64);
+ break;
+#endif
+
case EC_MKBP_EVENT_BUTTON:
r->buttons = mkbp_button_state;
args->response_size = sizeof(r->buttons);
diff --git a/common/util.c b/common/util.c
index a353c75a61..701419b073 100644
--- a/common/util.c
+++ b/common/util.c
@@ -153,6 +153,45 @@ int strtoi(const char *nptr, char **endptr, int base)
return neg ? -result : result;
}
+uint64_t strtoul(const char *nptr, char **endptr, int base)
+{
+ uint64_t result = 0;
+ int c = '\0';
+
+ if (endptr)
+ *endptr = (char *)nptr;
+
+ while ((c = *nptr++) && isspace(c))
+ ;
+
+ if (c == '0' && *nptr == 'x') {
+ base = 16;
+ c = nptr[1];
+ nptr += 2;
+ } else if (base == 0) {
+ base = 10;
+ if (c == '-')
+ return result;
+ }
+
+ while (c) {
+ if (c >= '0' && c < '0' + MIN(base, 10))
+ result = result * base + (c - '0');
+ else if (c >= 'A' && c < 'A' + base - 10)
+ result = result * base + (c - 'A' + 10);
+ else if (c >= 'a' && c < 'a' + base - 10)
+ result = result * base + (c - 'a' + 10);
+ else
+ break;
+
+ if (endptr)
+ *endptr = (char *)nptr;
+ c = *nptr++;
+ }
+
+ return result;
+}
+
int parse_bool(const char *s, int *dest)
{
/* off, disable, false, no */