futility: updater: Support new servo control 'ccd_cpu_fw_spi'

Some newer devices need extra preparation steps even when using CCD via
servo, so a new 'ccd_cpu_fw_spi' is added to hdctools. The firmware
updater should use it in servo+ccd modes.

Also, the custom_rst is now moved to detect_servo so the --servo_noreset
option is removed.

BUG=b:216832684
TEST=make; run test
BRANCH=None

Change-Id: I6af0f03d5b0b1bb473ecb29680b253a5b71c7465
Signed-off-by: Hung-Te Lin <hungte@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/3577658
Reviewed-by: Wai-Hong Tam <waihong@google.com>
Tested-by: Wai-Hong Tam <waihong@google.com>
diff --git a/futility/cmd_update.c b/futility/cmd_update.c
index e4b3765..51893f6 100644
--- a/futility/cmd_update.c
+++ b/futility/cmd_update.c
@@ -57,7 +57,6 @@
 
 	{"ccd", 0, NULL, OPT_CCD},
 	{"servo", 0, NULL, OPT_SERVO},
-	{"servo_noreset", 0, NULL, OPT_SERVO_NORESET},
 	{"servo_port", 1, NULL, OPT_SERVO_PORT},
 	{"emulate", 1, NULL, OPT_EMULATE},
 	{"factory", 0, NULL, OPT_FACTORY},
@@ -134,7 +133,6 @@
 		"    --gbb_flags=FLAG\tOverride new GBB flags\n"
 		"    --ccd           \tDo fast,force,wp=0,p=raiden_debug_spi\n"
 		"    --servo         \tFlash using Servo (v2, v4, micro, ...)\n"
-		"    --servo_noreset \tLike servo but with 'custom_rst=true'\n"
 		"    --servo_port=PRT\tOverride servod port, implies --servo\n"
 		"    --signature_id=S\tOverride signature ID for key files\n"
 		"    --sys_props=LIST\tList of system properties to override\n"
@@ -144,21 +142,15 @@
 		argv[0]);
 }
 
-static char *add_servo_noreset(char *programmer)
+static void prepare_servo_control(const char *control_name, int on)
 {
-	char *ret;
+	char *cmd;
+	if (!control_name)
+		return;
 
-	if (strstr(programmer, "raiden_debug_spi:target=AP") == NULL) {
-		ERROR("servo_noreset only works for AP flashing over CCD.\n");
-		free(programmer);
-
-		return NULL;
-	}
-
-	ASPRINTF(&ret, "%s,custom_rst=true", programmer);
-	free(programmer);
-
-	return ret;
+	ASPRINTF(&cmd, "dut-control %s:%s", control_name, on ? "on" : "off");
+	free(host_shell(cmd));
+	free(cmd);
 }
 
 static int do_update(int argc, char *argv[])
@@ -166,7 +158,8 @@
 	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, servo_noreset = 0;
+	int detect_servo = 0;
+	const char *prepare_ctrl_name = NULL;
 	char *servo_programmer = NULL;
 	char *endptr;
 
@@ -277,14 +270,6 @@
 			args.host_only = 1;
 			detect_servo = 1;
 			break;
-		case OPT_SERVO_NORESET:
-			args.fast_update = 1;
-			args.force_update = 1;
-			args.write_protection = "0";
-			args.host_only = 1;
-			detect_servo = 1;
-			servo_noreset = 1;
-			break;
 		case OPT_SERVO_PORT:
 			setenv(ENV_SERVOD_PORT, optarg, 1);
 			args.fast_update = 1;
@@ -318,10 +303,7 @@
 	}
 
 	if (!errorcnt && detect_servo) {
-		servo_programmer = host_detect_servo(&do_servo_cpu_fw_spi);
-
-		if (servo_programmer && servo_noreset)
-			servo_programmer = add_servo_noreset(servo_programmer);
+		servo_programmer = host_detect_servo(&prepare_ctrl_name);
 
 		if (!servo_programmer)
 			errorcnt++;
@@ -333,8 +315,7 @@
 	 * 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"));
+	prepare_servo_control(prepare_ctrl_name, 1);
 
 	if (!errorcnt)
 		errorcnt += updater_setup_config(cfg, &args, &do_update);
@@ -353,8 +334,7 @@
 			errorcnt ? "aborted" : "exits successfully");
 	}
 
