123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- /*
- * Copyright (c) 2017 Actions Semiconductor Co., Ltd
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- /**
- * @file
- * @brief Magic System Request Key Hacks
- *
- */
- #include <kernel.h>
- #include <drivers/uart.h>
- #include <soc.h>
- struct sysrq_key_op {
- char key;
- char reserved[3];
- void (*handler)(int);
- char *help_msg;
- char *action_msg;
- };
- #if CONFIG_KERNEL_SHOW_STACK
- extern void show_stack(void);
- static void sysrq_handle_show_stack(int key)
- {
- show_stack();
- }
- #endif
- static void sysrq_handle_change_jtag(int key)
- {
- jtag_set();
- }
- #if defined(CONFIG_INIT_STACKS) && defined(CONFIG_THREAD_STACK_INFO) && defined(CONFIG_THREAD_MONITOR)
- static void sysrq_stack_dump(const struct k_thread *thread, void *user_data)
- {
- unsigned int pcnt;
- size_t unused;
- size_t size = thread->stack_info.size;
- const char *tname;
- int ret;
- ret = k_thread_stack_space_get(thread, &unused);
- if (ret) {
- printk("Unable to determine unused stack size (%d)\n", ret);
- return;
- }
- tname = k_thread_name_get((struct k_thread *)thread);
- /* Calculate the real size reserved for the stack */
- pcnt = ((size - unused) * 100U) / size;
- printk("%p %-10s (real size %u):\tunused %u\tusage %u / %u (%u %%)\n",
- thread,
- tname ? tname : "NA",
- size, unused, size - unused, size, pcnt);
- }
- static void sysrq_handle_stack_dump(int key)
- {
- k_thread_foreach(sysrq_stack_dump, NULL);
- }
- #endif
- static const struct sysrq_key_op sysrq_key_table[] = {
- #ifdef CONFIG_KERNEL_SHOW_STACK
- {
- .key = 't',
- .handler = sysrq_handle_show_stack,
- .help_msg = "show-thread-states(t)",
- .action_msg = "Show State:",
- },
- #endif
- {
- .key = 'j',
- .handler = sysrq_handle_change_jtag,
- .help_msg = "change jtag to grp1 (j)",
- .action_msg = "jtag:",
- },
- #if defined(CONFIG_INIT_STACKS) && defined(CONFIG_THREAD_STACK_INFO) && defined(CONFIG_THREAD_MONITOR)
- {
- .key = 's',
- .handler = sysrq_handle_stack_dump,
- .help_msg = "show thread stack usage (s)",
- .action_msg = "stack usage:",
- },
- #endif
- };
- /* magic sysrq key: CTLR + 'b' 'r' 'e' 'a' 'k' */
- static const char sysrq_breakbuf[] = {0x02, 0x12, 0x05, 0x01, 0x0b};
- static int sysrq_break_idx;
- static struct sysrq_key_op* sysrq_get_key_op(char key)
- {
- int i, cnt;
- cnt = ARRAY_SIZE(sysrq_key_table);
- for (i = 0; i < cnt; i++) {
- if (key == sysrq_key_table[i].key) {
- return (struct sysrq_key_op*)&sysrq_key_table[i];
- }
- }
- return NULL;
- }
- static void sysrq_print_help(void)
- {
- int i;
- printk("HELP : quit(q) \n");
- for (i = 0; i < ARRAY_SIZE(sysrq_key_table); i++) {
- printk("%s \n", sysrq_key_table[i].help_msg);
- }
- printk("\n");
- }
- extern void printk_dma_switch(int sw_dma);
- static void handle_sysrq_main(const struct device * port)
- {
- struct sysrq_key_op* op_p;
- char key;
- #ifdef CONFIG_ACTIONS_PRINTK_DMA
- printk_dma_switch(0);
- #endif
- for(;;) {
- printk("Wait SYSRQ Key:\n");
- sysrq_print_help();
- uart_poll_in(port, &key);
- if (key == 'q') {
- printk("sysrq: exit\n");
- break;
- }
- op_p = sysrq_get_key_op(key);
- if (op_p) {
- printk("%s\n", op_p->action_msg);
- op_p->handler(key);
- } else {
- sysrq_print_help();
- }
- }
- #ifdef CONFIG_ACTIONS_PRINTK_DMA
- printk_dma_switch(1);
- #endif
- }
- void uart_handle_sysrq_char(const struct device * port, char c)
- {
- if (c == sysrq_breakbuf[sysrq_break_idx]) {
- sysrq_break_idx++;
- if (sysrq_break_idx == sizeof(sysrq_breakbuf)) {
- sysrq_break_idx = 0;
- handle_sysrq_main(port);
- }
- } else {
- sysrq_break_idx = 0;
- }
- }
|