diff --git a/futility/cmd_update.c b/futility/cmd_update.c index fef24c69..70e699a2 100644 --- a/futility/cmd_update.c +++ b/futility/cmd_update.c @@ -29,6 +29,7 @@ enum { OPT_QUIRKS, OPT_QUIRKS_LIST, OPT_REPACK, + OPT_SERVO, OPT_SIGNATURE, OPT_SYS_PROPS, OPT_UNPACK, @@ -50,6 +51,7 @@ static struct option const long_opts[] = { {"mode", 1, NULL, 'm'}, {"ccd", 0, NULL, OPT_CCD}, + {"servo", 0, NULL, OPT_SERVO}, {"emulate", 1, NULL, OPT_EMULATE}, {"factory", 0, NULL, OPT_FACTORY}, {"fast", 0, NULL, OPT_FAST}, @@ -111,6 +113,7 @@ static void print_help(int argc, char *argv[]) " --emulate=FILE \tEmulate system firmware using file\n" " --model=MODEL \tOverride system model for images\n" " --ccd \tDo fast,force,wp=0,p=raiden_debug_spi\n" + " --servo \tFlash using Servo (v2, v4, micro, ...)\n" " --signature_id=S\tOverride signature ID for key files\n" " --sys_props=LIST\tList of system properties to override\n" "-d, --debug \tPrint debugging messages\n" @@ -124,6 +127,7 @@ static int do_update(int argc, char *argv[]) struct updater_config *cfg; struct updater_config_arguments args = {0}; int i, errorcnt = 0, do_update = 1; + int detect_servo = 0, do_servo_cpu_fw_spi = 0; cfg = updater_new_config(); assert(cfg); @@ -216,6 +220,13 @@ static int do_update(int argc, char *argv[]) args.write_protection = "0"; args.programmer = "raiden_debug_spi:target=AP"; break; + case OPT_SERVO: + args.fast_update = 1; + args.force_update = 1; + args.write_protection = "0"; + args.host_only = 1; + detect_servo = 1; + break; case OPT_DUMMY: break; @@ -239,6 +250,18 @@ static int do_update(int argc, char *argv[]) errorcnt++; ERROR("Unexpected arguments.\n"); } + + if (!errorcnt && detect_servo) + errorcnt += host_detect_servo(&args.programmer, + &do_servo_cpu_fw_spi); + /* + * Some boards may need to fetch firmware before starting to + * update (i.e., in updater_setup_config) so we want to turn on + * cpu_fw_spi mode now. + */ + if (do_servo_cpu_fw_spi) + free(host_shell("dut-control cpu_fw_spi:on")); + if (!errorcnt) errorcnt += updater_setup_config(cfg, &args, &do_update); if (!errorcnt && do_update) { @@ -256,6 +279,9 @@ static int do_update(int argc, char *argv[]) errorcnt ? "aborted" : "exits successfully"); } + if (do_servo_cpu_fw_spi) + free(host_shell("dut-control cpu_fw_spi:off")); + updater_delete_config(cfg); return !!errorcnt; } diff --git a/futility/updater_utils.c b/futility/updater_utils.c index 3807fbbe..4a91a05f 100644 --- a/futility/updater_utils.c +++ b/futility/updater_utils.c @@ -435,6 +435,42 @@ static int host_get_platform_version(void) return rev; } +/* + * Helper function to detect type of Servo board attached to host, + * and store the right programmer / prepare settings to arguments. + * Returns 0 if success, non-zero if error. + */ +int host_detect_servo(const char **programmer_ptr, int *need_prepare_ptr) +{ + int ret = 0; + char *servo_type = host_shell("dut-control -o servo_type 2>/dev/null"); + const char *programmer = NULL; + int need_prepare = 0; /* To prepare by dut-control cpu_fw_spi:on */ + + if (!*servo_type) { + ERROR("Failed to get servo type. Check servod.\n"); + ret = 1; + } else if (strstr(servo_type, "servo_micro")) { + VB2_DEBUG("Selected Servo Micro.\n"); + programmer = "raiden_debug_spi"; + need_prepare = 1; + } else if (strstr(servo_type, "ccd_cr50")) { + VB2_DEBUG("Selected CCD CR50.\n"); + programmer = "raiden_debug_spi:target=AP"; + } else { + VB2_DEBUG("Selected Servo V2.\n"); + programmer = "ft2232_spi:type=servo-v2"; + need_prepare = 1; + } + + free(servo_type); + if (programmer && !*programmer_ptr) + *programmer_ptr = programmer; + *need_prepare_ptr = need_prepare; + + return ret; +} + /* * A helper function to invoke flashrom(8) command. * Returns 0 if success, non-zero if error. diff --git a/futility/updater_utils.h b/futility/updater_utils.h index f5248f86..5e6e99cd 100644 --- a/futility/updater_utils.h +++ b/futility/updater_utils.h @@ -170,6 +170,13 @@ enum wp_state { /* Helper function to return write protection status via given programmer. */ enum wp_state host_get_wp(const char *programmer); +/* + * Helper function to detect type of Servo board attached to host, + * and store the right programmer / prepare settings to arguments. + * Returns 0 if success, non-zero if error. + */ +int host_detect_servo(const char **programmer_ptr, int *need_prepare_ptr); + /* * Returns 1 if a given file (cbfs_entry_name) exists inside a particular CBFS * section of an image file, otherwise 0.