app: aboot: Add support for dynamic partitions fastboot commands

Changes to support
 * New fastboot commands, for dynamic partitions.
 * set and get recovery command fields.

Change-Id: Ie7dd7fb987e917ace1bacc035222f49915c3b8f8
Signed-off-by: Mayank Grover <groverm@codeaurora.org>
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 534db14..d5856eb 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -2,7 +2,7 @@
  * Copyright (c) 2009, Google Inc.
  * All rights reserved.
  *
- * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2019, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -4387,6 +4387,40 @@
 	return;
 }
 
+#if DYNAMIC_PARTITION_SUPPORT
+void cmd_reboot_fastboot(const char *arg, void *data, unsigned sz)
+{
+	dprintf(INFO, "rebooting the device - userspace fastboot\n");
+	if (send_recovery_cmd(RECOVERY_BOOT_FASTBOOT_CMD)) {
+		dprintf(CRITICAL, "ERROR: Failed to update recovery commands\n");
+		fastboot_fail("Failed to update recovery command");
+		return;
+	}
+	fastboot_okay("");
+	reboot_device(REBOOT_MODE_UNKNOWN);
+
+	//shouldn't come here.
+	dprintf(CRITICAL, "ERROR: Failed to reboot device\n");
+	return;
+}
+
+void cmd_reboot_recovery(const char *arg, void *data, unsigned sz)
+{
+	dprintf(INFO, "rebooting the device - recovery\n");
+	if (send_recovery_cmd(RECOVERY_BOOT_RECOVERY_CMD)) {
+		dprintf(CRITICAL, "ERROR: Failed to update recovery commands\n");
+		fastboot_fail("Failed to update recovery command");
+		return;
+	}
+	fastboot_okay("");
+	reboot_device(REBOOT_MODE_UNKNOWN);
+
+	//shouldn't come here.
+	dprintf(CRITICAL, "ERROR: Failed to reboot device\n");
+	return;
+}
+#endif
+
 void cmd_reboot_bootloader(const char *arg, void *data, unsigned sz)
 {
 	dprintf(INFO, "rebooting the device\n");
@@ -4910,6 +4944,10 @@
 						{"oem off-mode-charge", cmd_oem_off_mode_charger},
 						{"oem select-display-panel", cmd_oem_select_display_panel},
 						{"set_active",cmd_set_active},
+#if DYNAMIC_PARTITION_SUPPORT
+						{"reboot-fastboot",cmd_reboot_fastboot},
+						{"reboot-recovery",cmd_reboot_recovery},
+#endif
 #if UNITTEST_FW_SUPPORT
 						{"oem run-tests", cmd_oem_runtests},
 #endif
@@ -4988,6 +5026,8 @@
 	fastboot_publish("battery-voltage", (const char *) battery_voltage);
 	fastboot_publish("battery-soc-ok", (const char *) battery_soc_ok);
 #endif
+        if (target_dynamic_partition_supported())
+		fastboot_publish("is-userspace", "no");
 }
 
 void aboot_init(const struct app_descriptor *app)
diff --git a/app/aboot/recovery.c b/app/aboot/recovery.c
index 0cc2ceb..389b91d 100644
--- a/app/aboot/recovery.c
+++ b/app/aboot/recovery.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2017,2019 The Linux Foundation. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -241,7 +241,7 @@
 			sizeof(msg.command), msg.command);
 	}
 
-	if (!strcmp("boot-recovery",msg.command))
+	if (!strcmp(RECOVERY_BOOT_RECOVERY_CMD, msg.command))
 	{
 		if(!strcmp("RADIO",msg.status))
 		{
@@ -267,6 +267,12 @@
 		return 0;
 	}
 
+	if (target_dynamic_partition_supported() &&
+		!strcmp(RECOVERY_BOOT_FASTBOOT_CMD, msg.command)) {
+		boot_into_recovery = 1;		// Boot in userspace fastboot mode
+		return 0;
+	}
+
 	if (!strcmp("update-radio",msg.command)) {
 		dprintf(INFO,"start radio update\n");
 		valid_command = 1;
@@ -369,6 +375,28 @@
 	return 0;
 }
 
+/* Generic funcition to write misc commands. */
+int send_recovery_cmd(const char *command)
+{
+	struct recovery_message msg;
+	int status = 0;
+	memset(&msg, 0, sizeof(msg));
+
+	/* Populate command to msg */
+	snprintf(msg.command,
+		 sizeof(msg.command),
+		 command);
+
+	dprintf(INFO,"Recovery command: %s\n", msg.command);
+	if (target_is_emmc_boot())
+		/* Update emmc partition */
+		status = emmc_set_recovery_msg(&msg);
+	else
+		status = set_recovery_message(&msg);
+
+	return status;
+}
+
 int _emmc_recovery_init(void)
 {
 	int update_status = 0;
@@ -394,7 +422,12 @@
 			sizeof(msg->command), msg->command);
 	}
 
-	if (!strcmp(msg->command, "boot-recovery")) {
+	if (!strcmp(msg->command, RECOVERY_BOOT_RECOVERY_CMD)) {
+		boot_into_recovery = 1;
+	}
+
+	if (target_dynamic_partition_supported() &&
+		!strcmp(msg->command, RECOVERY_BOOT_FASTBOOT_CMD)) {
 		boot_into_recovery = 1;
 	}
 
diff --git a/app/aboot/recovery.h b/app/aboot/recovery.h
index 177148a..da7d400 100644
--- a/app/aboot/recovery.h
+++ b/app/aboot/recovery.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2017,2019 The Linux Foundation. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -38,6 +38,9 @@
 #define BOOTSELECT_FORMAT    (1 << 31)
 #define BOOTSELECT_FACTORY   (1 << 30)
 
+#define RECOVERY_BOOT_RECOVERY_CMD "boot-recovery"
+#define RECOVERY_BOOT_FASTBOOT_CMD "boot-fastboot"
+
 /* bootselect partition format structure */
 struct boot_selection_info {
 	uint32_t signature;                // Contains value BOOTSELECT_SIGNATURE defined above
@@ -78,7 +81,7 @@
 
 int get_recovery_message(struct recovery_message *out);
 int set_recovery_message(const struct recovery_message *in);
-
+int send_recovery_cmd(const char *command);
 int recovery_init (void);
 /* This function will look for the ffbm cookie in the misc partition.
  * Upon finding a valid cookie it will return 1 and place the cookie