-	if (do_servo_cpu_fw_spi)
-		free(host_shell("dut-control cpu_fw_spi:off"));
+	prepare_servo_control(prepare_ctrl_name, 0);
 	free(servo_programmer);
 
 	updater_delete_config(cfg);
diff --git a/futility/updater_utils.c b/futility/updater_utils.c
index 762be7c..c6ddae6 100644
--- a/futility/updater_utils.c
+++ b/futility/updater_utils.c
@@ -456,16 +456,21 @@
  * Helper function to detect type of Servo board attached to host.
  * Returns a string as programmer parameter on success, otherwise NULL.
  */
-char *host_detect_servo(int *need_prepare_ptr)
+char *host_detect_servo(const char **prepare_ctrl_name)
 {
 	const char *servo_port = getenv(ENV_SERVOD_PORT);
 	const char *servo_name = getenv(ENV_SERVOD_NAME);
 	char *servo_type = host_shell("dut-control -o servo_type 2>/dev/null");
 	const char *programmer = NULL;
 	char *ret = NULL;
-	int need_prepare = 0;  /* To prepare by dut-control cpu_fw_spi:on */
 	char *servo_serial = NULL;
 
+	static const char * const cpu_fw_spi = "cpu_fw_spi";
+	static const char * const ccd_cpu_fw_spi = "ccd_cpu_fw_spi";
+
+	/* By default, no control is needed. */
+	*prepare_ctrl_name = NULL;
+
 	/* Get serial name if servo port is provided. */
 	if ((servo_port && *servo_port) || (servo_name && *servo_name)) {
 		const char *cmd = "dut-control -o serialname 2>/dev/null";
@@ -492,19 +497,20 @@
 	} else if (strstr(servo_type, "servo_micro")) {
 		VB2_DEBUG("Selected Servo Micro.\n");
 		programmer = "raiden_debug_spi";
-		need_prepare = 1;
+		*prepare_ctrl_name = cpu_fw_spi;
 	} else if (strstr(servo_type, "c2d2")) {
 		VB2_DEBUG("Selected C2D2.\n");
 		programmer = "raiden_debug_spi";
-		need_prepare = 1;
+		*prepare_ctrl_name = cpu_fw_spi;
 	} else if (strstr(servo_type, "ccd_cr50") ||
 		   strstr(servo_type, "ccd_gsc")) {
 		VB2_DEBUG("Selected CCD.\n");
-		programmer = "raiden_debug_spi:target=AP";
+		programmer = "raiden_debug_spi:target=AP,custom_rst=true";
+		*prepare_ctrl_name = ccd_cpu_fw_spi;
 	} else {
 		VB2_DEBUG("Selected Servo V2.\n");
 		programmer = "ft2232_spi:type=google-servo-v2";
-		need_prepare = 1;
+		*prepare_ctrl_name = cpu_fw_spi;
 	}
 
 	if (programmer) {
@@ -520,7 +526,6 @@
 
 	free(servo_type);
 	free(servo_serial);
-	*need_prepare_ptr = need_prepare;
 
 	return ret;
 }
diff --git a/futility/updater_utils.h b/futility/updater_utils.h
index 0376eb3..a433ead 100644
--- a/futility/updater_utils.h
+++ b/futility/updater_utils.h
@@ -200,7 +200,7 @@
  * Helper function to detect type of Servo board attached to host.
  * Returns a string as programmer parameter on success, otherwise NULL.
  */
-char *host_detect_servo(int *need_prepare_ptr);
+char *host_detect_servo(const char **prepare_ctrl_name);
 
 /*
  * Returns 1 if a given file (cbfs_entry_name) exists inside a particular CBFS