diff --git a/chip/lm4/power_button.c b/chip/lm4/power_button.c index 3955d2edf8..415ebe6b5d 100644 --- a/chip/lm4/power_button.c +++ b/chip/lm4/power_button.c @@ -6,8 +6,8 @@ /* Power button and lid switch module for Chrome EC */ #include "chipset.h" +#include "common.h" #include "console.h" -#include "ec_commands.h" #include "eoption.h" #include "gpio.h" #include "hooks.h" @@ -651,12 +651,12 @@ DECLARE_CONSOLE_COMMAND(mmapinfo, command_mmapinfo, /*****************************************************************************/ /* Host commands */ -int switch_command_enable_backlight(uint8_t *data, int *resp_size) +int switch_command_enable_backlight(struct host_cmd_handler_args *args) { - struct ec_params_switch_enable_backlight *p = - (struct ec_params_switch_enable_backlight *)data; + const struct ec_params_switch_enable_backlight *p = + (const struct ec_params_switch_enable_backlight *)args->params; gpio_set_level(GPIO_ENABLE_BACKLIGHT, p->enabled); return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_SWITCH_ENABLE_BKLIGHT, - switch_command_enable_backlight); + switch_command_enable_backlight, 0); diff --git a/chip/stm32/keyboard_scan.c b/chip/stm32/keyboard_scan.c index 40a0498476..99b08669aa 100644 --- a/chip/stm32/keyboard_scan.c +++ b/chip/stm32/keyboard_scan.c @@ -421,26 +421,33 @@ int keyboard_scan_recovery_pressed(void) return switches & EC_SWITCH_KEYBOARD_RECOVERY; } -static int keyboard_get_scan(uint8_t *data, int *resp_size) +static int keyboard_get_scan(struct host_cmd_handler_args *args) { - kb_fifo_remove(data); + kb_fifo_remove(args->response); if (!kb_fifo_entries) board_interrupt_host(0); - *resp_size = KB_OUTPUTS; + + args->response_size = KB_OUTPUTS; return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_MKBP_STATE, keyboard_get_scan); +DECLARE_HOST_COMMAND(EC_CMD_MKBP_STATE, + keyboard_get_scan, + EC_VER_MASK(0)); -static int keyboard_get_info(uint8_t *data, int *resp_size) +static int keyboard_get_info(struct host_cmd_handler_args *args) { - struct ec_response_mkbp_info *r = (struct ec_response_mkbp_info *)data; + struct ec_response_mkbp_info *r = + (struct ec_response_mkbp_info *)args->response; r->rows = 8; r->cols = KB_OUTPUTS; r->switches = switches; - *resp_size = sizeof(struct ec_response_mkbp_info); + args->response_size = sizeof(*r); + return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_MKBP_INFO, keyboard_get_info); +DECLARE_HOST_COMMAND(EC_CMD_MKBP_INFO, + keyboard_get_info, + EC_VER_MASK(0)); diff --git a/common/flash_commands.c b/common/flash_commands.c index 5df42504c5..d8953bc3c7 100644 --- a/common/flash_commands.c +++ b/common/flash_commands.c @@ -186,45 +186,48 @@ DECLARE_CONSOLE_COMMAND(flashwp, command_flash_wp, /*****************************************************************************/ /* Host commands */ -static int flash_command_get_info(uint8_t *data, int *resp_size) +static int flash_command_get_info(struct host_cmd_handler_args *args) { struct ec_response_flash_info *r = - (struct ec_response_flash_info *)data; + (struct ec_response_flash_info *)args->response; r->flash_size = flash_get_size(); r->write_block_size = flash_get_write_block_size(); r->erase_block_size = flash_get_erase_block_size(); r->protect_block_size = flash_get_protect_block_size(); - *resp_size = sizeof(struct ec_response_flash_info); + args->response_size = sizeof(*r); return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_FLASH_INFO, flash_command_get_info); +DECLARE_HOST_COMMAND(EC_CMD_FLASH_INFO, + flash_command_get_info, + EC_VER_MASK(0)); -static int flash_command_read(uint8_t *data, int *resp_size) +static int flash_command_read(struct host_cmd_handler_args *args) { - struct ec_params_flash_read *p = - (struct ec_params_flash_read *)data; - struct ec_response_flash_read *r = - (struct ec_response_flash_read *)data; + const struct ec_params_flash_read *p = + (const struct ec_params_flash_read *)args->params; - if (p->size > sizeof(r->data)) + if (p->size > EC_PARAM_SIZE) + return EC_RES_INVALID_PARAM; + + if (flash_dataptr(p->offset, p->size, 1, (char **)&args->response) < 0) return EC_RES_ERROR; - if (flash_read(p->offset, p->size, r->data)) - return EC_RES_ERROR; + args->response_size = p->size; - *resp_size = sizeof(struct ec_response_flash_read); return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_FLASH_READ, flash_command_read); +DECLARE_HOST_COMMAND(EC_CMD_FLASH_READ, + flash_command_read, + EC_VER_MASK(0)); -static int flash_command_write(uint8_t *data, int *resp_size) +static int flash_command_write(struct host_cmd_handler_args *args) { - struct ec_params_flash_write *p = - (struct ec_params_flash_write *)data; + const struct ec_params_flash_write *p = + (const struct ec_params_flash_write *)args->params; if (p->size > sizeof(p->data)) - return EC_RES_ERROR; + return EC_RES_INVALID_PARAM; if (system_unsafe_to_overwrite(p->offset, p->size)) return EC_RES_ACCESS_DENIED; @@ -234,12 +237,14 @@ static int flash_command_write(uint8_t *data, int *resp_size) return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_FLASH_WRITE, flash_command_write); +DECLARE_HOST_COMMAND(EC_CMD_FLASH_WRITE, + flash_command_write, + EC_VER_MASK(0)); -static int flash_command_erase(uint8_t *data, int *resp_size) +static int flash_command_erase(struct host_cmd_handler_args *args) { - struct ec_params_flash_erase *p = - (struct ec_params_flash_erase *)data; + const struct ec_params_flash_erase *p = + (const struct ec_params_flash_erase *)args->params; if (system_unsafe_to_overwrite(p->offset, p->size)) return EC_RES_ACCESS_DENIED; @@ -249,51 +254,64 @@ static int flash_command_erase(uint8_t *data, int *resp_size) return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_FLASH_ERASE, flash_command_erase); +DECLARE_HOST_COMMAND(EC_CMD_FLASH_ERASE, + flash_command_erase, + EC_VER_MASK(0)); -static int flash_command_wp_enable(uint8_t *data, int *resp_size) +static int flash_command_wp_enable(struct host_cmd_handler_args *args) { - struct ec_params_flash_wp_enable *p = - (struct ec_params_flash_wp_enable *)data; + const struct ec_params_flash_wp_enable *p = + (const struct ec_params_flash_wp_enable *)args->params; + /* + * TODO: this is wrong; needs to translate return code to EC_RES_*. + * But since this command is going away imminently, no rush. + */ return flash_lock_protect(p->enable_wp ? 1 : 0); } -DECLARE_HOST_COMMAND(EC_CMD_FLASH_WP_ENABLE, flash_command_wp_enable); +DECLARE_HOST_COMMAND(EC_CMD_FLASH_WP_ENABLE, + flash_command_wp_enable, + EC_VER_MASK(0)); -static int flash_command_wp_get_state(uint8_t *data, int *resp_size) +static int flash_command_wp_get_state(struct host_cmd_handler_args *args) { - struct ec_response_flash_wp_enable *p = - (struct ec_response_flash_wp_enable *)data; + struct ec_response_flash_wp_enable *r = + (struct ec_response_flash_wp_enable *)args->response; if (flash_get_protect_lock() & FLASH_PROTECT_LOCK_SET) - p->enable_wp = 1; + r->enable_wp = 1; else - p->enable_wp = 0; + r->enable_wp = 0; - *resp_size = sizeof(struct ec_response_flash_wp_enable); + args->response_size = sizeof(*r); return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_FLASH_WP_GET_STATE, flash_command_wp_get_state); +DECLARE_HOST_COMMAND(EC_CMD_FLASH_WP_GET_STATE, + flash_command_wp_get_state, + EC_VER_MASK(0)); -static int flash_command_wp_set_range(uint8_t *data, int *resp_size) +static int flash_command_wp_set_range(struct host_cmd_handler_args *args) { - struct ec_params_flash_wp_range *p = - (struct ec_params_flash_wp_range *)data; - enum ec_status ret; + const struct ec_params_flash_wp_range *p = + (const struct ec_params_flash_wp_range *)args->params; + /* + * TODO: this is wrong; needs to translate return code to EC_RES_*. + * But since this command is going away imminently, no rush. + */ if (p->size) - ret = flash_set_protect(p->offset, p->size, 1); + return flash_set_protect(p->offset, p->size, 1); else - ret = flash_set_protect(0, flash_get_size(), 0); - - return ret; + return flash_set_protect(0, flash_get_size(), 0); } -DECLARE_HOST_COMMAND(EC_CMD_FLASH_WP_SET_RANGE, flash_command_wp_set_range); +DECLARE_HOST_COMMAND(EC_CMD_FLASH_WP_SET_RANGE, + flash_command_wp_set_range, + EC_VER_MASK(0)); -static int flash_command_wp_get_range(uint8_t *data, int *resp_size) +static int flash_command_wp_get_range(struct host_cmd_handler_args *args) { - struct ec_response_flash_wp_range *p = - (struct ec_response_flash_wp_range *)data; + struct ec_response_flash_wp_range *r = + (struct ec_response_flash_wp_range *)args->response; int pbsize = flash_get_protect_block_size(); int banks = flash_get_size() / pbsize; const uint8_t *blocks; @@ -320,14 +338,16 @@ static int flash_command_wp_get_range(uint8_t *data, int *resp_size) /* TODO(crosbug.com/p/9492): return multiple region of ranges(). */ if (min == -1) { /* None of bank is protected. */ - p->offset = 0; - p->size = 0; + r->offset = 0; + r->size = 0; } else { - p->offset = min * pbsize; - p->size = (max - min + 1) * pbsize; + r->offset = min * pbsize; + r->size = (max - min + 1) * pbsize; } - *resp_size = sizeof(struct ec_response_flash_wp_range); + args->response_size = sizeof(*r); return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_FLASH_WP_GET_RANGE, flash_command_wp_get_range); +DECLARE_HOST_COMMAND(EC_CMD_FLASH_WP_GET_RANGE, + flash_command_wp_get_range, + EC_VER_MASK(0)); diff --git a/common/host_command.c b/common/host_command.c index db71c11261..58e144fddc 100644 --- a/common/host_command.c +++ b/common/host_command.c @@ -60,38 +60,43 @@ void host_command_received(int command) task_set_event(TASK_ID_HOSTCMD, TASK_EVENT_CMD_PENDING, 0); } - -static int host_command_proto_version(uint8_t *data, int *resp_size) +static int host_command_proto_version(struct host_cmd_handler_args *args) { struct ec_response_proto_version *r = - (struct ec_response_proto_version *)data; + (struct ec_response_proto_version *)args->response; r->version = EC_PROTO_VERSION; + args->response_size = sizeof(*r); - *resp_size = sizeof(struct ec_response_proto_version); return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_PROTO_VERSION, host_command_proto_version); +DECLARE_HOST_COMMAND(EC_CMD_PROTO_VERSION, + host_command_proto_version, + EC_VER_MASK(0)); - -static int host_command_hello(uint8_t *data, int *resp_size) +static int host_command_hello(struct host_cmd_handler_args *args) { - struct ec_params_hello *p = (struct ec_params_hello *)data; - struct ec_response_hello *r = (struct ec_response_hello *)data; + const struct ec_params_hello *p = + (const struct ec_params_hello *)args->params; + struct ec_response_hello *r = + (struct ec_response_hello *)args->response; uint32_t d = p->in_data; r->out_data = d + 0x01020304; - *resp_size = sizeof(struct ec_response_hello); + args->response_size = sizeof(*r); + return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_HELLO, host_command_hello); +DECLARE_HOST_COMMAND(EC_CMD_HELLO, + host_command_hello, + EC_VER_MASK(0)); - -static int host_command_read_test(uint8_t *data, int *resp_size) +static int host_command_read_test(struct host_cmd_handler_args *args) { - struct ec_params_read_test *p = (struct ec_params_read_test *)data; + const struct ec_params_read_test *p = + (const struct ec_params_read_test *)args->params; struct ec_response_read_test *r = - (struct ec_response_read_test *)data; + (struct ec_response_read_test *)args->response; int offset = p->offset; int size = p->size / sizeof(uint32_t); @@ -103,40 +108,46 @@ static int host_command_read_test(uint8_t *data, int *resp_size) for (i = 0; i < size; i++) r->data[i] = offset + i; - *resp_size = sizeof(struct ec_response_read_test); + args->response_size = sizeof(*r); + return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_READ_TEST, host_command_read_test); +DECLARE_HOST_COMMAND(EC_CMD_READ_TEST, + host_command_read_test, + EC_VER_MASK(0)); #ifndef CONFIG_LPC /* * Host command to read memory map is not needed on LPC, because LPC can * directly map the data to the host's memory space. */ -static int host_command_read_memmap(uint8_t *data, int *resp_size) +static int host_command_read_memmap(struct host_cmd_handler_args *args) { - struct ec_params_read_memmap *p = (struct ec_params_read_memmap *)data; - struct ec_response_read_memmap *r = - (struct ec_response_read_memmap *)data; + const struct ec_params_read_memmap *p = + (const struct ec_params_read_memmap *)args->params; /* Copy params out of data before we overwrite it with output */ uint8_t offset = p->offset; uint8_t size = p->size; - if (size > sizeof(r->data) || offset > EC_MEMMAP_SIZE || + if (size > EC_PARAM_SIZE || offset > EC_MEMMAP_SIZE || offset + size > EC_MEMMAP_SIZE) return EC_RES_INVALID_PARAM; - memcpy(r->data, host_get_memmap(offset), size); + args->response = host_get_memmap(offset); + args->response_size = size; - *resp_size = size; return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_READ_MEMMAP, host_command_read_memmap); +DECLARE_HOST_COMMAND(EC_CMD_READ_MEMMAP, + host_command_read_memmap, + EC_VER_MASK(0)); #endif -/* Finds a command by command number. Returns the command structure, or NULL if - * no match found. */ +/* + * Find a command by command number. Returns the command structure, or NULL if + * no match found. + */ static const struct host_command *find_host_command(int command) { const struct host_command *cmd; @@ -153,13 +164,32 @@ enum ec_status host_command_process(int command, uint8_t *data, int *response_size) { const struct host_command *cmd = find_host_command(command); - enum ec_status res = EC_RES_INVALID_COMMAND; + struct host_cmd_handler_args args; + enum ec_status res; CPRINTF("[%T hostcmd 0x%02x]\n", command); - *response_size = 0; - if (cmd) - res = cmd->handler(data, response_size); + if (!cmd) + return EC_RES_INVALID_COMMAND; + + /* TODO: right now we assume the same data buffer for both params + * and response. This isn't true for I2C/SPI; we should + * propagate args farther up the call chain. */ + args.command = command; + args.version = 0; + args.params = data; + args.params_size = EC_PARAM_SIZE; + args.response = data; + args.response_size = 0; + + res = cmd->handler(&args); + + /* Copy response data if necessary */ + *response_size = args.response_size; + if (args.response_size > EC_PARAM_SIZE) + return EC_RES_INVALID_RESPONSE; + else if (args.response_size && args.response != data) + memcpy(data, args.response, args.response_size); return res; } diff --git a/common/host_event_commands.c b/common/host_event_commands.c index 0d87fcac38..3242a6de83 100644 --- a/common/host_event_commands.c +++ b/common/host_event_commands.c @@ -5,6 +5,7 @@ /* Host event commands for Chrome EC */ +#include "common.h" #include "console.h" #include "host_command.h" #include "lpc.h" @@ -93,83 +94,94 @@ DECLARE_CONSOLE_COMMAND(hostevent, command_host_event, #ifdef CONFIG_LPC -static int host_event_get_smi_mask(uint8_t *data, int *resp_size) +static int host_event_get_smi_mask(struct host_cmd_handler_args *args) { struct ec_response_host_event_mask *r = - (struct ec_response_host_event_mask *)data; + (struct ec_response_host_event_mask *)args->response; r->mask = lpc_get_host_event_mask(LPC_HOST_EVENT_SMI); - *resp_size = sizeof(struct ec_response_host_event_mask); + args->response_size = sizeof(*r); + return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_HOST_EVENT_GET_SMI_MASK, - host_event_get_smi_mask); + host_event_get_smi_mask, + EC_VER_MASK(0)); -static int host_event_get_sci_mask(uint8_t *data, int *resp_size) +static int host_event_get_sci_mask(struct host_cmd_handler_args *args) { struct ec_response_host_event_mask *r = - (struct ec_response_host_event_mask *)data; + (struct ec_response_host_event_mask *)args->response; r->mask = lpc_get_host_event_mask(LPC_HOST_EVENT_SCI); - *resp_size = sizeof(struct ec_response_host_event_mask); + args->response_size = sizeof(*r); + return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_HOST_EVENT_GET_SCI_MASK, - host_event_get_sci_mask); + host_event_get_sci_mask, + EC_VER_MASK(0)); -static int host_event_get_wake_mask(uint8_t *data, int *resp_size) +static int host_event_get_wake_mask(struct host_cmd_handler_args *args) { struct ec_response_host_event_mask *r = - (struct ec_response_host_event_mask *)data; + (struct ec_response_host_event_mask *)args->response; r->mask = lpc_get_host_event_mask(LPC_HOST_EVENT_WAKE); - *resp_size = sizeof(struct ec_response_host_event_mask); + args->response_size = sizeof(*r); + return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_HOST_EVENT_GET_WAKE_MASK, - host_event_get_wake_mask); + host_event_get_wake_mask, + EC_VER_MASK(0)); -static int host_event_set_smi_mask(uint8_t *data, int *resp_size) +static int host_event_set_smi_mask(struct host_cmd_handler_args *args) { const struct ec_params_host_event_mask *p = - (const struct ec_params_host_event_mask *)data; + (const struct ec_params_host_event_mask *)args->params; lpc_set_host_event_mask(LPC_HOST_EVENT_SMI, p->mask); return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_HOST_EVENT_SET_SMI_MASK, - host_event_set_smi_mask); + host_event_set_smi_mask, + EC_VER_MASK(0)); -static int host_event_set_sci_mask(uint8_t *data, int *resp_size) +static int host_event_set_sci_mask(struct host_cmd_handler_args *args) { const struct ec_params_host_event_mask *p = - (const struct ec_params_host_event_mask *)data; + (const struct ec_params_host_event_mask *)args->params; lpc_set_host_event_mask(LPC_HOST_EVENT_SCI, p->mask); return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_HOST_EVENT_SET_SCI_MASK, - host_event_set_sci_mask); + host_event_set_sci_mask, + EC_VER_MASK(0)); -static int host_event_set_wake_mask(uint8_t *data, int *resp_size) +static int host_event_set_wake_mask(struct host_cmd_handler_args *args) { const struct ec_params_host_event_mask *p = - (const struct ec_params_host_event_mask *)data; + (const struct ec_params_host_event_mask *)args->params; lpc_set_host_event_mask(LPC_HOST_EVENT_WAKE, p->mask); return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_HOST_EVENT_SET_WAKE_MASK, - host_event_set_wake_mask); + host_event_set_wake_mask, + EC_VER_MASK(0)); #endif /* CONFIG_LPC */ -static int host_event_clear(uint8_t *data, int *resp_size) +static int host_event_clear(struct host_cmd_handler_args *args) { const struct ec_params_host_event_mask *p = - (const struct ec_params_host_event_mask *)data; + (const struct ec_params_host_event_mask *)args->params; host_clear_events(p->mask); return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_HOST_EVENT_CLEAR, host_event_clear); +DECLARE_HOST_COMMAND(EC_CMD_HOST_EVENT_CLEAR, + host_event_clear, + EC_VER_MASK(0)); diff --git a/common/keyboard.c b/common/keyboard.c index 083b209e98..ccd0da63b1 100644 --- a/common/keyboard.c +++ b/common/keyboard.c @@ -893,10 +893,10 @@ DECLARE_CONSOLE_COMMAND(kbd, command_keyboard, /*****************************************************************************/ /* Host commands */ -static int mkbp_command_simulate_key(uint8_t *data, int *resp_size) +static int mkbp_command_simulate_key(struct host_cmd_handler_args *args) { - struct ec_params_mkbp_simulate_key *p = - (struct ec_params_mkbp_simulate_key *)data; + const struct ec_params_mkbp_simulate_key *p = + (const struct ec_params_mkbp_simulate_key *)args->params; /* Only available on unlocked systems */ if (system_is_locked()) @@ -911,7 +911,9 @@ static int mkbp_command_simulate_key(uint8_t *data, int *resp_size) keyboard_state_changed(p->row, p->col, p->pressed); return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_MKBP_SIMULATE_KEY, mkbp_command_simulate_key); +DECLARE_HOST_COMMAND(EC_CMD_MKBP_SIMULATE_KEY, + mkbp_command_simulate_key, + EC_VER_MASK(0)); /*****************************************************************************/ /* Hooks */ diff --git a/common/lightbar.c b/common/lightbar.c index 2e8434423f..bb7805c98d 100644 --- a/common/lightbar.c +++ b/common/lightbar.c @@ -5,7 +5,7 @@ * LED controls. */ -#include "board.h" +#include "common.h" #include "console.h" #include "gpio.h" #include "hooks.h" @@ -678,15 +678,24 @@ static void do_cmd_rgb(uint8_t led, /* Host commands via LPC bus */ /****************************************************************************/ -static int lpc_cmd_lightbar(uint8_t *data, int *resp_size) +static int lpc_cmd_lightbar(struct host_cmd_handler_args *args) { struct ec_params_lightbar_cmd *ptr = - (struct ec_params_lightbar_cmd *)data; + (struct ec_params_lightbar_cmd *)args->response; + + /* + * TODO: (crosbug.com/p/11277) Now that params and response are + * separate pointers, they need to be propagated to the lightbar + * sub-commands. For now, just copy params to response so the + * sub-commands above will work unchanged. + */ + if (args->params != args->response) + memcpy(args->response, args->params, args->params_size); switch (ptr->in.cmd) { case LIGHTBAR_CMD_DUMP: do_cmd_dump(ptr); - *resp_size = sizeof(struct ec_params_lightbar_cmd); + args->response_size = sizeof(struct ec_params_lightbar_cmd); break; case LIGHTBAR_CMD_OFF: lightbar_off(); @@ -716,7 +725,7 @@ static int lpc_cmd_lightbar(uint8_t *data, int *resp_size) break; case LIGHTBAR_CMD_GET_SEQ: ptr->out.get_seq.num = current_state; - *resp_size = sizeof(struct ec_params_lightbar_cmd); + args->response_size = sizeof(struct ec_params_lightbar_cmd); break; default: CPRINTF("[%T LB bad cmd 0x%x]\n", ptr->in.cmd); @@ -726,7 +735,10 @@ static int lpc_cmd_lightbar(uint8_t *data, int *resp_size) return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_LIGHTBAR_CMD, lpc_cmd_lightbar); +DECLARE_HOST_COMMAND(EC_CMD_LIGHTBAR_CMD, + lpc_cmd_lightbar, + EC_VER_MASK(0)); + /****************************************************************************/ diff --git a/common/pstore_commands.c b/common/pstore_commands.c index fdd0eaf26c..9717d3ccdb 100644 --- a/common/pstore_commands.c +++ b/common/pstore_commands.c @@ -5,42 +5,40 @@ /* Persistent storage commands for Chrome EC */ -#include "board.h" +#include "common.h" #include "eeprom.h" #include "host_command.h" #include "util.h" - -int pstore_command_get_info(uint8_t *data, int *resp_size) +int pstore_command_get_info(struct host_cmd_handler_args *args) { struct ec_response_pstore_info *r = - (struct ec_response_pstore_info *)data; + (struct ec_response_pstore_info *)args->response; ASSERT(EEPROM_BLOCK_START_PSTORE + EEPROM_BLOCK_COUNT_PSTORE <= eeprom_get_block_count()); r->pstore_size = EEPROM_BLOCK_COUNT_PSTORE * eeprom_get_block_size(); r->access_size = sizeof(uint32_t); - *resp_size = sizeof(struct ec_response_pstore_info); + args->response_size = sizeof(*r); return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_PSTORE_INFO, pstore_command_get_info); +DECLARE_HOST_COMMAND(EC_CMD_PSTORE_INFO, + pstore_command_get_info, + EC_VER_MASK(0)); - -int pstore_command_read(uint8_t *data, int *resp_size) +int pstore_command_read(struct host_cmd_handler_args *args) { - struct ec_params_pstore_read *p = - (struct ec_params_pstore_read *)data; - struct ec_response_pstore_read *r = - (struct ec_response_pstore_read *)data; - char *dest = r->data; + const struct ec_params_pstore_read *p = + (const struct ec_params_pstore_read *)args->params; + char *dest = args->response; int block_size = eeprom_get_block_size(); int block = p->offset / block_size + EEPROM_BLOCK_COUNT_PSTORE; int offset = p->offset % block_size; int bytes_left = p->size; - if (p->size > sizeof(r->data)) - return EC_RES_ERROR; + if (p->size > sizeof(EC_PARAM_SIZE)) + return EC_RES_INVALID_PARAM; while (bytes_left) { /* Read what we can from the current block */ @@ -60,16 +58,17 @@ int pstore_command_read(uint8_t *data, int *resp_size) dest += bytes_this; } - *resp_size = sizeof(struct ec_response_pstore_read); + args->response_size = p->size; return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_PSTORE_READ, pstore_command_read); +DECLARE_HOST_COMMAND(EC_CMD_PSTORE_READ, + pstore_command_read, + EC_VER_MASK(0)); - -int pstore_command_write(uint8_t *data, int *resp_size) +int pstore_command_write(struct host_cmd_handler_args *args) { - struct ec_params_pstore_write *p = - (struct ec_params_pstore_write *)data; + const struct ec_params_pstore_write *p = + (const struct ec_params_pstore_write *)args->params; const char *src = p->data; int block_size = eeprom_get_block_size(); @@ -100,4 +99,6 @@ int pstore_command_write(uint8_t *data, int *resp_size) return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_PSTORE_WRITE, pstore_command_write); +DECLARE_HOST_COMMAND(EC_CMD_PSTORE_WRITE, + pstore_command_write, + EC_VER_MASK(0)); diff --git a/common/pwm_commands.c b/common/pwm_commands.c index 12de09b3d0..0493bb9b5e 100644 --- a/common/pwm_commands.c +++ b/common/pwm_commands.c @@ -10,64 +10,73 @@ #include "thermal.h" -int pwm_command_get_fan_rpm(uint8_t *data, int *resp_size) +int pwm_command_get_fan_target_rpm(struct host_cmd_handler_args *args) { struct ec_response_pwm_get_fan_rpm *r = - (struct ec_response_pwm_get_fan_rpm *)data; + (struct ec_response_pwm_get_fan_rpm *)args->response; r->rpm = pwm_get_fan_target_rpm(); - *resp_size = sizeof(struct ec_response_pwm_get_fan_rpm); + args->response_size = sizeof(*r); + return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_PWM_GET_FAN_RPM, pwm_command_get_fan_rpm); +DECLARE_HOST_COMMAND(EC_CMD_PWM_GET_FAN_TARGET_RPM, + pwm_command_get_fan_target_rpm, + EC_VER_MASK(0)); - -int pwm_command_set_fan_target_rpm(uint8_t *data, int *resp_size) +int pwm_command_set_fan_target_rpm(struct host_cmd_handler_args *args) { - struct ec_params_pwm_set_fan_target_rpm *p = - (struct ec_params_pwm_set_fan_target_rpm *)data; + const struct ec_params_pwm_set_fan_target_rpm *p = + (const struct ec_params_pwm_set_fan_target_rpm *)args->params; #ifdef CONFIG_TASK_THERMAL thermal_toggle_auto_fan_ctrl(0); #endif pwm_set_fan_target_rpm(p->rpm); + return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_PWM_SET_FAN_TARGET_RPM, - pwm_command_set_fan_target_rpm); + pwm_command_set_fan_target_rpm, + EC_VER_MASK(0)); - -int pwm_command_fan_duty(uint8_t *data, int *resp_size) +int pwm_command_fan_duty(struct host_cmd_handler_args *args) { - struct ec_params_pwm_set_fan_duty *p = - (struct ec_params_pwm_set_fan_duty *)data; + const struct ec_params_pwm_set_fan_duty *p = + (const struct ec_params_pwm_set_fan_duty *)args->params; pwm_set_fan_duty(p->percent); + return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_PWM_SET_FAN_DUTY, pwm_command_fan_duty); +DECLARE_HOST_COMMAND(EC_CMD_PWM_SET_FAN_DUTY, + pwm_command_fan_duty, + EC_VER_MASK(0)); - -int pwm_command_get_keyboard_backlight(uint8_t *data, int *resp_size) +int pwm_command_get_keyboard_backlight(struct host_cmd_handler_args *args) { struct ec_response_pwm_get_keyboard_backlight *r = - (struct ec_response_pwm_get_keyboard_backlight *)data; + (struct ec_response_pwm_get_keyboard_backlight *)args->response; r->percent = pwm_get_keyboard_backlight(); r->enabled = pwm_get_keyboard_backlight_enabled(); - *resp_size = sizeof(struct ec_response_pwm_get_keyboard_backlight); + args->response_size = sizeof(*r); + return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_PWM_GET_KEYBOARD_BACKLIGHT, - pwm_command_get_keyboard_backlight); + pwm_command_get_keyboard_backlight, + EC_VER_MASK(0)); - -int pwm_command_set_keyboard_backlight(uint8_t *data, int *resp_size) +int pwm_command_set_keyboard_backlight(struct host_cmd_handler_args *args) { - struct ec_params_pwm_set_keyboard_backlight *p = - (struct ec_params_pwm_set_keyboard_backlight *)data; + const struct ec_params_pwm_set_keyboard_backlight *p = + (const struct ec_params_pwm_set_keyboard_backlight *) + args->params; pwm_set_keyboard_backlight(p->percent); + return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_PWM_SET_KEYBOARD_BACKLIGHT, - pwm_command_set_keyboard_backlight); + pwm_command_set_keyboard_backlight, + EC_VER_MASK(0)); diff --git a/common/system_common.c b/common/system_common.c index 10c7c42088..46fa33794f 100644 --- a/common/system_common.c +++ b/common/system_common.c @@ -684,10 +684,10 @@ DECLARE_CONSOLE_COMMAND(syslock, command_system_lock, /*****************************************************************************/ /* Host commands */ -static int host_command_get_version(uint8_t *data, int *resp_size) +static int host_command_get_version(struct host_cmd_handler_args *args) { struct ec_response_get_version *r = - (struct ec_response_get_version *)data; + (struct ec_response_get_version *)args->response; strzcpy(r->version_string_ro, system_get_version(SYSTEM_IMAGE_RO), sizeof(r->version_string_ro)); @@ -711,55 +711,60 @@ static int host_command_get_version(uint8_t *data, int *resp_size) break; } - *resp_size = sizeof(struct ec_response_get_version); + args->response_size = sizeof(*r); + return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_GET_VERSION, host_command_get_version); +DECLARE_HOST_COMMAND(EC_CMD_GET_VERSION, + host_command_get_version, + EC_VER_MASK(0)); - -static int host_command_build_info(uint8_t *data, int *resp_size) +static int host_command_build_info(struct host_cmd_handler_args *args) { - struct ec_response_get_build_info *r = - (struct ec_response_get_build_info *)data; + const char *info = system_get_build_info(); - strzcpy(r->build_string, system_get_build_info(), - sizeof(r->build_string)); + args->response = (uint8_t *)info; + args->response_size = strlen(info) + 1; - *resp_size = sizeof(struct ec_response_get_build_info); return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_GET_BUILD_INFO, host_command_build_info); +DECLARE_HOST_COMMAND(EC_CMD_GET_BUILD_INFO, + host_command_build_info, + EC_VER_MASK(0)); - -static int host_command_get_chip_info(uint8_t *data, int *resp_size) +static int host_command_get_chip_info(struct host_cmd_handler_args *args) { struct ec_response_get_chip_info *r = - (struct ec_response_get_chip_info *)data; + (struct ec_response_get_chip_info *)args->response; strzcpy(r->vendor, system_get_chip_vendor(), sizeof(r->vendor)); strzcpy(r->name, system_get_chip_name(), sizeof(r->name)); strzcpy(r->revision, system_get_chip_revision(), sizeof(r->revision)); - *resp_size = sizeof(struct ec_response_get_chip_info); + args->response_size = sizeof(*r); + return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_GET_CHIP_INFO, host_command_get_chip_info); +DECLARE_HOST_COMMAND(EC_CMD_GET_CHIP_INFO, + host_command_get_chip_info, + EC_VER_MASK(0)); - -int host_command_get_board_version(uint8_t *data, int *resp_size) +int host_command_get_board_version(struct host_cmd_handler_args *args) { - struct ec_params_board_version *board_v = - (struct ec_params_board_version *) data; + struct ec_response_board_version *r = + (struct ec_response_board_version *)args->response; - board_v->board_version = (uint16_t) system_get_board_version(); + r->board_version = (uint16_t) system_get_board_version(); + + args->response_size = sizeof(*r); - *resp_size = sizeof(struct ec_params_board_version); return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_GET_BOARD_VERSION, host_command_get_board_version); +DECLARE_HOST_COMMAND(EC_CMD_GET_BOARD_VERSION, + host_command_get_board_version, + EC_VER_MASK(0)); - -int host_command_reboot(uint8_t *data, int *resp_size) +int host_command_reboot(struct host_cmd_handler_args *args) { struct ec_params_reboot_ec p; @@ -767,7 +772,7 @@ int host_command_reboot(uint8_t *data, int *resp_size) * Ensure reboot parameters don't get clobbered when the response * is sent in case data argument points to the host tx/rx buffer. */ - memcpy(&p, data, sizeof(p)); + memcpy(&p, args->params, sizeof(p)); if (p.cmd == EC_REBOOT_CANCEL) { /* Cancel pending reboot */ @@ -798,4 +803,6 @@ int host_command_reboot(uint8_t *data, int *resp_size) return EC_RES_ERROR; } } -DECLARE_HOST_COMMAND(EC_CMD_REBOOT_EC, host_command_reboot); +DECLARE_HOST_COMMAND(EC_CMD_REBOOT_EC, + host_command_reboot, + EC_VER_MASK(0)); diff --git a/common/temp_sensor_commands.c b/common/temp_sensor_commands.c index bf303f2cb7..43b92385c7 100644 --- a/common/temp_sensor_commands.c +++ b/common/temp_sensor_commands.c @@ -5,23 +5,23 @@ /* Temp sensor host commands for Chrome EC */ +#include "common.h" #include "host_command.h" #include "temp_sensor.h" #include "util.h" - -/* Defined in board_temp_sensor.c. Must be in the same order as - * in enum temp_sensor_id. +/* + * Defined in board_temp_sensor.c. Must be in the same order as in enum + * temp_sensor_id. */ extern const struct temp_sensor_t temp_sensors[TEMP_SENSOR_COUNT]; - -int temp_sensor_command_get_info(uint8_t *data, int *resp_size) +int temp_sensor_command_get_info(struct host_cmd_handler_args *args) { - struct ec_params_temp_sensor_get_info *p = - (struct ec_params_temp_sensor_get_info *)data; + const struct ec_params_temp_sensor_get_info *p = + (const struct ec_params_temp_sensor_get_info *)args->params; struct ec_response_temp_sensor_get_info *r = - (struct ec_response_temp_sensor_get_info *)data; + (struct ec_response_temp_sensor_get_info *)args->response; int id = p->id; if (id >= TEMP_SENSOR_COUNT) @@ -30,8 +30,10 @@ int temp_sensor_command_get_info(uint8_t *data, int *resp_size) strzcpy(r->sensor_name, temp_sensors[id].name, sizeof(r->sensor_name)); r->sensor_type = temp_sensors[id].type; - *resp_size = sizeof(struct ec_response_temp_sensor_get_info); + args->response_size = sizeof(*r); + return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_TEMP_SENSOR_GET_INFO, - temp_sensor_command_get_info); + temp_sensor_command_get_info, + EC_VER_MASK(0)); diff --git a/common/thermal_commands.c b/common/thermal_commands.c index f4bb8d6497..5e6e024f89 100644 --- a/common/thermal_commands.c +++ b/common/thermal_commands.c @@ -5,47 +5,51 @@ /* Thermal engine host commands for Chrome EC */ +#include "common.h" #include "host_command.h" #include "thermal.h" - -int thermal_command_set_threshold(uint8_t *data, int *resp_size) +int thermal_command_set_threshold(struct host_cmd_handler_args *args) { - struct ec_params_thermal_set_threshold *p = - (struct ec_params_thermal_set_threshold *)data; + const struct ec_params_thermal_set_threshold *p = + (const struct ec_params_thermal_set_threshold *)args->params; if (thermal_set_threshold(p->sensor_type, p->threshold_id, p->value)) return EC_RES_ERROR; + return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_THERMAL_SET_THRESHOLD, - thermal_command_set_threshold); + thermal_command_set_threshold, + EC_VER_MASK(0)); - -int thermal_command_get_threshold(uint8_t *data, int *resp_size) +int thermal_command_get_threshold(struct host_cmd_handler_args *args) { - struct ec_params_thermal_get_threshold *p = - (struct ec_params_thermal_get_threshold *)data; + const struct ec_params_thermal_get_threshold *p = + (const struct ec_params_thermal_get_threshold *)args->params; struct ec_response_thermal_get_threshold *r = - (struct ec_response_thermal_get_threshold *)data; + (struct ec_response_thermal_get_threshold *)args->response; int value = thermal_get_threshold(p->sensor_type, p->threshold_id); if (value == -1) return EC_RES_ERROR; r->value = value; - *resp_size = sizeof(struct ec_response_thermal_get_threshold); + args->response_size = sizeof(*r); + return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_THERMAL_GET_THRESHOLD, - thermal_command_get_threshold); + thermal_command_get_threshold, + EC_VER_MASK(0)); - -int thermal_command_auto_fan_ctrl(uint8_t *data, int *resp_size) +int thermal_command_auto_fan_ctrl(struct host_cmd_handler_args *args) { if (thermal_toggle_auto_fan_ctrl(1)) return EC_RES_ERROR; return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_THERMAL_AUTO_FAN_CTRL, - thermal_command_auto_fan_ctrl); + thermal_command_auto_fan_ctrl, + EC_VER_MASK(0)); + diff --git a/common/usb_charge_commands.c b/common/usb_charge_commands.c index 4e69208622..7be591f2d2 100644 --- a/common/usb_charge_commands.c +++ b/common/usb_charge_commands.c @@ -5,24 +5,25 @@ /* USB charging control commands for Chrome EC */ +#include "common.h" #include "console.h" -#include "usb_charge.h" #include "host_command.h" +#include "usb_charge.h" #include "util.h" /* Console output macros */ #define CPUTS(outstr) cputs(CC_USBCHARGE, outstr) #define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) - -int usb_charge_command_set_mode(uint8_t *data, int *resp_size) +static int usb_charge_command_set_mode(struct host_cmd_handler_args *args) { - struct ec_params_usb_charge_set_mode *p = - (struct ec_params_usb_charge_set_mode *)data; + const struct ec_params_usb_charge_set_mode *p = + (const struct ec_params_usb_charge_set_mode *)args->params; int rv; 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) @@ -31,4 +32,5 @@ int usb_charge_command_set_mode(uint8_t *data, int *resp_size) return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_USB_CHARGE_SET_MODE, - usb_charge_command_set_mode); + usb_charge_command_set_mode, + EC_VER_MASK(0)); diff --git a/common/vboot.c b/common/vboot.c index 97ae09bede..e4b9ee0aed 100644 --- a/common/vboot.c +++ b/common/vboot.c @@ -5,10 +5,8 @@ /* Verified boot module for Chrome EC */ -#include "board.h" -#include "config.h" +#include "common.h" #include "console.h" -#include "eoption.h" #include "host_command.h" #include "system.h" #include "vboot.h" @@ -26,27 +24,31 @@ int vboot_pre_init(void) /****************************************************************************/ /* Host commands */ -static int host_cmd_vboot(uint8_t *data, int *resp_size) +static int host_cmd_vboot(struct host_cmd_handler_args *args) { - struct ec_params_vboot_cmd *ptr = - (struct ec_params_vboot_cmd *)data; + const struct ec_params_vboot_cmd *p = + (const struct ec_params_vboot_cmd *)args->params; + struct ec_params_vboot_cmd *r = + (struct ec_params_vboot_cmd *)args->response; uint8_t v; - switch (ptr->in.cmd) { + switch (p->in.cmd) { case VBOOT_CMD_GET_FLAGS: v = VBOOT_FLAGS_IMAGE_MASK & system_get_image_copy(); - ptr->out.get_flags.val = v; - *resp_size = sizeof(struct ec_params_vboot_cmd); + r->out.get_flags.val = v; + args->response_size = sizeof(r); break; case VBOOT_CMD_SET_FLAGS: - v = ptr->in.set_flags.val; + v = p->in.set_flags.val; break; default: - CPRINTF("[%T LB bad cmd 0x%x]\n", ptr->in.cmd); + CPRINTF("[%T LB bad cmd 0x%x]\n", p->in.cmd); return EC_RES_INVALID_PARAM; } return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_VBOOT_CMD, host_cmd_vboot); +DECLARE_HOST_COMMAND(EC_CMD_VBOOT_CMD, + host_cmd_vboot, + EC_VER_MASK(0)); diff --git a/common/vboot_hash.c b/common/vboot_hash.c index fc801a2e98..47b860111c 100644 --- a/common/vboot_hash.c +++ b/common/vboot_hash.c @@ -5,7 +5,7 @@ /* Verified boot hash computing module for Chrome EC */ -#include "config.h" +#include "common.h" #include "console.h" #include "cryptolib.h" #include "hooks.h" @@ -243,18 +243,18 @@ static void fill_response(struct ec_response_vboot_hash *r) r->status = EC_VBOOT_HASH_STATUS_NONE; } - -static int host_command_vboot_hash(uint8_t *data, int *resp_size) +static int host_command_vboot_hash(struct host_cmd_handler_args *args) { - struct ec_params_vboot_hash *p = (struct ec_params_vboot_hash *)data; + const struct ec_params_vboot_hash *p = + (const struct ec_params_vboot_hash *)args->params; struct ec_response_vboot_hash *r = - (struct ec_response_vboot_hash *)data; + (struct ec_response_vboot_hash *)args->response; int rv; switch (p->cmd) { case EC_VBOOT_HASH_GET: fill_response(r); - *resp_size = sizeof(struct ec_response_vboot_hash); + args->response_size = sizeof(*r); return EC_RES_SUCCESS; case EC_VBOOT_HASH_ABORT: @@ -295,11 +295,13 @@ static int host_command_vboot_hash(uint8_t *data, int *resp_size) usleep(1000); fill_response(r); - *resp_size = sizeof(struct ec_response_vboot_hash); + args->response_size = sizeof(*r); return EC_RES_SUCCESS; default: return EC_RES_INVALID_PARAM; } } -DECLARE_HOST_COMMAND(EC_CMD_VBOOT_HASH, host_command_vboot_hash); +DECLARE_HOST_COMMAND(EC_CMD_VBOOT_HASH, + host_command_vboot_hash, + EC_VER_MASK(0)); diff --git a/common/x86_power.c b/common/x86_power.c index 6aa98002f8..7136795529 100644 --- a/common/x86_power.c +++ b/common/x86_power.c @@ -674,15 +674,18 @@ DECLARE_CONSOLE_COMMAND(x86shutdown, command_x86shutdown, /*****************************************************************************/ /* Host commands */ -int switch_command_enable_wireless(uint8_t *data, int *resp_size) +static int switch_command_enable_wireless(struct host_cmd_handler_args *args) { - struct ec_params_switch_enable_wireless *p = - (struct ec_params_switch_enable_wireless *)data; + const struct ec_params_switch_enable_wireless *p = + (const struct ec_params_switch_enable_wireless *)args->params; + gpio_set_level(GPIO_RADIO_ENABLE_WLAN, p->enabled & EC_WIRELESS_SWITCH_WLAN); gpio_set_level(GPIO_RADIO_ENABLE_BT, p->enabled & EC_WIRELESS_SWITCH_BLUETOOTH); + return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_SWITCH_ENABLE_WIRELESS, - switch_command_enable_wireless); + switch_command_enable_wireless, + EC_VER_MASK(0)); diff --git a/include/ec_commands.h b/include/ec_commands.h index 653712106b..ec5837f217 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -30,6 +30,9 @@ /* Current version of this protocol */ #define EC_PROTO_VERSION 0x00000002 +/* Command version mask */ +#define EC_VER_MASK(version) (1UL << (version)) + /* I/O addresses for LPC commands */ #define EC_LPC_ADDR_ACPI_DATA 0x62 #define EC_LPC_ADDR_ACPI_CMD 0x66 @@ -137,6 +140,8 @@ enum ec_status { EC_RES_ERROR = 2, EC_RES_INVALID_PARAM = 3, EC_RES_ACCESS_DENIED = 4, + EC_RES_INVALID_RESPONSE = 5, + EC_RES_INVALID_VERSION = 6, }; /* @@ -246,13 +251,13 @@ struct ec_response_read_test { uint32_t data[32]; } __packed; -/* Get build information */ +/* + * Get build information + * + * Response is null-terminated string. + */ #define EC_CMD_GET_BUILD_INFO 0x04 -struct ec_response_get_build_info { - char build_string[EC_PARAM_SIZE]; -} __packed; - /* Get chip info */ #define EC_CMD_GET_CHIP_INFO 0x05 @@ -263,10 +268,10 @@ struct ec_response_get_chip_info { char revision[32]; /* Mask version */ } __packed; -/* Get board HW version. */ +/* Get board HW version */ #define EC_CMD_GET_BOARD_VERSION 0x06 -struct ec_params_board_version { +struct ec_response_board_version { uint16_t board_version; /* A monotonously incrementing number. */ } __packed; @@ -275,6 +280,8 @@ struct ec_params_board_version { * * This is an alternate interface to memory-mapped data for bus protocols * which don't support direct-mapped memory - I2C, SPI, etc. + * + * Response is params.size bytes of data. */ #define EC_CMD_READ_MEMMAP 0x07 @@ -283,10 +290,6 @@ struct ec_params_read_memmap { uint8_t size; /* Size to read in bytes */ } __packed; -struct ec_response_read_memmap { - uint32_t data[EC_PARAM_SIZE]; -} __packed; - /*****************************************************************************/ /* Flash commands */ @@ -313,7 +316,11 @@ struct ec_response_flash_info { uint32_t protect_block_size; } __packed; -/* Read flash */ +/* + * Read flash + * + * Response is params.size bytes of data. + */ #define EC_CMD_FLASH_READ 0x11 struct ec_params_flash_read { @@ -321,10 +328,6 @@ struct ec_params_flash_read { uint32_t size; /* Size to read in bytes */ } __packed; -struct ec_response_flash_read { - uint8_t data[EC_PARAM_SIZE]; -} __packed; - /* Write flash */ #define EC_CMD_FLASH_WRITE 0x12 @@ -346,7 +349,7 @@ struct ec_params_flash_erase { uint32_t size; /* Size to erase in bytes */ } __packed; -/* Flashmap offset */ +/* Get flashmap offset */ #define EC_CMD_FLASH_GET_FLASHMAP 0x14 struct ec_response_flash_flashmap { @@ -387,6 +390,11 @@ struct ec_response_flash_wp_range { /* Read flash write protection GPIO pin */ #define EC_CMD_FLASH_WP_GET_GPIO 0x19 +/* + * TODO: why does this pass in a pin number? EC *KNOWS* what the pin is. + * Of course, the EC doesn't implement this message yet, so this is somewhat + * theoretical. + */ struct ec_params_flash_wp_gpio { uint32_t pin_no; } __packed; @@ -398,8 +406,8 @@ struct ec_response_flash_wp_gpio { /*****************************************************************************/ /* PWM commands */ -/* Get fan RPM */ -#define EC_CMD_PWM_GET_FAN_RPM 0x20 +/* Get fan target RPM */ +#define EC_CMD_PWM_GET_FAN_TARGET_RPM 0x20 struct ec_response_pwm_get_fan_rpm { uint32_t rpm; @@ -582,7 +590,11 @@ struct ec_response_pstore_info { uint32_t access_size; } __packed; -/* Read persistent storage */ +/* + * Read persistent storage + * + * Response is params.size bytes of data. + */ #define EC_CMD_PSTORE_READ 0x41 struct ec_params_pstore_read { @@ -590,10 +602,6 @@ struct ec_params_pstore_read { uint32_t size; /* Size to read in bytes */ } __packed; -struct ec_response_pstore_read { - uint8_t data[EC_PSTORE_SIZE_MAX]; -} __packed; - /* Write persistent storage */ #define EC_CMD_PSTORE_WRITE 0x42 @@ -627,19 +635,20 @@ struct ec_response_thermal_get_threshold { uint16_t value; } __packed; -/* Toggling automatic fan control */ +/* Toggle automatic fan control */ #define EC_CMD_THERMAL_AUTO_FAN_CTRL 0x52 /*****************************************************************************/ /* MKBP - Matrix KeyBoard Protocol */ -/* Read key state */ +/* + * Read key state + * + * Returns raw data for keyboard cols; see ec_response_mkbp_info.cols for + * expected response size. + */ #define EC_CMD_MKBP_STATE 0x60 -struct ec_response_mkbp_state { - uint8_t cols[32]; -} __packed; - /* Provide information about the matrix : number of rows and columns */ #define EC_CMD_MKBP_INFO 0x61 diff --git a/include/host_command.h b/include/host_command.h index 511e1369ee..b892a68ec8 100644 --- a/include/host_command.h +++ b/include/host_command.h @@ -11,14 +11,33 @@ #include "common.h" #include "ec_commands.h" +/* Args for host command handler */ +struct host_cmd_handler_args { + uint8_t command; /* Command (e.g., EC_CMD_FLASH_GET_INFO) */ + uint8_t version; /* Version of command (0-31) */ + const uint8_t *params; /* Input parameters */ + uint8_t params_size; /* Size of input parameters in bytes */ + /* + * Pointer to output response data buffer. On input to the handler, + * points to a EC_PARAM_SIZE-byte buffer. Command handler can change + * this to point to a different location instead of memcpy()'ing data + * into the provided buffer. + */ + uint8_t *response; + uint8_t response_size; /* Size of data pointed to by resp_ptr */ +}; + /* Host command */ struct host_command { - /* Command code. */ + /* Command code */ int command; - /* Handler for the command; data points to parameters/response. - * returns negative error code if case of failure (using EC_LPC_STATUS - * codes). sets if it returns a payload to the host. */ - int (*handler)(uint8_t *data, int *response_size); + /* + * Handler for the command. Args points to context for handler. + * Returns result status (EC_RES_*). + */ + int (*handler)(struct host_cmd_handler_args *args); + /* Mask of supported versions */ + int version_mask; }; /** @@ -94,9 +113,9 @@ void host_send_response(enum ec_status result, const uint8_t *data, int size); uint8_t *host_get_buffer(void); /* Register a host command handler */ -#define DECLARE_HOST_COMMAND(command, routine) \ +#define DECLARE_HOST_COMMAND(command, routine, version_mask) \ const struct host_command __host_cmd_##command \ __attribute__((section(".rodata.hcmds"))) \ - = {command, routine} + = {command, routine, version_mask} #endif /* __CROS_EC_HOST_COMMAND_H */ diff --git a/util/burn_my_ec.c b/util/burn_my_ec.c index 60fb82c4d7..f0b2a569b6 100644 --- a/util/burn_my_ec.c +++ b/util/burn_my_ec.c @@ -20,13 +20,14 @@ static const char * const part_name[] = {"unknown", "RO", "A", "B"}; enum ec_current_image get_version(enum ec_current_image *version_ptr) { struct ec_response_get_version r; - struct ec_response_get_build_info r2; + char build_info[EC_PARAM_SIZE]; int res; res = ec_command(EC_CMD_GET_VERSION, NULL, 0, &r, sizeof(r)); if (res < 0) return res; - res = ec_command(EC_CMD_GET_BUILD_INFO, NULL, 0, &r2, sizeof(r2)); + res = ec_command(EC_CMD_GET_BUILD_INFO, NULL, 0, build_info, + sizeof(build_info)); if (res < 0) return res; @@ -34,7 +35,7 @@ enum ec_current_image get_version(enum ec_current_image *version_ptr) r.version_string_ro[sizeof(r.version_string_ro) - 1] = '\0'; r.version_string_rw_a[sizeof(r.version_string_rw_a) - 1] = '\0'; r.version_string_rw_b[sizeof(r.version_string_rw_b) - 1] = '\0'; - r2.build_string[sizeof(r2.build_string) - 1] = '\0'; + build_info[sizeof(build_info) - 1] = '\0'; /* Print versions */ printf("RO version: %s\n", r.version_string_ro); @@ -43,7 +44,7 @@ enum ec_current_image get_version(enum ec_current_image *version_ptr) printf("Firmware copy: %s\n", (r.current_image < sizeof(part_name)/sizeof(part_name[0]) ? part_name[r.current_image] : "?")); - printf("Build info: %s\n", r2.build_string); + printf("Build info: %s\n", build_info); if (version_ptr) *version_ptr = r.current_image; @@ -58,7 +59,7 @@ int flash_partition(enum ec_current_image part, const uint8_t *payload, struct ec_params_flash_erase er_req; struct ec_params_flash_write wr_req; struct ec_params_flash_read rd_req; - struct ec_response_flash_read rd_resp; + uint8_t rd_resp[EC_PARAM_SIZE]; int res; uint32_t i; enum ec_current_image current = EC_IMAGE_UNKNOWN; @@ -106,16 +107,16 @@ int flash_partition(enum ec_current_image part, const uint8_t *payload, printf("Verifying partition %s : 0x%x bytes at 0x%08x\n", part_name[part], size, offset); /* Read data in chunks */ - for (i = 0; i < size; i += sizeof(rd_resp.data)) { + for (i = 0; i < size; i += sizeof(rd_resp)) { rd_req.offset = offset + i; - rd_req.size = MIN(size - i, sizeof(rd_resp.data)); + rd_req.size = MIN(size - i, sizeof(rd_resp)); res = ec_command(EC_CMD_FLASH_READ, &rd_req, sizeof(rd_req), &rd_resp, sizeof(rd_resp)); if (res < 0) { fprintf(stderr, "Read error at 0x%08x : %d\n", i, res); return -1; } - if (memcmp(payload + i, rd_resp.data, rd_req.size)) + if (memcmp(payload + i, rd_resp, rd_req.size)) fprintf(stderr, "ERR: @%08x->%08x\n", offset + i, offset + i + size); } diff --git a/util/ectool.c b/util/ectool.c index 4d4f67045e..f7557d5415 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -235,14 +235,14 @@ int cmd_version(int argc, char *argv[]) { static const char * const fw_copies[] = {"unknown", "RO", "A", "B"}; struct ec_response_get_version r; - struct ec_response_get_build_info r2; + char build_string[EC_PARAM_SIZE]; int rv; rv = ec_command(EC_CMD_GET_VERSION, NULL, 0, &r, sizeof(r)); if (rv < 0) return rv; rv = ec_command(EC_CMD_GET_BUILD_INFO, - NULL, 0, &r2, sizeof(r2)); + NULL, 0, build_string, sizeof(build_string)); if (rv < 0) return rv; @@ -250,7 +250,7 @@ int cmd_version(int argc, char *argv[]) r.version_string_ro[sizeof(r.version_string_ro) - 1] = '\0'; r.version_string_rw_a[sizeof(r.version_string_rw_a) - 1] = '\0'; r.version_string_rw_b[sizeof(r.version_string_rw_b) - 1] = '\0'; - r2.build_string[sizeof(r2.build_string) - 1] = '\0'; + build_string[sizeof(build_string) - 1] = '\0'; /* Print versions */ printf("RO version: %s\n", r.version_string_ro); @@ -259,7 +259,7 @@ int cmd_version(int argc, char *argv[]) printf("Firmware copy: %s\n", (r.current_image < ARRAY_SIZE(fw_copies) ? fw_copies[r.current_image] : "?")); - printf("Build info: %s\n", r2.build_string); + printf("Build info: %s\n", build_string); return 0; } @@ -397,7 +397,7 @@ int cmd_flash_info(int argc, char *argv[]) int cmd_flash_read(int argc, char *argv[]) { struct ec_params_flash_read p; - struct ec_response_flash_read r; + uint8_t rdata[EC_PARAM_SIZE]; int offset, size; int rv; int i; @@ -428,17 +428,17 @@ int cmd_flash_read(int argc, char *argv[]) } /* Read data in chunks */ - for (i = 0; i < size; i += sizeof(r.data)) { + for (i = 0; i < size; i += sizeof(rdata)) { p.offset = offset + i; - p.size = MIN(size - i, sizeof(r.data)); + p.size = MIN(size - i, sizeof(rdata)); rv = ec_command(EC_CMD_FLASH_READ, - &p, sizeof(p), &r, sizeof(r)); + &p, sizeof(p), rdata, sizeof(rdata)); if (rv < 0) { fprintf(stderr, "Read error at offset %d\n", i); free(buf); return rv; } - memcpy(buf + i, r.data, p.size); + memcpy(buf + i, rdata, p.size); } rv = write_file(argv[3], buf, size); @@ -1131,7 +1131,7 @@ int cmd_pstore_info(int argc, char *argv[]) int cmd_pstore_read(int argc, char *argv[]) { struct ec_params_pstore_read p; - struct ec_response_pstore_read r; + uint8_t rdata[EC_PARAM_SIZE]; int offset, size; int rv; int i; @@ -1166,13 +1166,13 @@ int cmd_pstore_read(int argc, char *argv[]) p.offset = offset + i; p.size = MIN(size - i, EC_PSTORE_SIZE_MAX); rv = ec_command(EC_CMD_PSTORE_READ, - &p, sizeof(p), &r, sizeof(r)); + &p, sizeof(p), rdata, sizeof(rdata)); if (rv < 0) { fprintf(stderr, "Read error at offset %d\n", i); free(buf); return rv; } - memcpy(buf + i, r.data, p.size); + memcpy(buf + i, rdata, p.size); } rv = write_file(argv[3], buf, size);