bootstd: cros: Add ARM support

Support booting ChromiumOS on ARM devices using FIT. Add an entry into the
boot implementation which does not require a command line. This can be
expanded over time as the bootm code is refactored.

Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/boot/Kconfig b/boot/Kconfig
index b00d7a8..5e2d428 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -464,8 +464,8 @@
 
 config BOOTMETH_CROS
 	bool "Bootdev support for Chromium OS"
-	depends on X86 || SANDBOX
-	default y
+	depends on X86 || ARM || SANDBOX
+	default y if !ARM
 	help
 	  Enables support for booting Chromium OS using bootdevs. This uses the
 	  kernel A slot and obtains the kernel command line from the parameters
diff --git a/boot/bootm.c b/boot/bootm.c
index 75f0b4a..b1c3afe 100644
--- a/boot/bootm.c
+++ b/boot/bootm.c
@@ -823,6 +823,43 @@
 	return ret;
 }
 
+int bootm_boot_start(ulong addr, const char *cmdline)
+{
+	static struct cmd_tbl cmd = {"bootm"};
+	char addr_str[30];
+	char *argv[] = {addr_str, NULL};
+	int states;
+	int ret;
+
+	/*
+	 * TODO(sjg@chromium.org): This uses the command-line interface, but
+	 * should not. To clean this up, the various bootm states need to be
+	 * passed an info structure instead of cmdline flags. Then this can
+	 * set up the required info and move through the states without needing
+	 * the command line.
+	 */
+	states = BOOTM_STATE_START | BOOTM_STATE_FINDOS | BOOTM_STATE_PRE_LOAD |
+		BOOTM_STATE_FINDOTHER | BOOTM_STATE_LOADOS |
+		BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO |
+		BOOTM_STATE_OS_GO;
+	if (IS_ENABLED(CONFIG_SYS_BOOT_RAMDISK_HIGH))
+		states |= BOOTM_STATE_RAMDISK;
+	if (IS_ENABLED(CONFIG_PPC) || IS_ENABLED(CONFIG_MIPS))
+		states |= BOOTM_STATE_OS_CMDLINE;
+	images.state |= states;
+
+	snprintf(addr_str, sizeof(addr_str), "%lx", addr);
+
+	ret = env_set("bootargs", cmdline);
+	if (ret) {
+		printf("Failed to set cmdline\n");
+		return ret;
+	}
+	ret = do_bootm_states(&cmd, 0, 1, argv, states, &images, 1);
+
+	return ret;
+}
+
 #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
 /**
  * image_get_kernel - verify legacy format kernel image
diff --git a/boot/bootmeth_cros.c b/boot/bootmeth_cros.c
index 6c28feb..1776fb1 100644
--- a/boot/bootmeth_cros.c
+++ b/boot/bootmeth_cros.c
@@ -419,13 +419,17 @@
 		if (ret)
 			return log_msg_ret("rd", ret);
 	}
-#ifdef CONFIG_X86
-	zboot_start(map_to_sysmem(bflow->buf), bflow->size, 0, 0,
-		    map_to_sysmem(bflow->x86_setup),
-		    bflow->cmdline);
-#endif
 
-	return log_msg_ret("go", -EFAULT);
+	if (IS_ENABLED(CONFIG_X86)) {
+		ret = zboot_start(map_to_sysmem(bflow->buf), bflow->size, 0, 0,
+				  map_to_sysmem(bflow->x86_setup),
+				  bflow->cmdline);
+	} else {
+		ret = bootm_boot_start(map_to_sysmem(bflow->buf),
+				       bflow->cmdline);
+	}
+
+	return log_msg_ret("go", ret);
 }
 
 static int cros_bootmeth_bind(struct udevice *dev)