diff options
-rw-r--r-- | chip/lm4/keyboard_scan.c | 19 | ||||
-rw-r--r-- | chip/lm4/lpc.c | 17 | ||||
-rw-r--r-- | chip/lm4/power_button.c | 30 | ||||
-rw-r--r-- | chip/lm4/watchdog.c | 15 | ||||
-rw-r--r-- | chip/stm32l/keyboard_scan.c | 16 | ||||
-rw-r--r-- | chip/stm32l/watchdog.c | 11 | ||||
-rw-r--r-- | common/charge_state.c | 17 | ||||
-rw-r--r-- | common/console.c | 145 | ||||
-rw-r--r-- | common/host_command.c | 11 | ||||
-rw-r--r-- | common/i8042.c | 32 | ||||
-rw-r--r-- | common/keyboard.c | 877 | ||||
-rw-r--r-- | common/lightbar.c | 63 | ||||
-rw-r--r-- | common/port80.c | 13 | ||||
-rw-r--r-- | common/system_common.c | 61 | ||||
-rw-r--r-- | common/uart_buffering.c | 20 | ||||
-rw-r--r-- | common/usb_charge_commands.c | 9 | ||||
-rw-r--r-- | common/x86_power.c | 27 | ||||
-rw-r--r-- | core/cortex-m/task.c | 34 | ||||
-rw-r--r-- | include/console.h | 48 | ||||
-rw-r--r-- | include/uart.h | 5 | ||||
-rw-r--r-- | include/x86_power.h | 3 |
21 files changed, 826 insertions, 647 deletions
diff --git a/chip/lm4/keyboard_scan.c b/chip/lm4/keyboard_scan.c index 91e04aac82..2e00bbdc02 100644 --- a/chip/lm4/keyboard_scan.c +++ b/chip/lm4/keyboard_scan.c @@ -15,9 +15,12 @@ #include "system.h" #include "task.h" #include "timer.h" -#include "uart.h" #include "util.h" +/* Console output macros */ +#define CPUTS(outstr) cputs(CC_KEYSCAN, outstr) +#define CPRINTF(format, args...) cprintf(CC_KEYSCAN, format, ## args) + /* Notes: * @@ -159,7 +162,7 @@ static uint32_t clear_matrix_interrupt_status(void) { static void wait_for_interrupt(void) { - uart_puts("[KB wait]\n"); + CPUTS("[KB wait]\n"); /* Assert all outputs would trigger un-wanted interrupts. * Clear them before enable interrupt. */ @@ -174,7 +177,7 @@ static void wait_for_interrupt(void) static void enter_polling_mode(void) { - uart_puts("[KB poll]\n"); + CPUTS("[KB poll]\n"); LM4_GPIO_IM(KB_SCAN_ROW_GPIO) = 0; /* 0: disable interrupt */ select_column(COLUMN_TRI_STATE_ALL); } @@ -209,14 +212,14 @@ static void print_raw_state(const char *msg) { int c; - uart_printf("[KB %s:", msg); + CPRINTF("[KB %s:", msg); for (c = 0; c < KB_COLS; c++) { if (raw_state[c]) - uart_printf(" %02x", raw_state[c]); + CPRINTF(" %02x", raw_state[c]); else - uart_puts(" --"); + CPUTS(" --"); } - uart_puts("]\n"); + CPUTS("]\n"); } @@ -394,7 +397,7 @@ void keyboard_scan_task(void) print_raw_state("init state"); if (recovery_key_pressed) - uart_puts("[KB recovery key pressed at init!]\n"); + CPUTS("[KB recovery key pressed at init!]\n"); /* Enable interrupts */ task_enable_irq(KB_SCAN_ROW_IRQ); diff --git a/chip/lm4/lpc.c b/chip/lm4/lpc.c index a5dfedefc8..29bd66d52c 100644 --- a/chip/lm4/lpc.c +++ b/chip/lm4/lpc.c @@ -6,6 +6,7 @@ /* LPC module for Chrome EC */ #include "board.h" +#include "console.h" #include "gpio.h" #include "hooks.h" #include "host_command.h" @@ -20,6 +21,10 @@ #include "uart.h" #include "util.h" +/* Console output macros */ +#define CPUTS(outstr) cputs(CC_LPC, outstr) +#define CPRINTF(format, args...) cprintf(CC_LPC, format, ## args) + #define LPC_SYSJUMP_TAG 0x4c50 /* "LP" */ static uint32_t host_events; /* Currently pending SCI/SMI events */ @@ -93,8 +98,8 @@ static void lpc_generate_smi(void) gpio_set_level(GPIO_PCH_SMIn, 1); if (host_events & event_mask[LPC_HOST_EVENT_SMI]) - uart_printf("[%T smi 0x%08x]\n", - host_events & event_mask[LPC_HOST_EVENT_SMI]); + CPRINTF("[%T smi 0x%08x]\n", + host_events & event_mask[LPC_HOST_EVENT_SMI]); } @@ -104,8 +109,8 @@ static void lpc_generate_sci(void) LM4_LPC_LPCCTL |= LM4_LPC_SCI_START; if (host_events & event_mask[LPC_HOST_EVENT_SCI]) - uart_printf("[%T sci 0x%08x]\n", - host_events & event_mask[LPC_HOST_EVENT_SCI]); + CPRINTF("[%T sci 0x%08x]\n", + host_events & event_mask[LPC_HOST_EVENT_SCI]); } @@ -343,8 +348,8 @@ static void lpc_interrupt(void) /* Debugging: print changes to LPC0RESET */ if (mis & (1 << 31)) { - uart_printf("[%T LPC RESET# %sasserted]\n", - (LM4_LPC_LPCSTS & (1<<10)) ? "" : "de"); + CPRINTF("[%T LPC RESET# %sasserted]\n", + (LM4_LPC_LPCSTS & (1<<10)) ? "" : "de"); } } DECLARE_IRQ(LM4_IRQ_LPC, lpc_interrupt, 2); diff --git a/chip/lm4/power_button.c b/chip/lm4/power_button.c index 837c67c214..f037cb2139 100644 --- a/chip/lm4/power_button.c +++ b/chip/lm4/power_button.c @@ -19,9 +19,12 @@ #include "system.h" #include "task.h" #include "timer.h" -#include "uart.h" #include "util.h" +/* Console output macros */ +#define CPUTS(outstr) cputs(CC_POWERBTN, outstr) +#define CPRINTF(format, args...) cprintf(CC_POWERBTN, format, ## args) + /* Power button state machine. * * PWRBTN# --- ---- @@ -100,7 +103,7 @@ static void update_other_switches(void) static void set_pwrbtn_to_pch(int high) { - uart_printf("[%T PB PCH pwrbtn=%s]\n", high ? "HIGH" : "LOW"); + CPRINTF("[%T PB PCH pwrbtn=%s]\n", high ? "HIGH" : "LOW"); gpio_set_level(GPIO_PCH_PWRBTNn, high); } @@ -160,7 +163,7 @@ static void state_machine(uint64_t tnow) if (!chipset_in_state(CHIPSET_STATE_SOFT_OFF)) set_pwrbtn_to_pch(0); else - uart_printf("[%T PB chipset already off]\n"); + CPRINTF("[%T PB chipset already off]\n"); pwrbtn_state = PWRBTN_STATE_HELD_DOWN; break; case PWRBTN_STATE_STOPPING: @@ -185,10 +188,10 @@ static void power_button_changed(uint64_t tnow) { if (pwrbtn_state == PWRBTN_STATE_BOOT_RECOVERY) { /* Ignore all power button changes during the recovery pulse */ - uart_printf("[%T PB changed during recovery pulse]\n"); + CPRINTF("[%T PB changed during recovery pulse]\n"); } else if (get_power_button_pressed()) { /* Power button pressed */ - uart_printf("[%T PB pressed]\n"); + CPRINTF("[%T PB pressed]\n"); pwrbtn_state = PWRBTN_STATE_START; tnext_state = tnow; *memmap_switches |= EC_LPC_SWITCH_POWER_BUTTON_PRESSED; @@ -199,12 +202,12 @@ static void power_button_changed(uint64_t tnow) /* Ignore the first power button release after a * keyboard-controlled reset, since we already told the PCH the * power button was released. */ - uart_printf("[%T PB released after keyboard reset]\n"); + CPRINTF("[%T PB released after keyboard reset]\n"); pwrbtn_state = PWRBTN_STATE_STOPPED; } else { /* Power button released normally (outside of a * keyboard-controlled reset) */ - uart_printf("[%T PB released]\n"); + CPRINTF("[%T PB released]\n"); pwrbtn_state = PWRBTN_STATE_STOPPING; tnext_state = tnow; *memmap_switches &= ~EC_LPC_SWITCH_POWER_BUTTON_PRESSED; @@ -216,7 +219,7 @@ static void power_button_changed(uint64_t tnow) /* Lid open */ static void lid_switch_open(uint64_t tnow) { - uart_printf("[%T PB lid open]\n"); + CPRINTF("[%T PB lid open]\n"); debounced_lid_open = 1; *memmap_switches |= EC_LPC_SWITCH_LID_OPEN; @@ -238,7 +241,7 @@ static void lid_switch_open(uint64_t tnow) /* Lid close */ static void lid_switch_close(uint64_t tnow) { - uart_printf("[%T PB lid close]\n"); + CPRINTF("[%T PB lid close]\n"); debounced_lid_open = 0; *memmap_switches &= ~EC_LPC_SWITCH_LID_OPEN; @@ -375,8 +378,7 @@ void power_button_task(void) * that can't happen - and even if it did, we'd just go * back to sleep after deciding that we woke up too * early.) */ - uart_printf("[%T PB task %d wait %d]\n", - pwrbtn_state, d); + CPRINTF("[%T PB task %d wait %d]\n", pwrbtn_state, d); task_wait_event(d); } } @@ -393,8 +395,8 @@ static int command_powerbtn(int argc, char **argv) if (argc > 1) { ms = strtoi(argv[1], &e, 0); if (*e) { - uart_puts("Invalid duration.\n" - "Usage: powerbtn [duration_ms]\n"); + ccputs("Invalid duration.\n" + "Usage: powerbtn [duration_ms]\n"); return EC_ERROR_INVAL; } } @@ -402,7 +404,7 @@ static int command_powerbtn(int argc, char **argv) /* Note that this only simulates the raw power button signal to the * PCH. It does not simulate the full state machine which sends SMIs * and other events to other parts of the EC and chipset. */ - uart_printf("Simulating %d ms power button press.\n", ms); + ccprintf("Simulating %d ms power button press.\n", ms); set_pwrbtn_to_pch(0); usleep(ms * 1000); set_pwrbtn_to_pch(1); diff --git a/chip/lm4/watchdog.c b/chip/lm4/watchdog.c index c13414c20e..ebca3f67d7 100644 --- a/chip/lm4/watchdog.c +++ b/chip/lm4/watchdog.c @@ -36,12 +36,10 @@ static uint32_t watchdog_period; /* Watchdog counter initial value */ int command_task_info(int argc, char **argv); int command_timer_info(int argc, char **argv); -/** - * watchdog debug trace. - * - * It is triggered if the watchdog has not been reloaded after 1x the timeout - * period, after 2x the period an hardware reset is triggering. - */ + +/* Watchdog debug trace. This is triggered if the watchdog has not been + * reloaded after 1x the timeout period, after 2x the period an hardware reset + * is triggering. */ void watchdog_trace(uint32_t excep_lr, uint32_t excep_sp) { uint32_t psp; @@ -168,11 +166,6 @@ int watchdog_init(void) /* Low priority task to reload the watchdog */ void watchdog_task(void) { - /* Print when the watchdog task starts. This is the lowest priority - * task, so this only starts once all other tasks have gotten a chance - * to do their task inits and have gone to sleep. */ - uart_printf("[watchdog task started at %d us]\n", get_time().le.lo); - while (1) { #ifdef BOARD_bds gpio_set_level(GPIO_DEBUG_LED, 1); diff --git a/chip/stm32l/keyboard_scan.c b/chip/stm32l/keyboard_scan.c index d627d14b70..4b63584f59 100644 --- a/chip/stm32l/keyboard_scan.c +++ b/chip/stm32l/keyboard_scan.c @@ -10,15 +10,19 @@ */ #include "board.h" +#include "console.h" #include "gpio.h" #include "keyboard.h" #include "keyboard_scan.h" #include "registers.h" #include "task.h" #include "timer.h" -#include "uart.h" #include "util.h" +/* Console output macros */ +#define CPUTS(outstr) cputs(CC_KEYSCAN, outstr) +#define CPRINTF(format, args...) cprintf(CC_KEYSCAN, format, ## args) + extern const struct gpio_info gpio_list[]; /* used for select_column() */ @@ -123,7 +127,7 @@ int keyboard_scan_init(void) { int i; - uart_printf("[kbscan %s()] initializing keyboard...\n", __func__); + CPRINTF("[kbscan %s()] initializing keyboard...\n", __func__); /* Tri-state (put into Hi-Z) the outputs */ select_column(COL_TRI_STATE_ALL); @@ -236,14 +240,14 @@ static int check_keys_changed(void) memcpy(saved_state, raw_state, sizeof(saved_state)); board_keyboard_scan_ready(); - uart_printf("[%d keys pressed: ", num_press); + CPRINTF("[%d keys pressed: ", num_press); for (c = 0; c < KB_COLS; c++) { if (raw_state[c]) - uart_printf(" %02x", raw_state[c]); + CPRINTF(" %02x", raw_state[c]); else - uart_puts(" --"); + CPUTS(" --"); } - uart_puts("]\n"); + CPUTS("]\n"); } return num_press ? 1 : 0; diff --git a/chip/stm32l/watchdog.c b/chip/stm32l/watchdog.c index 9d66ea75b7..1666d21525 100644 --- a/chip/stm32l/watchdog.c +++ b/chip/stm32l/watchdog.c @@ -5,8 +5,6 @@ /* Watchdog driver */ -#include <stdint.h> - #include "board.h" #include "common.h" #include "config.h" @@ -14,7 +12,6 @@ #include "gpio.h" #include "task.h" #include "timer.h" -#include "uart.h" #include "util.h" /* LSI oscillator frequency is typically 38 kHz @@ -28,12 +25,14 @@ #define IWDG_PRESCALER 6 #define IWDG_PRESCALER_DIV (1 << ((IWDG_PRESCALER) + 2)) + void watchdog_reload(void) { /* Reload the watchdog */ STM32L_IWDG_KR = 0xaaaa; } + int watchdog_init(int period_ms) { uint32_t watchdog_period; @@ -55,14 +54,10 @@ int watchdog_init(int period_ms) return EC_SUCCESS; } + /* Low priority task to reload the watchdog */ void watchdog_task(void) { - /* Print when the watchdog task starts. This is the lowest priority - * task, so this only starts once all other tasks have gotten a chance - * to do their task inits and have gone to sleep. */ - uart_printf("[watchdog task started at %d us]\n", get_time().le.lo); - while (1) { #ifdef BOARD_discovery gpio_set_level(GPIO_GREEN_LED, 1); diff --git a/common/charge_state.c b/common/charge_state.c index c17df6e97e..a47bb2f23d 100644 --- a/common/charge_state.c +++ b/common/charge_state.c @@ -20,10 +20,13 @@ #include "smart_battery.h" #include "system.h" #include "timer.h" -#include "uart.h" #include "util.h" #include "x86_power.h" +/* Console output macros */ +#define CPUTS(outstr) cputs(CC_CHARGER, outstr) +#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args) + /* Stop charge when state of charge reaches this percentage */ #define STOP_CHARGE_THRESHOLD 100 @@ -414,7 +417,7 @@ static enum power_state state_error(struct power_state_context *ctx) /* Debug output */ if (ctx->curr.error != logged_error) { - uart_printf("[Charge error: flag[%08b -> %08b], ac %d, " + CPRINTF("[Charge error: flag[%08b -> %08b], ac %d, " " charger %s, battery %s\n", logged_error, ctx->curr.error, ctx->curr.ac, (ctx->curr.error & F_CHARGER_MASK) ? @@ -439,7 +442,7 @@ static void charging_progress(struct power_state_context *ctx) else battery_time_to_empty(&minutes); - uart_printf("[Battery %3d%% / %dh:%d]\n", + CPRINTF("[Battery %3d%% / %dh:%d]\n", ctx->curr.batt.state_of_charge, minutes / 60, minutes % 60); return; @@ -455,7 +458,7 @@ static void charging_progress(struct power_state_context *ctx) seconds = (int)(get_time().val - ctx->trickle_charging_time.val) / (int)SECOND; minutes = seconds / 60; - uart_printf("[Precharge CHG(%dmV) BATT(%dmV %dmA) " + CPRINTF("[Precharge CHG(%dmV) BATT(%dmV %dmA) " "%dh:%d]\n", ctx->curr.charging_voltage, ctx->curr.batt.voltage, ctx->curr.batt.current, minutes / 60, minutes % 60); @@ -508,15 +511,15 @@ void charge_state_machine_task(void) new_state = state_error(&ctx); break; default: - uart_printf("[Undefined charging state %d]\n", - ctx.curr.state); + CPRINTF("[Undefined charging state %d]\n", + ctx.curr.state); ctx.curr.state = PWR_STATE_ERROR; new_state = PWR_STATE_ERROR; } if (new_state) { ctx.curr.state = new_state; - uart_printf("[Charge state %s -> %s]\n", + CPRINTF("[Charge state %s -> %s]\n", state_name[ctx.prev.state], state_name[new_state]); } diff --git a/common/console.c b/common/console.c index 29de7ef85a..0eff6e3529 100644 --- a/common/console.c +++ b/common/console.c @@ -15,19 +15,74 @@ #define PROMPT "> " +/* Default to all channels active */ +static uint32_t channel_mask = 0xffffffff; + +static char input_buf[80]; /* Current console command line */ + +/* List of channel names; must match enum console_channel. */ +/* TODO: move this to board.c */ +static const char *channel_names[CC_CHANNEL_COUNT] = { + "command", + "charger", + "hostcmd", + "i8042", + "keyboard", + "keyscan", + "lightbar", + "lpc", + "port80", + "powerbtn", + "system", + "task", + "usbcharge", + "x86power", +}; -void console_has_input(void) +/*****************************************************************************/ +/* Channel-based console output */ + +int cputs(enum console_channel channel, const char *outstr) { - /* Wake up the console task */ - task_wake(TASK_ID_CONSOLE); + /* Filter out inactive channels */ + if (!((1 << channel) & channel_mask)) + return EC_SUCCESS; + + return uart_puts(outstr); +} + + +int cprintf(enum console_channel channel, const char *format, ...) +{ + int rv; + va_list args; + + /* Filter out inactive channels */ + if (!((1 << channel) & channel_mask)) + return EC_SUCCESS; + + va_start(args, format); + rv = uart_vprintf(format, args); + va_end(args); + return rv; } +void cflush(void) +{ + uart_flush_output(); +} + + + +/*****************************************************************************/ +/* Console input */ + /* Splits a line of input into words. Stores the count of words in * <argc>. Stores pointers to the words in <argv>, which must be at * least <max_argc> long. If more than <max_argc> words are found, * discards the excess and returns EC_ERROR_OVERFLOW. */ -int split_words(char *input, int max_argc, int *argc, char **argv) +static int split_words(char *input, int max_argc, int *argc, char **argv) { char *c; int in_word = 0; @@ -63,7 +118,7 @@ int split_words(char *input, int max_argc, int *argc, char **argv) /* Finds a command by name. Returns the command structure, or NULL if * no match found. */ -const struct console_command *find_command(char *name) +static const struct console_command *find_command(char *name) { const struct console_command *cmd; @@ -96,15 +151,26 @@ static int handle_command(char *input) if (cmd) return cmd->handler(argc, argv); - uart_printf("Command '%s' not found.\n", argv[0]); + ccprintf("Command '%s' not found.\n", argv[0]); return EC_ERROR_UNKNOWN; } -static char input_buf[80]; +static int console_init(void) +{ + *input_buf = '\0'; + uart_set_console_mode(1); + uart_printf("Console is enabled; type HELP for help.\n"); + uart_puts(PROMPT); + + /* TODO: restore channel list from EEPROM */ + + return EC_SUCCESS; +} + /* handle a console command */ -void console_process(void) +static void console_process(void) { int rv; @@ -122,6 +188,14 @@ void console_process(void) } } + +void console_has_input(void) +{ + /* Wake up the console task */ + task_wake(TASK_ID_CONSOLE); +} + + void console_task(void) { console_init(); @@ -133,6 +207,7 @@ void console_task(void) } } + /*****************************************************************************/ /* Console commands */ @@ -152,7 +227,7 @@ static int command_help(int argc, char **argv) const char *next = "zzzz"; if (!(i % 5)) - uart_puts("\n "); + ccputs("\n "); /* Find the next command */ for (cmd = __cmds; cmd < __cmds_end; cmd++) { @@ -161,27 +236,55 @@ static int command_help(int argc, char **argv) next = cmd->name; } - uart_printf("%-15s", next); + ccprintf("%-15s", next); /* Generates enough output to overflow the buffer */ - uart_flush_output(); + cflush(); prev = next; } - uart_puts("\n"); + ccputs("\n"); return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(help, command_help); -/*****************************************************************************/ -/* Initialization */ -int console_init(void) +/* Set active channels */ +static int command_ch(int argc, char **argv) { - *input_buf = '\0'; - uart_set_console_mode(1); - uart_printf("Console is enabled; type HELP for help.\n"); - uart_puts(PROMPT); + int m; + char *e; + + /* If no args, print the list of channels */ + if (argc == 1) { + int i; + ccputs(" # Mask Enabled Channel\n"); + for (i = 0; i < CC_CHANNEL_COUNT; i++) { + ccprintf("%2d %08x %c %s\n", + i, 1 << i, + (channel_mask & (1 << i) ? '*' : ' '), + channel_names[i]); + } + return EC_SUCCESS; + } - return EC_SUCCESS; -} + /* If one arg, set the mask */ + if (argc == 2) { + m = strtoi(argv[1], &e, 0); + if (e && *e) { + ccputs("Invalid mask\n"); + return EC_ERROR_INVAL; + } + /* No disabling the command output channel */ + channel_mask = m | (1 << CC_COMMAND); + + /* TODO: save channel list to EEPROM */ + + return EC_SUCCESS; + } + + /* Otherwise, print help */ + ccputs("Usage: ch [newmask]\n"); + return EC_ERROR_INVAL; +}; +DECLARE_CONSOLE_COMMAND(ch, command_ch); diff --git a/common/host_command.c b/common/host_command.c index 09bc339e8b..8428edc497 100644 --- a/common/host_command.c +++ b/common/host_command.c @@ -13,9 +13,12 @@ #include "system.h" #include "task.h" #include "timer.h" -#include "uart.h" #include "util.h" +/* Console output macros */ +#define CPUTS(outstr) cputs(CC_SYSTEM, outstr) +#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args) + #define TASK_EVENT_SLOT(n) TASK_EVENT_CUSTOM(1 << n) static int host_command[2]; @@ -49,7 +52,7 @@ static enum lpc_status host_command_hello(uint8_t *data) struct lpc_response_hello *r = (struct lpc_response_hello *)data; uint32_t d = p->in_data; - uart_printf("[LPC Hello 0x%08x]\n", d); + CPRINTF("[LPC Hello 0x%08x]\n", d); #ifdef DELAY_HELLO_RESPONSE /* Pretend command takes a long time, so we can see the busy @@ -60,7 +63,7 @@ static enum lpc_status host_command_hello(uint8_t *data) usleep(1000000); #endif - uart_puts("[LPC sending hello back]\n"); + CPUTS("[LPC sending hello back]\n"); r->out_data = d + 0x01020304; return EC_LPC_RESULT_SUCCESS; @@ -133,7 +136,7 @@ static void command_process(int slot) uint8_t *data = lpc_get_host_range(slot); const struct host_command *cmd = find_host_command(command); - uart_printf("[hostcmd%d 0x%02x]\n", slot, command); + CPRINTF("[hostcmd%d 0x%02x]\n", slot, command); if (cmd) lpc_send_host_response(slot, cmd->handler(data)); diff --git a/common/i8042.c b/common/i8042.c index 5db0c98388..fa5a7bc512 100644 --- a/common/i8042.c +++ b/common/i8042.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved. +/* Copyright (c) 2012 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. * @@ -7,16 +7,28 @@ #include "board.h" #include "common.h" +#include "console.h" #include "i8042.h" #include "keyboard.h" #include "task.h" #include "timer.h" -#include "uart.h" #include "util.h" #define I8042_DEBUG 1 +/* Console output macros */ +#if I8042_DEBUG >= 4 +#define CPRINTF4(format, args...) cprintf(CC_I8042, format, ## args) +#else +#define CPRINTF4(format, args...) +#endif +#if I8042_DEBUG >= 5 +#define CPRINTF5(format, args...) cprintf(CC_I8042, format, ## args) +#else +#define CPRINTF5(format, args...) +#endif + #define MAX_QUEUED_KEY_PRESS 16 /* Circular buffer to host. @@ -113,12 +125,9 @@ void i8042_command_task(void) /* if the host still didn't read that away, try next time. */ if (keyboard_has_char()) { -#if I8042_DEBUG >= 5 - uart_printf("[%d] i8042_command_task() " - "cannot send to host due to host " - "havn't taken away.\n", - get_time().le.lo); -#endif + CPRINTF5("[%T i8042_command_task() " + "cannot send to host due to host " + "haven't taken away.\n"); break; } @@ -129,11 +138,8 @@ void i8042_command_task(void) /* Write to host. */ keyboard_put_char(chr, i8042_irq_enabled); -#if I8042_DEBUG >= 4 - uart_printf("[%d] i8042_command_task() " - "sends to host: 0x%02x\n", - get_time().le.lo, chr); -#endif + CPRINTF4("[%T i8042_command_task() " + "sends to host: 0x%02x\n", chr); } } } diff --git a/common/keyboard.c b/common/keyboard.c index 95d1586600..3764329d91 100644 --- a/common/keyboard.c +++ b/common/keyboard.c @@ -25,6 +25,23 @@ #define KEYBOARD_DEBUG 1 +/* Console output macros */ +#if KEYBOARD_DEBUG >= 1 +#define CPUTS(outstr) cputs(CC_KEYBOARD, outstr) +#define CPRINTF(format, args...) cprintf(CC_KEYBOARD, format, ## args) +#else +#define CPUTS(outstr) +#define CPRINTF(format, args...) +#endif + +#if KEYBOARD_DEBUG >= 5 +#define CPUTS5(outstr) cputs(CC_KEYBOARD, outstr) +#define CPRINTF5(format, args...) cprintf(CC_KEYBOARD, format, ## args) +#else +#define CPUTS5(outstr) +#define CPRINTF5(format, args...) +#endif + /* * i8042 global settings. @@ -34,9 +51,9 @@ static uint8_t resend_command[MAX_SCAN_CODE_LEN]; static uint8_t resend_command_len = 0; static uint8_t controller_ram_address; static uint8_t controller_ram[0x20] = { - /* the so called "command byte" */ - I8042_XLATE | I8042_AUX_DIS | I8042_KBD_DIS, - /* 0x01 - 0x1f are controller RAM */ + /* the so called "command byte" */ + I8042_XLATE | I8042_AUX_DIS | I8042_KBD_DIS, + /* 0x01 - 0x1f are controller RAM */ }; static int power_button_pressed = 0; static void keyboard_special(uint16_t k); @@ -70,13 +87,13 @@ static int typematic_len = 0; /* length of typematic_scan_code */ static uint8_t typematic_scan_code[MAX_SCAN_CODE_LEN]; -#define KB_SYSJUMP_TAG 0x4b42 // "KB" +#define KB_SYSJUMP_TAG 0x4b42 /* "KB" */ #define KB_HOOK_VERSION 1 /* the previous keyboard state before reboot_ec. */ struct kb_state { uint8_t codeset; uint8_t ctlram; - uint8_t pad[2]; // pad to 4 bytes for system_add_jump_tag(). + uint8_t pad[2]; /* Pad to 4 bytes for system_add_jump_tag(). */ }; @@ -84,41 +101,41 @@ struct kb_state { #define CROS_ROW_NUM 8 /* TODO: +1 for power button. */ #define CROS_COL_NUM 13 static uint16_t scancode_set1[CROS_ROW_NUM][CROS_COL_NUM] = { - {0x0000, 0xe05b, 0x003b, 0x0030, 0x0044, 0x0073, 0x0031, 0x0000, 0x000d, - 0x0000, 0xe038, 0x0000, 0x0000}, - {0x0000, 0x0001, 0x003e, 0x0022, 0x0041, 0x0000, 0x0023, 0x0000, 0x0028, - 0x0043, 0x0000, 0x000e, 0x0078}, - {0x001d, 0x000f, 0x003d, 0x0014, 0x0040, 0x001b, 0x0015, 0x0056, 0x001a, - 0x0042, 0x0073, 0x0000, 0x0000}, - {0x0000, 0x0029, 0x003c, 0x0006, 0x003f, 0x0000, 0x0007, 0x0000, 0x000c, - 0x0000, 0x0000, 0x002b, 0x0079}, - {0xe01d, 0x001e, 0x0020, 0x0021, 0x001f, 0x0025, 0x0024, 0x0000, 0x0027, - 0x0026, 0x002b, 0x001c, 0x0000}, - {0x0000, 0x002c, 0x002e, 0x002f, 0x002d, 0x0033, 0x0032, 0x002a, 0x0035, - 0x0034, 0x0000, 0x0039, 0x0000}, - {0x0000, 0x0002, 0x0004, 0x0005, 0x0003, 0x0009, 0x0008, 0x0000, 0x000b, - 0x000a, 0x0038, 0xe050, 0xe04d}, - {0x0000, 0x0010, 0x0012, 0x0013, 0x0011, 0x0017, 0x0016, 0x0036, 0x0019, - 0x0018, 0x0000, 0xe048, 0xe04b}, + {0x0000, 0xe05b, 0x003b, 0x0030, 0x0044, 0x0073, 0x0031, 0x0000, 0x000d, + 0x0000, 0xe038, 0x0000, 0x0000}, + {0x0000, 0x0001, 0x003e, 0x0022, 0x0041, 0x0000, 0x0023, 0x0000, 0x0028, + 0x0043, 0x0000, 0x000e, 0x0078}, + {0x001d, 0x000f, 0x003d, 0x0014, 0x0040, 0x001b, 0x0015, 0x0056, 0x001a, + 0x0042, 0x0073, 0x0000, 0x0000}, + {0x0000, 0x0029, 0x003c, 0x0006, 0x003f, 0x0000, 0x0007, 0x0000, 0x000c, + 0x0000, 0x0000, 0x002b, 0x0079}, + {0xe01d, 0x001e, 0x0020, 0x0021, 0x001f, 0x0025, 0x0024, 0x0000, 0x0027, + 0x0026, 0x002b, 0x001c, 0x0000}, + {0x0000, 0x002c, 0x002e, 0x002f, 0x002d, 0x0033, 0x0032, 0x002a, 0x0035, + 0x0034, 0x0000, 0x0039, 0x0000}, + {0x0000, 0x0002, 0x0004, 0x0005, 0x0003, 0x0009, 0x0008, 0x0000, 0x000b, + 0x000a, 0x0038, 0xe050, 0xe04d}, + {0x0000, 0x0010, 0x0012, 0x0013, 0x0011, 0x0017, 0x0016, 0x0036, 0x0019, + 0x0018, 0x0000, 0xe048, 0xe04b}, }; static uint16_t scancode_set2[CROS_ROW_NUM][CROS_COL_NUM] = { - {0x0000, 0xe01f, 0x0005, 0x0032, 0x0009, 0x0051, 0x0031, 0x0000, 0x0055, - 0x0000, 0xe011, 0x0000, 0x0000}, - {0x0000, 0x0076, 0x000c, 0x0034, 0x0083, 0x0000, 0x0033, 0x0000, 0x0052, - 0x0001, 0x0000, 0x0066, 0x0067}, - {0x0014, 0x000d, 0x0004, 0x002c, 0x000b, 0x005b, 0x0035, 0x0061, 0x0054, - 0x000a, 0x0051, 0x0000, 0x0000}, - {0x0000, 0x000e, 0x0006, 0x002e, 0x0003, 0x0000, 0x0036, 0x0000, 0x004e, - 0x0000, 0x0000, 0x005d, 0x0064}, - {0xe014, 0x001c, 0x0023, 0x002b, 0x001b, 0x0042, 0x003b, 0x0000, 0x004c, - 0x004b, 0x005d, 0x005a, 0x0000}, - {0x0000, 0x001a, 0x0021, 0x002a, 0x0022, 0x0041, 0x003a, 0x0012, 0x004a, - 0x0049, 0x0000, 0x0029, 0x0000}, - {0x0000, 0x0016, 0x0026, 0x0025, 0x001e, 0x003e, 0x003d, 0x0000, 0x0045, - 0x0046, 0x0011, 0xe072, 0xe074}, - {0x0000, 0x0015, 0x0024, 0x002d, 0x001d, 0x0043, 0x003c, 0x0059, 0x004d, - 0x0044, 0x0000, 0xe075, 0xe06b}, + {0x0000, 0xe01f, 0x0005, 0x0032, 0x0009, 0x0051, 0x0031, 0x0000, 0x0055, + 0x0000, 0xe011, 0x0000, 0x0000}, + {0x0000, 0x0076, 0x000c, 0x0034, 0x0083, 0x0000, 0x0033, 0x0000, 0x0052, + 0x0001, 0x0000, 0x0066, 0x0067}, + {0x0014, 0x000d, 0x0004, 0x002c, 0x000b, 0x005b, 0x0035, 0x0061, 0x0054, + 0x000a, 0x0051, 0x0000, 0x0000}, + {0x0000, 0x000e, 0x0006, 0x002e, 0x0003, 0x0000, 0x0036, 0x0000, 0x004e, + 0x0000, 0x0000, 0x005d, 0x0064}, + {0xe014, 0x001c, 0x0023, 0x002b, 0x001b, 0x0042, 0x003b, 0x0000, 0x004c, + 0x004b, 0x005d, 0x005a, 0x0000}, + {0x0000, 0x001a, 0x0021, 0x002a, 0x0022, 0x0041, 0x003a, 0x0012, 0x004a, + 0x0049, 0x0000, 0x0029, 0x0000}, + {0x0000, 0x0016, 0x0026, 0x0025, 0x001e, 0x003e, 0x003d, 0x0000, 0x0045, + 0x0046, 0x0011, 0xe072, 0xe074}, + {0x0000, 0x0015, 0x0024, 0x002d, 0x001d, 0x0043, 0x003c, 0x0059, 0x004d, + 0x0044, 0x0000, 0xe075, 0xe06b}, }; @@ -126,59 +143,56 @@ static uint16_t scancode_set2[CROS_ROW_NUM][CROS_COL_NUM] = { static uint8_t simulated_key[CROS_COL_NUM]; -/* change to set 1 if the I8042_XLATE flag is set. */ -static enum scancode_set_list acting_code_set(enum scancode_set_list set) { - if (controller_ram[0] & I8042_XLATE) { - /* If the keyboard translation is enabled, - * then always generates set 1. */ - return SCANCODE_SET_1; - } - return set; +/* Change to set 1 if the I8042_XLATE flag is set. */ +static enum scancode_set_list acting_code_set(enum scancode_set_list set) +{ + if (controller_ram[0] & I8042_XLATE) { + /* If the keyboard translation is enabled, then always + * generates set 1. */ + return SCANCODE_SET_1; + } + return set; } -static enum ec_error_list matrix_callback( - int8_t row, int8_t col, int8_t pressed, - enum scancode_set_list code_set, uint8_t *scan_code, int32_t* len) { +static enum ec_error_list matrix_callback(int8_t row, int8_t col, + int8_t pressed, + enum scancode_set_list code_set, + uint8_t *scan_code, int32_t* len) +{ + uint16_t make_code; - uint16_t make_code; + ASSERT(scan_code); + ASSERT(len); - ASSERT(scan_code); - ASSERT(len); + if (row > CROS_ROW_NUM || col > CROS_COL_NUM) + return EC_ERROR_INVAL; - if (row > CROS_ROW_NUM || - col > CROS_COL_NUM) { - return EC_ERROR_INVAL; - } + if (pressed) + keyboard_special(scancode_set1[row][col]); - if (pressed) - keyboard_special(scancode_set1[row][col]); + *len = 0; - *len = 0; + code_set = acting_code_set(code_set); - code_set = acting_code_set(code_set); + switch (code_set) { + case SCANCODE_SET_1: + make_code = scancode_set1[row][col]; + break; - switch (code_set) { - case SCANCODE_SET_1: - make_code = scancode_set1[row][col]; - break; + case SCANCODE_SET_2: + make_code = scancode_set2[row][col]; + break; - case SCANCODE_SET_2: - make_code = scancode_set2[row][col]; - break; + default: + CPRINTF("[Not supported scan code set: %d]\n", code_set); + return EC_ERROR_UNIMPLEMENTED; + } - default: -#if KEYBOARD_DEBUG >= 1 - uart_printf("[Not supported scan code set: %d]\n", code_set); -#endif - return EC_ERROR_UNIMPLEMENTED; - } - if (!make_code) { -#if KEYBOARD_DEBUG >= 1 - uart_printf("[No scancode for (row:col)=(%d:%d)]\n", row, col); -#endif - return EC_ERROR_UNIMPLEMENTED; - } + if (!make_code) { + CPRINTF("[No scancode for (row:col)=(%d:%d)]\n", row, col); + return EC_ERROR_UNIMPLEMENTED; + } /* Output the make code (from table) */ if (make_code >= 0x0100) { @@ -217,15 +231,17 @@ static enum ec_error_list matrix_callback( } -static void reset_rate_and_delay(void) { - typematic_value_from_host = DEFAULT_TYPEMATIC_VALUE; - refill_first_delay = DEFAULT_FIRST_DELAY; - refill_inter_delay = DEFAULT_INTER_DELAY; +static void reset_rate_and_delay(void) +{ + typematic_value_from_host = DEFAULT_TYPEMATIC_VALUE; + refill_first_delay = DEFAULT_FIRST_DELAY; + refill_inter_delay = DEFAULT_INTER_DELAY; } -static void clean_underlying_buffer(void) { - i8042_init(); +static void clean_underlying_buffer(void) +{ + i8042_init(); } @@ -235,380 +251,357 @@ static void clean_underlying_buffer(void) { * daisy(variants): no CONFIG_LPC and no CONFIG_TASK_X86POWER * crosbug.com/p/8523 */ -static void keyboard_wakeup(void) { +static void keyboard_wakeup(void) +{ #ifdef CONFIG_LPC - lpc_set_host_events(EC_LPC_HOST_EVENT_MASK(EC_LPC_HOST_EVENT_KEY_PRESSED)); + lpc_set_host_events( + EC_LPC_HOST_EVENT_MASK(EC_LPC_HOST_EVENT_KEY_PRESSED)); #endif } -void keyboard_state_changed(int row, int col, int is_pressed) { - uint8_t scan_code[MAX_SCAN_CODE_LEN]; - int32_t len; - enum ec_error_list ret; - -#if KEYBOARD_DEBUG >= 5 - uart_printf("[File %s:%s(): row=%d col=%d is_pressed=%d]\n", - __FILE__, __FUNCTION__, row, col, is_pressed); -#endif +void keyboard_state_changed(int row, int col, int is_pressed) +{ + uint8_t scan_code[MAX_SCAN_CODE_LEN]; + int32_t len; + enum ec_error_list ret; - ret = matrix_callback(row, col, is_pressed, scancode_set, scan_code, &len); - if (ret == EC_SUCCESS) { - ASSERT(len > 0); + CPRINTF5("[%s(): row=%d col=%d is_pressed=%d]\n", + __func__, row, col, is_pressed); - i8042_send_to_host(len, scan_code); - } + ret = matrix_callback(row, col, is_pressed, scancode_set, scan_code, + &len); + if (ret == EC_SUCCESS) { + ASSERT(len > 0); + i8042_send_to_host(len, scan_code); + } - if (is_pressed) { - keyboard_wakeup(); + if (is_pressed) { + keyboard_wakeup(); - typematic_delay = refill_first_delay * 1000; - memcpy(typematic_scan_code, scan_code, len); - typematic_len = len; - task_wake(TASK_ID_TYPEMATIC); - } else { - typematic_len = 0; - } + typematic_delay = refill_first_delay * 1000; + memcpy(typematic_scan_code, scan_code, len); + typematic_len = len; + task_wake(TASK_ID_TYPEMATIC); + } else { + typematic_len = 0; + } } -void keyboard_enable(int enable) { - if (!keyboard_enabled && enable) { - /* enable */ - } else if (keyboard_enabled && !enable) { - /* disable */ - reset_rate_and_delay(); - clean_underlying_buffer(); - } - keyboard_enabled = enable; +void keyboard_enable(int enable) +{ + if (!keyboard_enabled && enable) { + /* enable */ + } else if (keyboard_enabled && !enable) { + /* disable */ + reset_rate_and_delay(); + clean_underlying_buffer(); + } + keyboard_enabled = enable; } -uint8_t read_ctl_ram(uint8_t addr) { - if (addr < 0x20) // Controller RAM is only 32 bytes. - return controller_ram[addr]; - else - return 0; +uint8_t read_ctl_ram(uint8_t addr) +{ + if (addr < 0x20) /* Controller RAM is only 32 bytes. */ + return controller_ram[addr]; + else + return 0; } -/* Manipulates the controller_ram[]. Some bits change may trigger internal - * state change. - */ -void update_ctl_ram(uint8_t addr, uint8_t data) { - uint8_t orig; +/* Manipulate the controller_ram[]. Some bits change may trigger internal + * state change. */ +void update_ctl_ram(uint8_t addr, uint8_t data) +{ + uint8_t orig; - if (addr >= 0x20); // Controller RAM is only 32 bytes. - return; + if (addr >= 0x20) /* Controller RAM is only 32 bytes. */ + return; - orig = controller_ram[addr]; - controller_ram[addr] = data; -#if KEYBOARD_DEBUG >= 5 - uart_printf("[Set CTR_RAM(0x%02x)=0x%02x (old:0x%02x)]\n", - addr, data, orig); -#endif + orig = controller_ram[addr]; + controller_ram[addr] = data; + CPRINTF5("[Set CTR_RAM(0x%02x)=0x%02x (old:0x%02x)]\n", + addr, data, orig); - if (addr == 0x00) { /* the controller RAM */ - /* Handle the I8042_KBD_DIS bit */ - keyboard_enable(!(data & I8042_KBD_DIS)); + if (addr == 0x00) { /* the controller RAM */ + /* Handle the I8042_KBD_DIS bit */ + keyboard_enable(!(data & I8042_KBD_DIS)); - /* Handle the I8042_ENIRQ1 bit */ - if (!(orig & I8042_ENIRQ1) && (data & I8042_ENIRQ1)) { - i8042_enable_keyboard_irq(); - } else if ((orig & I8042_ENIRQ1) && !(data & I8042_ENIRQ1)) { - i8042_disable_keyboard_irq(); - } - } + /* Handle the I8042_ENIRQ1 bit */ + if (!(orig & I8042_ENIRQ1) && (data & I8042_ENIRQ1)) + i8042_enable_keyboard_irq(); + else if ((orig & I8042_ENIRQ1) && !(data & I8042_ENIRQ1)) + i8042_disable_keyboard_irq(); + } } enum { - STATE_NORMAL = 0, - STATE_SCANCODE, - STATE_SETLEDS, - STATE_EX_SETLEDS_1, /* expect 2-byte parameter coming */ - STATE_EX_SETLEDS_2, - STATE_WRITE_CMD_BYTE, - STATE_ECHO_MOUSE, - STATE_SETREP, - STATE_SEND_TO_MOUSE, + STATE_NORMAL = 0, + STATE_SCANCODE, + STATE_SETLEDS, + STATE_EX_SETLEDS_1, /* expect 2-byte parameter coming */ + STATE_EX_SETLEDS_2, + STATE_WRITE_CMD_BYTE, + STATE_ECHO_MOUSE, + STATE_SETREP, + STATE_SEND_TO_MOUSE, } data_port_state = STATE_NORMAL; -int handle_keyboard_data(uint8_t data, uint8_t *output) { - int out_len = 0; - int save_for_resend = 1; - int i; +int handle_keyboard_data(uint8_t data, uint8_t *output) +{ + int out_len = 0; + int save_for_resend = 1; + int i; + + CPRINTF5("[KB recv data: 0x%02x]\n", data); + + switch (data_port_state) { + case STATE_SCANCODE: + CPRINTF5("[Eaten by STATE_SCANCODE: 0x%02x]\n", data); + if (data == SCANCODE_GET_SET) { + output[out_len++] = I8042_RET_ACK; + output[out_len++] = scancode_set; + } else { + scancode_set = data; + CPRINTF("[Scancode set to %d]\n", scancode_set); + output[out_len++] = I8042_RET_ACK; + } + data_port_state = STATE_NORMAL; + break; + + case STATE_SETLEDS: + CPUTS5("[Eaten by STATE_SETLEDS]\n"); + output[out_len++] = I8042_RET_ACK; + data_port_state = STATE_NORMAL; + break; + + case STATE_EX_SETLEDS_1: + CPUTS5("[Eaten by STATE_EX_SETLEDS_1]\n"); + output[out_len++] = I8042_RET_ACK; + data_port_state = STATE_EX_SETLEDS_2; + break; + + case STATE_EX_SETLEDS_2: + CPUTS5("[Eaten by STATE_EX_SETLEDS_2]\n"); + output[out_len++] = I8042_RET_ACK; + data_port_state = STATE_NORMAL; + break; + + case STATE_WRITE_CMD_BYTE: + CPRINTF5("[Eaten by STATE_WRITE_CMD_BYTE: 0x%02x]\n", data); + update_ctl_ram(controller_ram_address, data); + output[out_len++] = I8042_RET_ACK; + data_port_state = STATE_NORMAL; + break; + + case STATE_ECHO_MOUSE: + CPRINTF5("[Eaten by STATE_ECHO_MOUSE: 0x%02x]\n", data); + output[out_len++] = I8042_RET_ACK; + output[out_len++] = data; + data_port_state = STATE_NORMAL; + break; + + case STATE_SETREP: + CPRINTF5("[Eaten by STATE_SETREP: 0x%02x]\n", data); + typematic_value_from_host = data; + refill_first_delay = + (((typematic_value_from_host & 0x60) >> 5) + 1) * 250; + refill_inter_delay = 1000 * /* ms */ + (1 << ((typematic_value_from_host & 0x18) >> 3)) * + ((typematic_value_from_host & 0x7) + 8) / + 240; + + output[out_len++] = I8042_RET_ACK; + data_port_state = STATE_NORMAL; + break; + + case STATE_SEND_TO_MOUSE: + CPRINTF5("[Eaten by STATE_SEND_TO_MOUSE: 0x%02x]\n", data); + data_port_state = STATE_NORMAL; + break; + + default: /* STATE_NORMAL */ + switch (data) { + case I8042_CMD_GSCANSET: /* also I8042_CMD_SSCANSET */ + output[out_len++] = I8042_RET_ACK; + data_port_state = STATE_SCANCODE; + break; -#if KEYBOARD_DEBUG >= 5 - uart_printf("[KB recv data: 0x%02x]\n", data); -#endif + case I8042_CMD_SETLEDS: + /* We use screen indicator. Do nothing in keyboard + * controller. */ + output[out_len++] = I8042_RET_ACK; + data_port_state = STATE_SETLEDS; + break; - switch (data_port_state) { - case STATE_SCANCODE: -#if KEYBOARD_DEBUG >= 5 - uart_printf("[Eaten by STATE_SCANCODE: 0x%02x]\n", data); -#endif - if (data == SCANCODE_GET_SET) { - output[out_len++] = I8042_RET_ACK; - output[out_len++] = scancode_set; - } else { - scancode_set = data; -#if KEYBOARD_DEBUG >= 1 - uart_printf("[Scancode set to %d]\n", scancode_set); -#endif - output[out_len++] = I8042_RET_ACK; - } - data_port_state = STATE_NORMAL; - break; + case I8042_CMD_EX_SETLEDS: + output[out_len++] = I8042_RET_ACK; + data_port_state = STATE_EX_SETLEDS_1; + break; - case STATE_SETLEDS: -#if KEYBOARD_DEBUG >= 5 - uart_printf("[Eaten by STATE_SETLEDS]\n"); -#endif - output[out_len++] = I8042_RET_ACK; - data_port_state = STATE_NORMAL; - break; + case I8042_CMD_DIAG_ECHO: + output[out_len++] = I8042_RET_ACK; + output[out_len++] = I8042_CMD_DIAG_ECHO; + break; - case STATE_EX_SETLEDS_1: -#if KEYBOARD_DEBUG >= 5 - uart_printf("[Eaten by STATE_EX_SETLEDS_1]\n"); -#endif - output[out_len++] = I8042_RET_ACK; - data_port_state = STATE_EX_SETLEDS_2; - break; + case I8042_CMD_GETID: /* fall-thru */ + case I8042_CMD_OK_GETID: + output[out_len++] = I8042_RET_ACK; + output[out_len++] = 0xab; /* Regular keyboards */ + output[out_len++] = 0x83; + break; - case STATE_EX_SETLEDS_2: -#if KEYBOARD_DEBUG >= 5 - uart_printf("[Eaten by STATE_EX_SETLEDS_2]\n"); -#endif - output[out_len++] = I8042_RET_ACK; - data_port_state = STATE_NORMAL; - break; + case I8042_CMD_SETREP: + output[out_len++] = I8042_RET_ACK; + data_port_state = STATE_SETREP; + break; - case STATE_WRITE_CMD_BYTE: -#if KEYBOARD_DEBUG >= 5 - uart_printf("[Eaten by STATE_WRITE_CMD_BYTE: 0x%02x]\n", data); -#endif - update_ctl_ram(controller_ram_address, data); - output[out_len++] = I8042_RET_ACK; - data_port_state = STATE_NORMAL; - break; + case I8042_CMD_ENABLE: + output[out_len++] = I8042_RET_ACK; + keyboard_enable(1); + break; - case STATE_ECHO_MOUSE: -#if KEYBOARD_DEBUG >= 5 - uart_printf("[Eaten by STATE_ECHO_MOUSE: 0x%02x]\n", data); -#endif - output[out_len++] = I8042_RET_ACK; - output[out_len++] = data; - data_port_state = STATE_NORMAL; - break; + case I8042_CMD_RESET_DIS: + output[out_len++] = I8042_RET_ACK; + keyboard_enable(0); + reset_rate_and_delay(); + clean_underlying_buffer(); + break; - case STATE_SETREP: -#if KEYBOARD_DEBUG >= 5 - uart_printf("[Eaten by STATE_SETREP: 0x%02x]\n", data); -#endif - typematic_value_from_host = data; - refill_first_delay = (((typematic_value_from_host & 0x60) >> 5) + 1) * 250; - refill_inter_delay = 1000 * /* ms */ - (1 << ((typematic_value_from_host & 0x18) >> 3)) * - ((typematic_value_from_host & 0x7) + 8) / - 240; - - output[out_len++] = I8042_RET_ACK; - data_port_state = STATE_NORMAL; - break; + case I8042_CMD_RESET_DEF: + output[out_len++] = I8042_RET_ACK; + reset_rate_and_delay(); + clean_underlying_buffer(); + break; - case STATE_SEND_TO_MOUSE: -#if KEYBOARD_DEBUG >= 5 - uart_printf("[Eaten by STATE_SEND_TO_MOUSE: 0x%02x]\n", data); -#endif - data_port_state = STATE_NORMAL; - break; + case I8042_CMD_RESET_BAT: + output[out_len++] = I8042_RET_ACK; + keyboard_enable(0); + output[out_len++] = I8042_RET_BAT; + output[out_len++] = I8042_RET_BAT; + break; - default: /* STATE_NORMAL */ - switch (data) { - case I8042_CMD_GSCANSET: /* also I8042_CMD_SSCANSET */ - output[out_len++] = I8042_RET_ACK; - data_port_state = STATE_SCANCODE; - break; - - case I8042_CMD_SETLEDS: - /* We use screen indicator. Do nothing in keyboard controller. */ - output[out_len++] = I8042_RET_ACK; - data_port_state = STATE_SETLEDS; - break; - - case I8042_CMD_EX_SETLEDS: - output[out_len++] = I8042_RET_ACK; - data_port_state = STATE_EX_SETLEDS_1; - break; - - case I8042_CMD_DIAG_ECHO: - output[out_len++] = I8042_RET_ACK; - output[out_len++] = I8042_CMD_DIAG_ECHO; - break; - - case I8042_CMD_GETID: /* fall-thru */ - case I8042_CMD_OK_GETID: - output[out_len++] = I8042_RET_ACK; - output[out_len++] = 0xab; /* Regular keyboards */ - output[out_len++] = 0x83; - break; - - case I8042_CMD_SETREP: - output[out_len++] = I8042_RET_ACK; - data_port_state = STATE_SETREP; - break; - - case I8042_CMD_ENABLE: - output[out_len++] = I8042_RET_ACK; - keyboard_enable(1); - break; - - case I8042_CMD_RESET_DIS: - output[out_len++] = I8042_RET_ACK; - keyboard_enable(0); - reset_rate_and_delay(); - clean_underlying_buffer(); - break; - - case I8042_CMD_RESET_DEF: - output[out_len++] = I8042_RET_ACK; - reset_rate_and_delay(); - clean_underlying_buffer(); - break; - - case I8042_CMD_RESET_BAT: - output[out_len++] = I8042_RET_ACK; - keyboard_enable(0); - output[out_len++] = I8042_RET_BAT; - output[out_len++] = I8042_RET_BAT; - break; - - case I8042_CMD_RESEND: - output[out_len++] = I8042_RET_ACK; - save_for_resend = 0; - for (i = 0; i < resend_command_len; ++i) { - output[out_len++] = resend_command[i]; - } - break; - - /* u-boot hack */ - case 0x60: /* see CONFIG_USE_CPCIDVI in */ - case 0x45: /* third_party/u-boot/files/drivers/input/i8042.c */ - /* just ignore, don't reply anything. */ - break; - - case I8042_CMD_SETALL_MB: /* fall-thru below */ - case I8042_CMD_SETALL_MBR: - case I8042_CMD_EX_ENABLE: - default: - output[out_len++] = I8042_RET_NAK; -#if KEYBOARD_DEBUG >= 1 - uart_printf("[Unsupported i8042 data 0x%02x]\n", data); -#endif - break; - } - } + case I8042_CMD_RESEND: + output[out_len++] = I8042_RET_ACK; + save_for_resend = 0; + for (i = 0; i < resend_command_len; ++i) + output[out_len++] = resend_command[i]; + break; - /* For resend, keep output before leaving. */ - if (out_len && save_for_resend) { - ASSERT(out_len <= MAX_SCAN_CODE_LEN); - for (i = 0; i < out_len; ++i) { - resend_command[i] = output[i]; - } - resend_command_len = out_len; - } + /* u-boot hack */ + case 0x60: /* see CONFIG_USE_CPCIDVI in */ + case 0x45: /* third_party/u-boot/files/drivers/input/i8042.c */ + /* just ignore, don't reply anything. */ + break; - ASSERT(out_len <= MAX_SCAN_CODE_LEN); - return out_len; + case I8042_CMD_SETALL_MB: /* fall-thru below */ + case I8042_CMD_SETALL_MBR: + case I8042_CMD_EX_ENABLE: + default: + output[out_len++] = I8042_RET_NAK; + CPRINTF("[Unsupported i8042 data 0x%02x]\n", data); + break; + } + } + + /* For resend, keep output before leaving. */ + if (out_len && save_for_resend) { + ASSERT(out_len <= MAX_SCAN_CODE_LEN); + for (i = 0; i < out_len; ++i) + resend_command[i] = output[i]; + resend_command_len = out_len; + } + + ASSERT(out_len <= MAX_SCAN_CODE_LEN); + return out_len; } -int handle_keyboard_command(uint8_t command, uint8_t *output) { - int out_len = 0; +int handle_keyboard_command(uint8_t command, uint8_t *output) +{ + int out_len = 0; -#if KEYBOARD_DEBUG >= 5 - uart_printf("[KB recv cmd: 0x%02x]\n", command); -#endif - switch (command) { - case I8042_READ_CMD_BYTE: - output[out_len++] = read_ctl_ram(0); - break; + CPRINTF5("[KB recv cmd: 0x%02x]\n", command); + switch (command) { + case I8042_READ_CMD_BYTE: + output[out_len++] = read_ctl_ram(0); + break; - case I8042_WRITE_CMD_BYTE: - data_port_state = STATE_WRITE_CMD_BYTE; - controller_ram_address = command - 0x60; - break; + case I8042_WRITE_CMD_BYTE: + data_port_state = STATE_WRITE_CMD_BYTE; + controller_ram_address = command - 0x60; + break; - case I8042_DIS_KB: - keyboard_enable(0); - break; + case I8042_DIS_KB: + keyboard_enable(0); + break; - case I8042_ENA_KB: - keyboard_enable(1); - break; + case I8042_ENA_KB: + keyboard_enable(1); + break; - case I8042_RESET_SELF_TEST: - output[out_len++] = 0x55; // Self test success. - break; + case I8042_RESET_SELF_TEST: + output[out_len++] = 0x55; /* Self test success */ + break; - case I8042_DIS_MOUSE: - update_ctl_ram(0, read_ctl_ram(0) | I8042_AUX_DIS); - break; + case I8042_DIS_MOUSE: + update_ctl_ram(0, read_ctl_ram(0) | I8042_AUX_DIS); + break; - case I8042_ENA_MOUSE: - update_ctl_ram(0, read_ctl_ram(0) & ~I8042_AUX_DIS); - break; + case I8042_ENA_MOUSE: + update_ctl_ram(0, read_ctl_ram(0) & ~I8042_AUX_DIS); + break; - case I8042_TEST_MOUSE: - output[out_len++] = 0; // no error detected - break; + case I8042_TEST_MOUSE: + output[out_len++] = 0; /* No error detected */ + break; - case I8042_ECHO_MOUSE: - data_port_state = STATE_ECHO_MOUSE; - break; + case I8042_ECHO_MOUSE: + data_port_state = STATE_ECHO_MOUSE; + break; - case I8042_SEND_TO_MOUSE: - data_port_state = STATE_SEND_TO_MOUSE; - break; + case I8042_SEND_TO_MOUSE: + data_port_state = STATE_SEND_TO_MOUSE; + break; #ifdef CONFIG_TASK_X86POWER - case I8042_SYSTEM_RESET: - /* Trigger a cold reset, since that also resets the TPM. If we just - * trigger a warm reset, that doesn't assert PLTRST# and the TPM is - * not reset. See crosbug.com/p/8379. */ - x86_power_reset(1); - break; + case I8042_SYSTEM_RESET: + /* Trigger a cold reset, since that also resets the TPM. If we + * just trigger a warm reset, that doesn't assert PLTRST# and + * the TPM is not reset. See crosbug.com/p/8379. */ + x86_power_reset(1); + break; #endif - default: - if (command >= I8042_READ_CTL_RAM && - command <= I8042_READ_CTL_RAM_END) { - output[out_len++] = read_ctl_ram(command - 0x20); - } else if (command >= I8042_WRITE_CTL_RAM && - command <= I8042_WRITE_CTL_RAM_END) { - data_port_state = STATE_WRITE_CMD_BYTE; - controller_ram_address = command - 0x60; - } else if (command >= I8042_PULSE_START && - command <= I8042_PULSE_END) { - /* Pulse Output Bit. Not implemented. Ignore it. */ - } else { -#if KEYBOARD_DEBUG >= 1 - uart_printf("[Unsupported cmd: 0x%02x]\n", command); -#endif - reset_rate_and_delay(); - clean_underlying_buffer(); - output[out_len++] = I8042_RET_NAK; - data_port_state = STATE_NORMAL; - } - break; - } + default: + if (command >= I8042_READ_CTL_RAM && + command <= I8042_READ_CTL_RAM_END) { + output[out_len++] = read_ctl_ram(command - 0x20); + } else if (command >= I8042_WRITE_CTL_RAM && + command <= I8042_WRITE_CTL_RAM_END) { + data_port_state = STATE_WRITE_CMD_BYTE; + controller_ram_address = command - 0x60; + } else if (command >= I8042_PULSE_START && + command <= I8042_PULSE_END) { + /* Pulse Output Bit. Not implemented. Ignore it. */ + } else { + CPRINTF("[Unsupported cmd: 0x%02x]\n", command); + reset_rate_and_delay(); + clean_underlying_buffer(); + output[out_len++] = I8042_RET_NAK; + data_port_state = STATE_NORMAL; + } + break; + } - return out_len; + return out_len; } + /* U U D D L R L R b a */ static void keyboard_special(uint16_t k) { @@ -621,6 +614,7 @@ static void keyboard_special(uint16_t k) s = 0; else if (s != 2) s = 1; + if (s == ARRAY_SIZE(a)) { s = 0; #ifdef CONFIG_TASK_LIGHTBAR @@ -629,6 +623,7 @@ static void keyboard_special(uint16_t k) } } + void keyboard_set_power_button(int pressed) { enum scancode_set_list code_set; @@ -657,23 +652,23 @@ void keyboard_set_power_button(int pressed) } - void keyboard_typematic_task(void) { - while (1) { - task_wait_event(-1); - - while (typematic_len) { - usleep(TYPEMATIC_DELAY_UNIT); - typematic_delay -= TYPEMATIC_DELAY_UNIT; - - if (typematic_delay <= 0) { - /* re-send to host */ - i8042_send_to_host(typematic_len, typematic_scan_code); - typematic_delay = refill_inter_delay * 1000; - } - } - } + while (1) { + task_wait_event(-1); + + while (typematic_len) { + usleep(TYPEMATIC_DELAY_UNIT); + typematic_delay -= TYPEMATIC_DELAY_UNIT; + + if (typematic_delay <= 0) { + /* re-send to host */ + i8042_send_to_host(typematic_len, + typematic_scan_code); + typematic_delay = refill_inter_delay * 1000; + } + } + } } @@ -682,30 +677,30 @@ static int command_typematic(int argc, char **argv) if (argc == 1) { int i; - uart_printf("Value set from host: 0x%02x\n", + ccprintf("Value set from host: 0x%02x\n", typematic_value_from_host); - uart_printf("Refill first delay : %d (ms)\n", + ccprintf("Refill first delay : %d (ms)\n", refill_first_delay); - uart_printf(" inter delay : %d (ms)\n", + ccprintf(" inter delay : %d (ms)\n", refill_inter_delay); - uart_printf("Current delay : %d (us)\n", + ccprintf("Current delay : %d (us)\n", typematic_delay); - uart_puts("Repeat scan code : "); + ccputs("Repeat scan code : "); for (i = 0; i < typematic_len; ++i) { - uart_printf("0x%02x ", typematic_scan_code[i]); + ccprintf("0x%02x ", typematic_scan_code[i]); } - uart_puts("\n"); + ccputs("\n"); } else if (argc == 3) { refill_first_delay = strtoi(argv[1], NULL, 0); refill_inter_delay = strtoi(argv[2], NULL, 0); - uart_puts("New typematic delays:\n"); - uart_printf(" Refill first delay : %d (ms)\n", + ccputs("New typematic delays:\n"); + ccprintf(" Refill first delay : %d (ms)\n", refill_first_delay); - uart_printf(" Refill inter delay : %d (ms)\n", + ccprintf(" Refill inter delay : %d (ms)\n", refill_inter_delay); } else { - uart_puts("Usage: typematic [<first> <inter>]\n"); + ccputs("Usage: typematic [<first> <inter>]\n"); return EC_ERROR_UNKNOWN; } @@ -719,8 +714,8 @@ static int command_codeset(int argc, char **argv) int set; if (argc == 1) { - uart_printf("Current scancode set: %d\n", scancode_set); - uart_printf("I8042_XLATE: %d\n", + ccprintf("Current scancode set: %d\n", scancode_set); + ccprintf("I8042_XLATE: %d\n", controller_ram[0] & I8042_XLATE ? 1 : 0); } else if (argc == 2) { set = strtoi(argv[1], NULL, 0); @@ -728,15 +723,15 @@ static int command_codeset(int argc, char **argv) case SCANCODE_SET_1: /* fall-thru */ case SCANCODE_SET_2: /* fall-thru */ scancode_set = set; - uart_printf("Set scancode set to %d\n", scancode_set); + ccprintf("Set scancode set to %d\n", scancode_set); break; default: - uart_printf("Scancode %d is NOT supported.\n", set); + ccprintf("Scancode %d is NOT supported.\n", set); return EC_ERROR_UNKNOWN; break; } } else { - uart_puts("Usage: codeset [<set>]\n"); + ccputs("Usage: codeset [<set>]\n"); return EC_ERROR_UNKNOWN; } @@ -753,23 +748,23 @@ static int command_controller_ram(int argc, char **argv) if (argc >= 2) { index = strtoi(argv[1], NULL, 0); - uart_printf("Controller RAM index = %d\n", index); + ccprintf("Controller RAM index = %d\n", index); if (index >= 0x20) { - uart_printf("Index is out of range (0x00-0x1f).\n"); + ccprintf("Index is out of range (0x00-0x1f).\n"); return EC_ERROR_UNKNOWN; } if (argc >= 3) { update_ctl_ram(index, strtoi(argv[2], NULL, 0)); - uart_printf("Write ctlram[%d] as 0x%02x.\n", + ccprintf("Write ctlram[%d] as 0x%02x.\n", index, controller_ram[index]); } else { - uart_printf("ctlram[%d] is 0x%02x.\n", + ccprintf("ctlram[%d] is 0x%02x.\n", index, controller_ram[index]); } } else { - uart_puts("Usage: ctrlram <index> [<write_value>]\n"); - uart_puts("\nGet/set controller RAM.\n\n"); + ccputs("Usage: ctrlram <index> [<write_value>]\n"); + ccputs("\nGet/set controller RAM.\n\n"); return EC_ERROR_UNKNOWN; } @@ -786,30 +781,30 @@ static int command_keyboard_press(int argc, char **argv) int r, c, p; char *e; if (argc == 1) { - uart_puts("Simulated key:\n"); + ccputs("Simulated key:\n"); for (i = 0; i < CROS_COL_NUM; ++i) { if (simulated_key[i] == 0) continue; for (j = 0; j < CROS_ROW_NUM; ++j) if (simulated_key[i] & (1 << j)) - uart_printf("\t%d %d\n", i, j); + ccprintf("\t%d %d\n", i, j); } } else if (argc == 4) { c = strtoi(argv[1], &e, 0); if ((e && *e) || c < 0 || c >= CROS_COL_NUM) { - uart_puts("Bad column.\n"); + ccputs("Bad column.\n"); return EC_ERROR_UNKNOWN; } r = strtoi(argv[2], &e, 0); if ((e && *e) || r < 0 || r >= CROS_ROW_NUM) { - uart_puts("Bad row.\n"); + ccputs("Bad row.\n"); return EC_ERROR_UNKNOWN; } p = strtoi(argv[3], &e, 0); if ((e && *e) || p < 0 || p > 1) { - uart_puts("Bad pressed flag.\n"); + ccputs("Bad pressed flag.\n"); return EC_ERROR_UNKNOWN; } @@ -820,7 +815,7 @@ static int command_keyboard_press(int argc, char **argv) keyboard_state_changed(r, c, p); } else { - uart_puts("Usage: kbpress [<col> <row> <pressed>]\n"); + ccputs("Usage: kbpress [<col> <row> <pressed>]\n"); return EC_ERROR_UNKNOWN; } @@ -862,7 +857,7 @@ static int keyboard_restore_state(void) prev = (const struct kb_state *)system_get_jump_tag(KB_SYSJUMP_TAG, &version, &size); if (prev && version == KB_HOOK_VERSION && size == sizeof(*prev)) { - // Coming back from a sysjump, so restore settings. + /* Coming back from a sysjump, so restore settings. */ scancode_set = prev->codeset; update_ctl_ram(0, prev->ctlram); } diff --git a/common/lightbar.c b/common/lightbar.c index f2e95e3a74..c2d8ccbab3 100644 --- a/common/lightbar.c +++ b/common/lightbar.c @@ -13,9 +13,12 @@ #include "lightbar.h" #include "task.h" #include "timer.h" -#include "uart.h" #include "util.h" +/* Console output macros */ +#define CPUTS(outstr) cputs(CC_LIGHTBAR, outstr) +#define CPRINTF(format, args...) cprintf(CC_LIGHTBAR, format, ## args) + /******************************************************************************/ /* How to talk to the controller */ /******************************************************************************/ @@ -92,7 +95,7 @@ static void set_from_array(const struct initdata_s *data, int count) static void lightbar_init_vals(void) { - uart_printf("[%s()]\n", __func__); + CPRINTF("[%s()]\n", __func__); set_from_array(init_vals, ARRAY_SIZE(init_vals)); } @@ -141,7 +144,7 @@ static void setrgb(int led, int red, int green, int blue) static void lightbar_off(void) { - uart_printf("[%s()]\n", __func__); + CPRINTF("[%s()]\n", __func__); /* Just go into standby mode. No register values should change. */ controller_write(0, 0x01, 0x00); controller_write(1, 0x01, 0x00); @@ -149,7 +152,7 @@ static void lightbar_off(void) static void lightbar_on(void) { - uart_printf("[%s()]\n", __func__); + CPRINTF("[%s()]\n", __func__); /* Come out of standby mode. */ controller_write(0, 0x01, 0x20); controller_write(1, 0x01, 0x20); @@ -171,7 +174,7 @@ static void lightbar_setrgb(int led, int red, int green, int blue) static inline void lightbar_brightness(int newval) { int i; - uart_printf("%s[(%d)]\n", __func__, newval); + CPRINTF("%s[(%d)]\n", __func__, newval); brightness = newval; for (i = 0; i < NUM_LEDS; i++) lightbar_setrgb(i, current[i][0], @@ -208,7 +211,7 @@ static const struct { static uint32_t sequence_s5(void) { int i; - uart_printf("[%s()]\n", __func__); + CPRINTF("[%s()]\n", __func__); /* For now, do something to indicate S5. We might see it. */ lightbar_on(); @@ -226,7 +229,7 @@ static uint32_t sequence_s5s3(void) { int i; - uart_printf("[%s()]\n", __func__); + CPRINTF("[%s()]\n", __func__); /* The controllers need 100us after power is applied before they'll * respond. */ usleep(100); @@ -248,7 +251,7 @@ static uint32_t sequence_s0(void) int l = 0; int n = 0; - uart_printf("[%s()]\n", __func__); + CPRINTF("[%s()]\n", __func__); lightbar_on(); while (1) { @@ -270,7 +273,7 @@ static uint32_t sequence_s0(void) /* CPU is going to sleep */ static uint32_t sequence_s0s3(void) { - uart_printf("[%s()]\n", __func__); + CPRINTF("[%s()]\n", __func__); lightbar_on(); lightbar_setrgb(0, 0, 0, 255); lightbar_setrgb(1, 255, 0, 0); @@ -291,7 +294,7 @@ static uint32_t sequence_s0s3(void) static uint32_t sequence_s3(void) { int i = 0; - uart_printf("[%s()]\n", __func__); + CPRINTF("[%s()]\n", __func__); lightbar_off(); lightbar_init_vals(); lightbar_setrgb(0, 0, 0, 0); @@ -316,7 +319,7 @@ static uint32_t sequence_s3(void) /* CPU is waking from sleep */ static uint32_t sequence_s3s0(void) { - uart_printf("[%s()]\n", __func__); + CPRINTF("[%s()]\n", __func__); lightbar_init_vals(); lightbar_on(); lightbar_setrgb(0, 0, 0, 255); @@ -335,7 +338,7 @@ static uint32_t sequence_s3s5(void) { int i; - uart_printf("[%s()]\n", __func__); + CPRINTF("[%s()]\n", __func__); /* For now, do something to indicate this transition. * We might see it. */ @@ -354,7 +357,7 @@ static uint32_t sequence_test(void) int kmax = 254; int kstep = 8; - uart_printf("[%s()]\n", __func__); + CPRINTF("[%s()]\n", __func__); lightbar_init_vals(); lightbar_on(); @@ -403,7 +406,7 @@ static uint32_t sequence_pulse(void) {0x1a, g}, }; - uart_printf("[%s()]\n", __func__); + CPRINTF("[%s()]\n", __func__); lightbar_init_vals(); lightbar_on(); @@ -427,15 +430,15 @@ static uint32_t sequence_ec_stop(void) { uint32_t msg; - uart_printf("[%s()]\n", __func__); + CPRINTF("[%s()]\n", __func__); do { msg = TASK_EVENT_CUSTOM(task_wait_event(-1)); - uart_printf("[%s - got msg %x]\n", __func__, msg); + CPRINTF("[%s - got msg %x]\n", __func__, msg); } while (msg != LIGHTBAR_EC_RUN); /* FIXME: What should we do if the host shuts down? */ - uart_printf("[%s() - leaving]\n", __func__); + CPRINTF("[%s() - leaving]\n", __func__); return 0; } @@ -443,7 +446,7 @@ static uint32_t sequence_ec_stop(void) /* We shouldn't come here, but if we do it shouldn't hurt anything */ static uint32_t sequence_error(void) { - uart_printf("[%s()]\n", __func__); + CPRINTF("[%s()]\n", __func__); lightbar_init_vals(); lightbar_on(); @@ -540,7 +543,7 @@ static uint32_t sequence_konami(void) int i; int tmp; - uart_printf("[%s()]\n", __func__); + CPRINTF("[%s()]\n", __func__); lightbar_init_vals(); lightbar_on(); @@ -599,7 +602,7 @@ void lightbar_task(void) while (1) { msg = sequence[state](); - uart_printf("[%s(%d)]\n", __func__, msg); + CPRINTF("[%s(%d)]\n", __func__, msg); msg = TASK_EVENT_CUSTOM(msg); if (msg && msg < LIGHTBAR_NUM_SEQUENCES) { previous_state = state; @@ -635,7 +638,7 @@ void lightbar_task(void) /* Function to request a preset sequence from the lightbar task. */ void lightbar_sequence(enum lightbar_sequence num) { - uart_printf("[%s(%d)]\n", __func__, num); + CPRINTF("[%s(%d)]\n", __func__, num); if (num && num < LIGHTBAR_NUM_SEQUENCES) task_set_event(TASK_ID_LIGHTBAR, TASK_EVENT_WAKE | TASK_EVENT_CUSTOM(num), 0); @@ -669,14 +672,14 @@ DECLARE_HOST_COMMAND(EC_LPC_COMMAND_LIGHTBAR_TEST, lpc_cmd_test); static int help(const char *cmd) { - uart_printf("Usage: %s\n", cmd); - uart_printf(" %s off\n", cmd); - uart_printf(" %s init\n", cmd); - uart_printf(" %s on\n", cmd); - uart_printf(" %s msg NUM\n", cmd); - uart_printf(" %s brightness NUM\n", cmd); - uart_printf(" %s CTRL REG VAL\n", cmd); - uart_printf(" %s LED RED GREEN BLUE\n", cmd); + ccprintf("Usage: %s\n", cmd); + ccprintf(" %s off\n", cmd); + ccprintf(" %s init\n", cmd); + ccprintf(" %s on\n", cmd); + ccprintf(" %s msg NUM\n", cmd); + ccprintf(" %s brightness NUM\n", cmd); + ccprintf(" %s CTRL REG VAL\n", cmd); + ccprintf(" %s LED RED GREEN BLUE\n", cmd); return EC_ERROR_UNKNOWN; } @@ -691,7 +694,7 @@ static void dump_regs(void) reg = reglist[i]; d1 = controller_read(0, reg); d2 = controller_read(1, reg); - uart_printf(" %02x %02x %02x\n", reg, d1, d2); + ccprintf(" %02x %02x %02x\n", reg, d1, d2); } } diff --git a/common/port80.c b/common/port80.c index 77ff6fa471..f048a54884 100644 --- a/common/port80.c +++ b/common/port80.c @@ -8,9 +8,10 @@ #include "board.h" #include "console.h" #include "port80.h" -#include "uart.h" #include "util.h" +#define CPRINTF(format, args...) cprintf(CC_PORT80, format, ## args) + #define HISTORY_LEN 16 static uint8_t history[HISTORY_LEN]; @@ -24,7 +25,7 @@ void port_80_write(int data) * itself. Probably not worth the system overhead to buffer the data * and print it from a task, because we're printing a small amount of * data and uart_printf() doesn't block. */ - uart_printf("%c[%T Port 80: 0x%02x]", scroll ? '\n' : '\r', data); + CPRINTF("%c[%T Port 80: 0x%02x]", scroll ? '\n' : '\r', data); history[head] = data; head = (head + 1) & (HISTORY_LEN - 1); @@ -42,7 +43,7 @@ static int command_port80(int argc, char **argv) * (scrolling) or CR (non-scrolling). */ if (argc > 1 && !strcasecmp(argv[1], "scroll")) { scroll = !scroll; - uart_printf("port80 scrolling %sabled\n", + ccprintf("port80 scrolling %sabled\n", scroll ? "en" : "dis"); return EC_SUCCESS; } @@ -50,10 +51,10 @@ static int command_port80(int argc, char **argv) /* Technically, if a port 80 write comes in while we're * printing this, we could print an incorrect history. * Probably not worth the complexity to work around that. */ - uart_puts("Last port 80 writes:"); + ccputs("Last port 80 writes:"); for (i = 0; i < HISTORY_LEN; i++) - uart_printf(" %02x", history[(h + i) & (HISTORY_LEN - 1)]); - uart_puts(" <--newest\n"); + ccprintf(" %02x", history[(h + i) & (HISTORY_LEN - 1)]); + ccputs(" <--newest\n"); return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(port80, command_port80); diff --git a/common/system_common.c b/common/system_common.c index 0d1805b2ca..f1b5473eb7 100644 --- a/common/system_common.c +++ b/common/system_common.c @@ -16,6 +16,9 @@ #include "util.h" #include "version.h" +/* Console output macros */ +#define CPUTS(outstr) cputs(CC_SYSTEM, outstr) +#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args) struct jump_tag { uint16_t tag; @@ -330,12 +333,12 @@ int system_common_pre_init(void) static int command_sysinfo(int argc, char **argv) { - uart_printf("Reset cause: %d (%s)\n", + ccprintf("Reset cause: %d (%s)\n", system_get_reset_cause(), system_get_reset_cause_string()); - uart_printf("Scratchpad: 0x%08x\n", system_get_scratchpad()); - uart_printf("Firmware copy: %s\n", system_get_image_copy_string()); - uart_printf("Jumped to this copy: %s\n", + ccprintf("Scratchpad: 0x%08x\n", system_get_scratchpad()); + ccprintf("Firmware copy: %s\n", system_get_image_copy_string()); + ccprintf("Jumped to this copy: %s\n", system_jumped_to_this_image() ? "yes" : "no"); return EC_SUCCESS; } @@ -344,9 +347,9 @@ DECLARE_CONSOLE_COMMAND(sysinfo, command_sysinfo); static int command_chipinfo(int argc, char **argv) { - uart_printf("Chip vendor: %s\n", system_get_chip_vendor()); - uart_printf("Chip name: %s\n", system_get_chip_name()); - uart_printf("Chip revision: %s\n", system_get_chip_revision()); + ccprintf("Chip vendor: %s\n", system_get_chip_vendor()); + ccprintf("Chip name: %s\n", system_get_chip_name()); + ccprintf("Chip revision: %s\n", system_get_chip_revision()); return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(chipinfo, command_chipinfo); @@ -358,16 +361,16 @@ static int command_set_scratchpad(int argc, char **argv) char *e; if (argc < 2) { - uart_puts("Usage: scratchpad <value>\n"); + ccputs("Usage: scratchpad <value>\n"); return EC_ERROR_UNKNOWN; } s = strtoi(argv[1], &e, 0); if (*e) { - uart_puts("Invalid scratchpad value\n"); + ccputs("Invalid scratchpad value\n"); return EC_ERROR_UNKNOWN; } - uart_printf("Setting scratchpad to 0x%08x\n", s); + ccprintf("Setting scratchpad to 0x%08x\n", s); return system_set_scratchpad(s); } DECLARE_CONSOLE_COMMAND(setscratchpad, command_set_scratchpad); @@ -379,15 +382,15 @@ static int command_hibernate(int argc, char **argv) int microseconds = 0; if (argc < 2) { - uart_puts("Usage: hibernate <seconds> [<microseconds>]\n"); + ccputs("Usage: hibernate <seconds> [<microseconds>]\n"); return EC_ERROR_UNKNOWN; } seconds = strtoi(argv[1], NULL, 0); if (argc >= 3) microseconds = strtoi(argv[2], NULL, 0); - uart_printf("Hibernating for %d.%06d s ...\n", seconds, microseconds); - uart_flush_output(); + ccprintf("Hibernating for %d.%06d s ...\n", seconds, microseconds); + cflush(); system_hibernate(seconds, microseconds); @@ -398,13 +401,13 @@ DECLARE_CONSOLE_COMMAND(hibernate, command_hibernate); static int command_version(int argc, char **argv) { - uart_printf("RO version: %s\n", + ccprintf("RO version: %s\n", system_get_version(SYSTEM_IMAGE_RO)); - uart_printf("RW-A version: %s\n", + ccprintf("RW-A version: %s\n", system_get_version(SYSTEM_IMAGE_RW_A)); - uart_printf("RW-B version: %s\n", + ccprintf("RW-B version: %s\n", system_get_version(SYSTEM_IMAGE_RW_B)); - uart_printf("Current build: %s\n", system_get_build_info()); + ccprintf("Current build: %s\n", system_get_build_info()); return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(version, command_version); @@ -419,30 +422,30 @@ static int command_sysjump(int argc, char **argv) * be disabled. */ if (argc < 2) { - uart_puts("Usage: sysjump <RO | A | B | addr>\n"); + ccputs("Usage: sysjump <RO | A | B | addr>\n"); return EC_ERROR_INVAL; } /* Handle named images */ if (!strcasecmp(argv[1], "RO")) { - uart_puts("Jumping directly to RO image...\n"); + ccputs("Jumping directly to RO image...\n"); return system_run_image_copy(SYSTEM_IMAGE_RO); } else if (!strcasecmp(argv[1], "A")) { - uart_puts("Jumping directly to image A...\n"); + ccputs("Jumping directly to image A...\n"); return system_run_image_copy(SYSTEM_IMAGE_RW_A); } else if (!strcasecmp(argv[1], "B")) { - uart_puts("Jumping directly to image B...\n"); + ccputs("Jumping directly to image B...\n"); return system_run_image_copy(SYSTEM_IMAGE_RW_B); } /* Check for arbitrary address */ addr = strtoi(argv[1], &e, 0); if (e && *e) { - uart_puts("Invalid image address\n"); + ccputs("Invalid image address\n"); return EC_ERROR_INVAL; } - uart_printf("Jumping directly to 0x%08x...\n", addr); - uart_flush_output(); + ccprintf("Jumping directly to 0x%08x...\n", addr); + cflush(); jump_to_image(addr); return EC_SUCCESS; } @@ -451,8 +454,8 @@ DECLARE_CONSOLE_COMMAND(sysjump, command_sysjump); static int command_reboot(int argc, char **argv) { - uart_puts("Rebooting!\n\n\n"); - uart_flush_output(); + ccputs("Rebooting!\n\n\n"); + cflush(); system_reset(1); return EC_SUCCESS; } @@ -538,17 +541,17 @@ enum lpc_status host_command_reboot(uint8_t *data) switch (p->target) { case EC_LPC_IMAGE_RO: - uart_puts("[Rebooting to image RO!\n]"); + CPUTS("[Rebooting to image RO!\n]"); clean_busy_bits(); system_run_image_copy(SYSTEM_IMAGE_RO); break; case EC_LPC_IMAGE_RW_A: - uart_puts("[Rebooting to image A!]\n"); + CPUTS("[Rebooting to image A!]\n"); clean_busy_bits(); system_run_image_copy(SYSTEM_IMAGE_RW_A); break; case EC_LPC_IMAGE_RW_B: - uart_puts("[Rebooting to image B!]\n"); + CPUTS("[Rebooting to image B!]\n"); clean_busy_bits(); system_run_image_copy(SYSTEM_IMAGE_RW_B); break; diff --git a/common/uart_buffering.c b/common/uart_buffering.c index 6d08dbb9af..d83b34ea40 100644 --- a/common/uart_buffering.c +++ b/common/uart_buffering.c @@ -357,6 +357,7 @@ void uart_process(void) uart_tx_stop(); } + void uart_set_console_mode(int enable) { console_mode = enable; @@ -382,7 +383,7 @@ int uart_puts(const char *outstr) } -int uart_printf(const char *format, ...) +int uart_vprintf(const char *format, va_list args) { static const char int_chars[] = "0123456789abcdef"; static const char error_str[] = "ERROR"; @@ -394,12 +395,9 @@ int uart_printf(const char *format, ...) int is_left; int pad_zero; int pad_width; - va_list args; char *vstr; int vlen; - va_start(args, format); - while (*format && !dropped_chars) { int c = *format++; @@ -532,7 +530,6 @@ int uart_printf(const char *format, ...) vlen++; } } - va_end(args); if (uart_tx_stopped()) uart_tx_start(); @@ -541,6 +538,19 @@ int uart_printf(const char *format, ...) return dropped_chars ? EC_ERROR_OVERFLOW : EC_SUCCESS; } + +int uart_printf(const char *format, ...) +{ + int rv; + va_list args; + + va_start(args, format); + rv = uart_vprintf(format, args); + va_end(args); + return rv; +} + + void uart_flush_output(void) { /* Wait for buffer to empty */ diff --git a/common/usb_charge_commands.c b/common/usb_charge_commands.c index 006ef97ea8..a8a855841a 100644 --- a/common/usb_charge_commands.c +++ b/common/usb_charge_commands.c @@ -8,9 +8,12 @@ #include "console.h" #include "usb_charge.h" #include "host_command.h" -#include "uart.h" #include "util.h" +/* Console output macros */ +#define CPUTS(outstr) cputs(CC_USBCHARGE, outstr) +#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) + enum lpc_status usb_charge_command_set_mode(uint8_t *data) { @@ -18,8 +21,8 @@ enum lpc_status usb_charge_command_set_mode(uint8_t *data) (struct lpc_params_usb_charge_set_mode *)data; int rv; - uart_printf("[Setting USB port %d to mode %d]\n", - p->usb_port_id, p->mode); + CPRINTF("[Setting USB port %d to mode %d]\n", + p->usb_port_id, p->mode); rv = usb_charge_set_mode(p->usb_port_id, p->mode); if (rv != EC_SUCCESS) diff --git a/common/x86_power.c b/common/x86_power.c index 8cb1daaa55..de6a5cfe5d 100644 --- a/common/x86_power.c +++ b/common/x86_power.c @@ -16,10 +16,13 @@ #include "system.h" #include "task.h" #include "timer.h" -#include "uart.h" #include "util.h" #include "x86_power.h" +/* Console output macros */ +#define CPUTS(outstr) cputs(CC_X86POWER, outstr) +#define CPRINTF(format, args...) cprintf(CC_X86POWER, format, ## args) + /* Default timeout in us; if we've been waiting this long for an input * transition, just jump to the next state. */ #define DEFAULT_TIMEOUT 1000000 @@ -145,9 +148,9 @@ static int wait_in_signals(uint32_t want) while ((in_signals & in_want) != in_want) { if (task_wait_event(DEFAULT_TIMEOUT) == TASK_EVENT_TIMER) { update_in_signals(); - uart_printf("[x86 power timeout on input; " - "wanted 0x%04x, got 0x%04x]\n", - in_want, in_signals & in_want); + CPRINTF("[x86 power timeout on input; " + "wanted 0x%04x, got 0x%04x]\n", + in_want, in_signals & in_want); return EC_ERROR_TIMEOUT; } /* TODO: should really shrink the remaining timeout if we woke @@ -240,7 +243,7 @@ void x86_power_interrupt(enum gpio_signal signal) /*****************************************************************************/ /* Initialization */ -int x86_power_init(void) +static int x86_power_init(void) { /* Default to G3 state unless proven otherwise */ state = X86_G3; @@ -254,11 +257,11 @@ int x86_power_init(void) * through G3. */ if (system_jumped_to_this_image()) { if ((in_signals & IN_ALL_S0) == IN_ALL_S0) { - uart_puts("[x86 already in S0]\n"); + CPUTS("[x86 already in S0]\n"); state = X86_S0; } else { /* Force all signals to their G3 states */ - uart_puts("[x86 forcing G3]\n"); + CPUTS("[x86 forcing G3]\n"); gpio_set_level(GPIO_PCH_PWROK, 0); gpio_set_level(GPIO_ENABLE_VCORE, 0); gpio_set_level(GPIO_PCH_RCINn, 0); @@ -300,8 +303,8 @@ void x86_power_task(void) x86_power_init(); while (1) { - uart_printf("[%T x86 power state %d = %s, in 0x%04x]\n", - state, state_names[state], in_signals); + CPRINTF("[%T x86 power state %d = %s, in 0x%04x]\n", + state, state_names[state], in_signals); switch (state) { case X86_G3: @@ -460,11 +463,11 @@ void x86_power_task(void) static int command_x86power(int argc, char **argv) { /* Print current state */ - uart_printf("Current X86 state: %d (%s)\n", state, state_names[state]); + ccprintf("Current X86 state: %d (%s)\n", state, state_names[state]); /* Forcing a power state from EC is deprecated */ if (argc > 1) - uart_puts("Use 'powerbtn' instead of 'x86power s0'.\n"); + ccputs("Use 'powerbtn' instead of 'x86power s0'.\n"); return EC_SUCCESS; } @@ -481,7 +484,7 @@ static int command_x86reset(int argc, char **argv) is_cold = 0; /* Force the x86 to reset */ - uart_printf("Issuing x86 %s reset...\n", is_cold ? "cold" : "warm"); + ccprintf("Issuing x86 %s reset...\n", is_cold ? "cold" : "warm"); x86_power_reset(is_cold); return EC_SUCCESS; } diff --git a/core/cortex-m/task.c b/core/cortex-m/task.c index b22a336dde..5a9f3d7c84 100644 --- a/core/cortex-m/task.c +++ b/core/cortex-m/task.c @@ -12,7 +12,6 @@ #include "link_defs.h" #include "task.h" #include "timer.h" -#include "uart.h" #include "util.h" /** @@ -68,6 +67,11 @@ extern int __task_start(int *need_resched); /* Idle task. Executed when no tasks are ready to be scheduled. */ void __idle(void) { + /* Print when the idle task starts. This is the lowest priority task, + * so this only starts once all other tasks have gotten a chance to do + * their task inits and have gone to sleep. */ + cprintf(CC_TASK, "[%T idle task started]\n"); + while (1) { /* Wait for the irq event */ asm("wfi"); @@ -79,7 +83,7 @@ void __idle(void) static void task_exit_trap(void) { int i = task_get_current(); - uart_printf("[Task %d (%s) exited!]\n", i, task_names[i]); + cprintf(CC_TASK, "[%T Task %d (%s) exited!]\n", i, task_names[i]); /* Exited tasks simply sleep forever */ while (1) task_wait_event(-1); @@ -473,26 +477,26 @@ int command_task_info(int argc, char **argv) int i; #ifdef CONFIG_TASK_PROFILING - uart_printf("Task switching started: %10ld us\n", task_start_time); - uart_printf("Time in tasks: %10ld us\n", + ccprintf("Task switching started: %10ld us\n", task_start_time); + ccprintf("Time in tasks: %10ld us\n", get_time().val - task_start_time); - uart_printf("Time in exceptions: %10ld us\n", exc_total_time); - uart_flush_output(); - uart_printf("Service calls: %10d\n", svc_calls); - uart_puts("IRQ counts by type:\n"); + ccprintf("Time in exceptions: %10ld us\n", exc_total_time); + cflush(); + ccprintf("Service calls: %10d\n", svc_calls); + ccputs("IRQ counts by type:\n"); for (i = 0; i < ARRAY_SIZE(irq_dist); i++) { if (irq_dist[i]) - uart_printf("%4d %8d\n", i, irq_dist[i]); + ccprintf("%4d %8d\n", i, irq_dist[i]); } #endif - uart_puts("Task Ready Name Events Time (us)\n"); + ccputs("Task Ready Name Events Time (us)\n"); for (i = 0; i < TASK_ID_COUNT; i++) { char is_ready = (tasks_ready & (1<<i)) ? 'R' : ' '; - uart_printf("%4d %c %-16s %08x %10ld\n", i, is_ready, - task_names[i], tasks[i].events, tasks[i].runtime); - uart_flush_output(); + ccprintf("%4d %c %-16s %08x %10ld\n", i, is_ready, + task_names[i], tasks[i].events, tasks[i].runtime); + cflush(); } @@ -504,10 +508,10 @@ DECLARE_CONSOLE_COMMAND(taskinfo, command_task_info); static int command_task_ready(int argc, char **argv) { if (argc < 2) { - uart_printf("tasks_ready: 0x%08x\n", tasks_ready); + ccprintf("tasks_ready: 0x%08x\n", tasks_ready); } else { tasks_ready = strtoi(argv[1], NULL, 16); - uart_printf("Setting tasks_ready to 0x%08x\n", tasks_ready); + ccprintf("Setting tasks_ready to 0x%08x\n", tasks_ready); __schedule(0, 0); } diff --git a/include/console.h b/include/console.h index 4aeca1c5f4..b0d3f5b63e 100644 --- a/include/console.h +++ b/include/console.h @@ -1,16 +1,16 @@ -/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved. +/* Copyright (c) 2012 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. */ -/* console.h - Debug console for Chrome EC */ +/* Debug console for Chrome EC */ #ifndef __CROS_EC_CONSOLE_H #define __CROS_EC_CONSOLE_H #include "common.h" -/* Console command */ +/* Console command; used by DECLARE_CONSOLE_COMMAND macro. */ struct console_command { /* Command name. Case-insensitive. */ const char *name; @@ -19,13 +19,51 @@ struct console_command { }; -/* Initializes the console module. */ -int console_init(void); +/* Console channels */ +enum console_channel { + CC_COMMAND = 0, /* Console command (interactive I/O). Use this only + * inside a console command routine. */ + CC_CHARGER, + CC_HOSTCMD, + CC_I8042, + CC_KEYBOARD, + CC_KEYSCAN, + CC_LIGHTBAR, + CC_LPC, + CC_PORT80, + CC_POWERBTN, + CC_SYSTEM, + CC_TASK, + CC_USBCHARGE, + CC_X86POWER, + /* Channel count; not itself a channel */ + CC_CHANNEL_COUNT +}; + +/* Put a string to the console channel. */ +int cputs(enum console_channel channel, const char *outstr); + +/* Print formatted output to the console channel. See uart_vprintf() for + * valid format codes. */ +int cprintf(enum console_channel channel, const char *format, ...); + +/* Flush the console output for all channels. */ +void cflush(void); + +/* Convenience macros for printing to the command channel. + * + * Modules may define similar macros in their .c files for their own use; it is + * recommended those module-specific macros be named CPUTS and CPRINTF. */ +#define ccputs(outstr) cputs(CC_COMMAND, outstr) +/* gcc allows variable arg lists in macros; see + * http://gcc.gnu.org/onlinedocs/gcc/Variadic-Macros.html */ +#define ccprintf(format, args...) cprintf(CC_COMMAND, format, ## args) /* Called by UART when a line of input is pending. */ void console_has_input(void); + /* Register a console command handler */ #define DECLARE_CONSOLE_COMMAND(name, routine) \ static const char __con_cmd_label_##name[] = #name; \ diff --git a/include/uart.h b/include/uart.h index 67a2968d6c..17922879bc 100644 --- a/include/uart.h +++ b/include/uart.h @@ -8,6 +8,7 @@ #ifndef __CROS_EC_UART_H #define __CROS_EC_UART_H +#include <stdarg.h> /* For va_list */ #include "common.h" @@ -55,6 +56,10 @@ int uart_puts(const char *outstr); * Floating point output (%f / %g) is not supported. */ int uart_printf(const char *format, ...); +/* Print formatted output to the UART, like vprintf(). Supports the same + * formatting codes as uart_printf(). */ +int uart_vprintf(const char *format, va_list args); + /* Flushes output. Blocks until UART has transmitted all output. */ void uart_flush_output(void); diff --git a/include/x86_power.h b/include/x86_power.h index fba3f0cc15..ec0adeb34e 100644 --- a/include/x86_power.h +++ b/include/x86_power.h @@ -11,9 +11,6 @@ #include "common.h" #include "gpio.h" -/* Initializes the module. */ -int x86_power_init(void); - /* Interrupt handler for input GPIOs */ void x86_power_interrupt(enum gpio_signal signal); |