diff --git a/common/keyboard_mkbp.c b/common/keyboard_mkbp.c index 277e63dc03..e592addf2f 100644 --- a/common/keyboard_mkbp.c +++ b/common/keyboard_mkbp.c @@ -90,6 +90,7 @@ static int get_data_size(enum ec_mkbp_event e) case EC_MKBP_EVENT_HOST_EVENT: case EC_MKBP_EVENT_BUTTON: case EC_MKBP_EVENT_SWITCH: + case EC_MKBP_EVENT_SYSRQ: return sizeof(uint32_t); default: /* For unknown types, say it's 0. */ @@ -258,6 +259,15 @@ void keyboard_update_button(enum keyboard_button_type button, int is_pressed) (const uint8_t *)&mkbp_button_state); } +#ifdef CONFIG_EMULATED_SYSRQ +void send_sysrq(uint8_t key) +{ + uint32_t value = key; + + mkbp_fifo_add(EC_MKBP_EVENT_SYSRQ, (const uint8_t *)&value); +} +#endif + #ifdef CONFIG_POWER_BUTTON /** * Handle power button changing state. @@ -325,6 +335,14 @@ static int switch_get_next_event(uint8_t *out) } DECLARE_EVENT_SOURCE(EC_MKBP_EVENT_SWITCH, switch_get_next_event); +#ifdef CONFIG_EMULATED_SYSRQ +static int sysrq_get_next_event(uint8_t *out) +{ + return get_next_event(out, EC_MKBP_EVENT_SYSRQ); +} +DECLARE_EVENT_SOURCE(EC_MKBP_EVENT_SYSRQ, sysrq_get_next_event); +#endif + void keyboard_send_battery_key(void) { uint8_t state[KEYBOARD_COLS]; diff --git a/common/system.c b/common/system.c index 72d642f0f4..e152696941 100644 --- a/common/system.c +++ b/common/system.c @@ -1109,6 +1109,23 @@ DECLARE_CONSOLE_COMMAND(jumptags, command_jumptags, "List jump tags"); #endif /* CONFIG_CMD_JUMPTAGS */ +#ifdef CONFIG_EMULATED_SYSRQ +static int command_sysrq(int argc, char **argv) +{ + char key = 'x'; + + if (argc > 1 && argv[1]) + key = argv[1][0]; + + send_sysrq(key); + + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(sysrq, command_sysrq, + "[key]", + "Simulate sysrq press (default: x)"); +#endif /* CONFIG_EMULATED_SYSRQ */ + /*****************************************************************************/ /* Host commands */ diff --git a/include/config.h b/include/config.h index d096c90c2c..fcf98ada97 100644 --- a/include/config.h +++ b/include/config.h @@ -922,6 +922,9 @@ /* Support EC chip internal data EEPROM */ #undef CONFIG_EEPROM +/* Support for sending emulated sysrq commands to AP */ +#undef CONFIG_EMULATED_SYSRQ + /* Support for eSPI for host communication */ #undef CONFIG_ESPI diff --git a/include/ec_commands.h b/include/ec_commands.h index 08decc71a6..d10fca9df5 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -2797,6 +2797,9 @@ enum ec_mkbp_event { /* New Fingerprint sensor event, the event data is fp_events bitmap. */ EC_MKBP_EVENT_FINGERPRINT = 5, + /* Sysrq event */ + EC_MKBP_EVENT_SYSRQ = 6, + /* Number of MKBP events */ EC_MKBP_EVENT_COUNT, }; @@ -2818,6 +2821,8 @@ union __ec_align_offset1 ec_response_get_next_data { uint32_t switches; uint32_t fp_events; + + uint32_t sysrq; }; struct __ec_align1 ec_response_get_next_event { diff --git a/include/system.h b/include/system.h index b584e3586e..38132140b5 100644 --- a/include/system.h +++ b/include/system.h @@ -498,4 +498,12 @@ uintptr_t system_get_fw_reset_vector(uintptr_t base); */ int system_is_reboot_warm(void); +/* + * Sends an emulated sysrq to the host, used by button-based debug mode. + * Only implemented on top of MKBP protocol. + * + * @param key Key to be sent (e.g. 'x') + */ +void send_sysrq(uint8_t key); + #endif /* __CROS_EC_SYSTEM_H */