summaryrefslogtreecommitdiff
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
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>
-rw-r--r--board/kevin/board.h2
-rw-r--r--chip/it83xx/lpc.c4
-rw-r--r--chip/lm4/lpc.c12
-rw-r--r--chip/mec1322/lpc.c4
-rw-r--r--chip/npcx/gpio.c2
-rw-r--r--chip/npcx/lpc.c12
-rw-r--r--chip/stm32/clock-f.c2
-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
-rw-r--r--include/config.h4
-rw-r--r--include/ec_commands.h14
-rw-r--r--include/host_command.h31
-rw-r--r--include/lpc.h11
-rw-r--r--include/util.h1
-rw-r--r--power/intel_x86.c4
18 files changed, 255 insertions, 93 deletions
diff --git a/board/kevin/board.h b/board/kevin/board.h
index d0306c8c26..856accd01b 100644
--- a/board/kevin/board.h
+++ b/board/kevin/board.h
@@ -8,6 +8,8 @@
#ifndef __CROS_EC_BOARD_H
#define __CROS_EC_BOARD_H
+#undef CONFIG_HOST_EVENT64
+
/* Optional modules */
#define CONFIG_ADC
#define CONFIG_CHIPSET_RK3399
diff --git a/chip/it83xx/lpc.c b/chip/it83xx/lpc.c
index ed83a85c01..8fd08f2b90 100644
--- a/chip/it83xx/lpc.c
+++ b/chip/it83xx/lpc.c
@@ -153,7 +153,7 @@ static void lpc_generate_sci(void)
*
* @param wake_events Currently asserted wake events
*/
-static void lpc_update_wake(uint32_t wake_events)
+static void lpc_update_wake(host_event_t wake_events)
{
/*
* Mask off power button event, since the AP gets that through a
@@ -238,7 +238,7 @@ void lpc_update_host_event_status(void)
}
/* Copy host events to mapped memory */
- *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) =
+ *(host_event_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) =
lpc_get_host_events();
task_enable_irq(IT83XX_IRQ_PMC_IN);
diff --git a/chip/lm4/lpc.c b/chip/lm4/lpc.c
index 8068940d70..f2f1cb0549 100644
--- a/chip/lm4/lpc.c
+++ b/chip/lm4/lpc.c
@@ -149,7 +149,7 @@ static inline void keyboard_irq_assert(void)
*/
static void lpc_generate_smi(void)
{
- uint32_t smi;
+ host_event_t smi;
/* Enforce signal-high for long enough to debounce high */
gpio_set_level(GPIO_PCH_SMI_L, 1);
@@ -162,7 +162,7 @@ static void lpc_generate_smi(void)
smi = lpc_get_host_events_by_type(LPC_HOST_EVENT_SMI);
if (smi)
- CPRINTS("smi 0x%08x", smi);
+ HOST_EVENT_CPRINTS("smi", smi);
}
/**
@@ -170,7 +170,7 @@ static void lpc_generate_smi(void)
*/
static void lpc_generate_sci(void)
{
- uint32_t sci;
+ host_event_t sci;
#ifdef CONFIG_SCI_GPIO
/* Enforce signal-high for long enough to debounce high */
@@ -187,7 +187,7 @@ static void lpc_generate_sci(void)
sci = lpc_get_host_events_by_type(LPC_HOST_EVENT_SCI);
if (sci)
- CPRINTS("sci 0x%08x", sci);
+ HOST_EVENT_CPRINTS("sci", sci);
}
/**
@@ -195,7 +195,7 @@ static void lpc_generate_sci(void)
*
* @param wake_events Currently asserted wake events
*/
-static void lpc_update_wake(uint32_t wake_events)
+static void lpc_update_wake(uint64_t wake_events)
{
/*
* Mask off power button event, since the AP gets that through a
@@ -368,7 +368,7 @@ void lpc_update_host_event_status(void)
LM4_LPC_ST(LPC_CH_ACPI) &= ~LM4_LPC_ST_SCI;
/* Copy host events to mapped memory */
- *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) =
+ *(host_event_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) =
lpc_get_host_events();
task_enable_irq(LM4_IRQ_LPC);
diff --git a/chip/mec1322/lpc.c b/chip/mec1322/lpc.c
index acc3e11b45..5d2d57f834 100644
--- a/chip/mec1322/lpc.c
+++ b/chip/mec1322/lpc.c
@@ -93,7 +93,7 @@ static void lpc_generate_sci(void)
*
* @param wake_events Currently asserted wake events
*/
-static void lpc_update_wake(uint32_t wake_events)
+static void lpc_update_wake(host_event_t wake_events)
{
/*
* Mask off power button event, since the AP gets that through a
@@ -151,7 +151,7 @@ void lpc_update_host_event_status(void)
}
/* Copy host events to mapped memory */
- *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) =
+ *(host_event_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) =
lpc_get_host_events();
task_enable_irq(MEC1322_IRQ_ACPIEC0_IBF);
diff --git a/chip/npcx/gpio.c b/chip/npcx/gpio.c
index c06aff4d32..d19e6c2107 100644
--- a/chip/npcx/gpio.c
+++ b/chip/npcx/gpio.c
@@ -536,7 +536,7 @@ void __gpio_rtc_interrupt(void)
if (NPCX_WKPND(MIWU_TABLE_0, MIWU_GROUP_4) & 0x80) {
/* Clear pending bit for WUI */
SET_BIT(NPCX_WKPCL(MIWU_TABLE_0, MIWU_GROUP_4), 7);
- host_set_events(EC_HOST_EVENT_MASK(EC_HOST_EVENT_RTC));
+ host_set_single_event(EC_HOST_EVENT_RTC);
} else
#endif
{
diff --git a/chip/npcx/lpc.c b/chip/npcx/lpc.c
index c97713d34b..7f909cae2b 100644
--- a/chip/npcx/lpc.c
+++ b/chip/npcx/lpc.c
@@ -137,7 +137,7 @@ static void lpc_task_disable_irq(void)
*/
static void lpc_generate_smi(void)
{
- uint32_t smi;
+ host_event_t smi;
#ifdef CONFIG_SCI_GPIO
/* Enforce signal-high for long enough to debounce high */
@@ -175,7 +175,7 @@ static void lpc_generate_smi(void)
#endif
smi = lpc_get_host_events_by_type(LPC_HOST_EVENT_SMI);
if (smi)
- CPRINTS("smi 0x%08x", smi);
+ HOST_EVENT_CPRINTS("smi", smi);
}
/**
@@ -183,7 +183,7 @@ static void lpc_generate_smi(void)
*/
static void lpc_generate_sci(void)
{
- uint32_t sci;
+ host_event_t sci;
#ifdef CONFIG_SCI_GPIO
/* Enforce signal-high for long enough to debounce high */
@@ -222,7 +222,7 @@ static void lpc_generate_sci(void)
sci = lpc_get_host_events_by_type(LPC_HOST_EVENT_SCI);
if (sci)
- CPRINTS("sci 0x%08x", sci);
+ HOST_EVENT_CPRINTS("sci", sci);
}
/**
@@ -230,7 +230,7 @@ static void lpc_generate_sci(void)
*
* @param wake_events Currently asserted wake events
*/
-static void lpc_update_wake(uint32_t wake_events)
+static void lpc_update_wake(host_event_t wake_events)
{
/*
* Mask off power button event, since the AP gets that through a
@@ -450,7 +450,7 @@ void lpc_update_host_event_status(void)
CLEAR_BIT(NPCX_HIPMST(PMC_ACPI), NPCX_HIPMST_ST1);
/* Copy host events to mapped memory */
- *(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) =
+ *(host_event_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) =
lpc_get_host_events();
lpc_task_enable_irq();
diff --git a/chip/stm32/clock-f.c b/chip/stm32/clock-f.c
index 7f1fa8e03e..025eaf0246 100644
--- a/chip/stm32/clock-f.c
+++ b/chip/stm32/clock-f.c
@@ -257,7 +257,7 @@ void __rtc_alarm_irq(void)
#ifdef CONFIG_HOSTCMD_RTC
/* Do not wake up the host if the alarm was not set by the host */
if (host_rtc_alarm_set) {
- host_set_events(EC_HOST_EVENT_MASK(EC_HOST_EVENT_RTC));
+ host_set_single_event(EC_HOST_EVENT_RTC);
host_rtc_alarm_set = 0;
}
#endif
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 */
diff --git a/include/config.h b/include/config.h
index 083f81258d..dba87924db 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1436,6 +1436,10 @@
/* clear bit(s) to mask reporting of an EC_HOST_EVENT_XXX event(s) */
#define CONFIG_HOST_EVENT_REPORT_MASK 0xffffffff
+#define CONFIG_HOST_EVENT64_REPORT_MASK 0xffffffffffffffffULL
+
+/* Config option to support 64-bit hostevents and wake-masks. */
+#define CONFIG_HOST_EVENT64
/*
* The host commands are sorted in the .rodata.hcmds section so use the binary
diff --git a/include/ec_commands.h b/include/ec_commands.h
index 09ebc75319..fb39644e19 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -83,8 +83,7 @@
/* Unused 0x28 - 0x2f */
#define EC_MEMMAP_SWITCHES 0x30 /* 8 bits */
/* Unused 0x31 - 0x33 */
-#define EC_MEMMAP_HOST_EVENTS 0x34 /* 32 bits */
-/* Reserve 0x38 - 0x3f for additional host event-related stuff */
+#define EC_MEMMAP_HOST_EVENTS 0x34 /* 64 bits */
/* Battery values are all 32 bits */
#define EC_MEMMAP_BATT_VOLT 0x40 /* Battery Present Voltage */
#define EC_MEMMAP_BATT_RATE 0x44 /* Battery Present Rate */
@@ -595,7 +594,7 @@ enum host_event_code {
EC_HOST_EVENT_INVALID = 32
};
/* Host event mask */
-#define EC_HOST_EVENT_MASK(event_code) (1UL << ((event_code) - 1))
+#define EC_HOST_EVENT_MASK(event_code) (1ULL << ((event_code) - 1))
/* Arguments at EC_LPC_ADDR_HOST_ARGS */
struct __ec_align4 ec_lpc_host_args {
@@ -1112,6 +1111,8 @@ enum ec_feature_code {
EC_FEATURE_DEVICE_EVENT = 31,
/* EC supports the unified wake masks for LPC/eSPI systems */
EC_FEATURE_UNIFIED_WAKE_MASKS = 32,
+ /* EC supports 64-bit host events */
+ EC_FEATURE_HOST_EVENT64 = 33,
};
#define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32))
@@ -3016,6 +3017,12 @@ enum ec_mkbp_event {
*/
EC_MKBP_EVENT_SYSRQ = 6,
+ /*
+ * New 64-bit host event.
+ * The event data is 8 bytes of host event flags.
+ */
+ EC_MKBP_EVENT_HOST_EVENT64 = 7,
+
/* Number of MKBP events */
EC_MKBP_EVENT_COUNT,
};
@@ -3025,6 +3032,7 @@ union __ec_align_offset1 ec_response_get_next_data {
/* Unaligned */
uint32_t host_event;
+ uint64_t host_event64;
struct __ec_todo_unpacked {
/* For aligning the fifo_info */
diff --git a/include/host_command.h b/include/host_command.h
index 78157231ca..6fdbc639e9 100644
--- a/include/host_command.h
+++ b/include/host_command.h
@@ -122,6 +122,16 @@ struct host_command {
int version_mask;
};
+#ifdef CONFIG_HOST_EVENT64
+typedef uint64_t host_event_t;
+#define HOST_EVENT_CPRINTS(str, e) CPRINTS("%s 0x%016lx", str, e)
+#define HOST_EVENT_CCPRINTF(str, e) ccprintf("%s 0x%016lx\n", str, e)
+#else
+typedef uint32_t host_event_t;
+#define HOST_EVENT_CPRINTS(str, e) CPRINTS("%s 0x%08x", str, e)
+#define HOST_EVENT_CCPRINTF(str, e) ccprintf("%s 0x%08x\n", str, e)
+#endif
+
/**
* Return a pointer to the memory-mapped buffer.
*
@@ -146,21 +156,11 @@ uint16_t host_command_process(struct host_cmd_handler_args *args);
#ifdef CONFIG_HOSTCMD_EVENTS
/**
- * Set one or more host event bits.
- *
- * @param mask Event bits to set (use EC_HOST_EVENT_MASK()).
- */
-void host_set_events(uint32_t mask);
-
-/**
* Set a single host event.
*
* @param event Event to set (EC_HOST_EVENT_*).
*/
-static inline void host_set_single_event(int event)
-{
- host_set_events(EC_HOST_EVENT_MASK(event));
-}
+void host_set_single_event(enum host_event_code event);
/**
* Clear one or more host event bits.
@@ -168,12 +168,12 @@ static inline void host_set_single_event(int event)
* @param mask Event bits to clear (use EC_HOST_EVENT_MASK()).
* Write 1 to a bit to clear it.
*/
-void host_clear_events(uint32_t mask);
+void host_clear_events(host_event_t mask);
/**
* Return the raw event state.
*/
-uint32_t host_get_events(void);
+host_event_t host_get_events(void);
/**
* Check a single host event.
@@ -181,10 +181,7 @@ uint32_t host_get_events(void);
* @param event Event to check
* @return true if <event> is set or false otherwise
*/
-static inline int host_is_event_set(enum host_event_code event)
-{
- return host_get_events() & EC_HOST_EVENT_MASK(event);
-}
+int host_is_event_set(enum host_event_code event);
#endif
/**
diff --git a/include/lpc.h b/include/lpc.h
index 7b9a7d7012..c95999a98e 100644
--- a/include/lpc.h
+++ b/include/lpc.h
@@ -9,6 +9,7 @@
#define __CROS_EC_LPC_H
#include "common.h"
+#include "host_command.h"
/**
* Return a pointer to the memory-mapped buffer.
@@ -78,14 +79,14 @@ enum lpc_host_event_type {
/**
* Get current state of host events.
*/
-uint32_t lpc_get_host_events(void);
+host_event_t lpc_get_host_events(void);
/**
* Get host events that are set based on the type provided.
*
* @param type Event type
*/
-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);
/**
* Set the event mask for the specified event type.
@@ -93,14 +94,14 @@ uint32_t lpc_get_host_events_by_type(enum lpc_host_event_type type);
* @param type Event type
* @param mask New event mask
*/
-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);
/**
* Get host event mask based on the type provided.
*
* @param type Event type
*/
-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);
/**
* Clear and return the lowest host event.
@@ -147,7 +148,7 @@ void lpc_update_host_event_status(void);
* LPC_HOST_EVENT_ALWAYS_REPORT mask. It can be implemented by boards if there
* is a need to use custom mask.
*/
-uint32_t lpc_override_always_report_mask(void);
+host_event_t lpc_override_always_report_mask(void);
/* Initialize LPC masks. */
void lpc_init_mask(void);
diff --git a/include/util.h b/include/util.h
index bf3405728a..453ff8c739 100644
--- a/include/util.h
+++ b/include/util.h
@@ -77,6 +77,7 @@ int strncmp(const char *s1, const char *s2, size_t n);
/* Like strtol(), but for integers. */
int strtoi(const char *nptr, char **endptr, int base);
+uint64_t strtoul(const char *nptr, char **endptr, int base);
/* Like strncpy(), but guarantees null termination. */
char *strzcpy(char *dest, const char *src, int len);
diff --git a/power/intel_x86.c b/power/intel_x86.c
index 8a841161e3..c1962965b3 100644
--- a/power/intel_x86.c
+++ b/power/intel_x86.c
@@ -131,7 +131,7 @@ static void s0ix_transition(int check_state, int hook_id)
static void s0ix_lpc_enable_wake_mask(void)
{
if (chipset_in_state(CHIPSET_STATE_STANDBY | CHIPSET_STATE_ON)) {
- uint32_t mask;
+ host_event_t mask;
mask = lpc_get_host_event_mask(LPC_HOST_EVENT_WAKE) |
EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN) |
@@ -150,7 +150,7 @@ static void s0ix_lpc_enable_wake_mask(void)
static void s0ix_lpc_disable_wake_mask(void)
{
if (chipset_in_state(CHIPSET_STATE_STANDBY | CHIPSET_STATE_ON)) {
- uint32_t mask;
+ host_event_t mask;
mask = lpc_get_host_event_mask(LPC_HOST_EVENT_WAKE) &
~EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN) &