summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/cmd_fastboot.c6
-rw-r--r--common/fb_mmc.c60
-rw-r--r--common/spl/spl.c35
3 files changed, 99 insertions, 2 deletions
diff --git a/common/cmd_fastboot.c b/common/cmd_fastboot.c
index b72f4f310d..346ab80454 100644
--- a/common/cmd_fastboot.c
+++ b/common/cmd_fastboot.c
@@ -20,6 +20,12 @@ static int do_fastboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
if (ret)
return ret;
+ if (!g_dnl_board_usb_cable_connected()) {
+ puts("\rUSB cable not detected.\n" \
+ "Command exit.\n");
+ return CMD_RET_FAILURE;
+ }
+
while (1) {
if (g_dnl_detach())
break;
diff --git a/common/fb_mmc.c b/common/fb_mmc.c
index 6ea3938d83..75899e4c28 100644
--- a/common/fb_mmc.c
+++ b/common/fb_mmc.c
@@ -10,6 +10,7 @@
#include <part.h>
#include <aboot.h>
#include <sparse_format.h>
+#include <mmc.h>
#ifndef CONFIG_FASTBOOT_GPT_NAME
#define CONFIG_FASTBOOT_GPT_NAME GPT_ENTRY_NAME
@@ -22,13 +23,13 @@ static char *response_str;
void fastboot_fail(const char *s)
{
- strncpy(response_str, "FAIL", 4);
+ strncpy(response_str, "FAIL\0", 5);
strncat(response_str, s, RESPONSE_LEN - 4 - 1);
}
void fastboot_okay(const char *s)
{
- strncpy(response_str, "OKAY", 4);
+ strncpy(response_str, "OKAY\0", 5);
strncat(response_str, s, RESPONSE_LEN - 4 - 1);
}
@@ -110,3 +111,58 @@ void fb_mmc_flash_write(const char *cmd, void *download_buffer,
write_raw_image(dev_desc, &info, cmd, download_buffer,
download_bytes);
}
+
+void fb_mmc_erase(const char *cmd, char *response)
+{
+ int ret;
+ block_dev_desc_t *dev_desc;
+ disk_partition_t info;
+ lbaint_t blks, blks_start, blks_size, grp_size;
+ struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
+
+ if (mmc == NULL) {
+ error("invalid mmc device");
+ fastboot_fail("invalid mmc device");
+ return;
+ }
+
+ /* initialize the response buffer */
+ response_str = response;
+
+ dev_desc = get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
+ if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
+ error("invalid mmc device");
+ fastboot_fail("invalid mmc device");
+ return;
+ }
+
+ ret = get_partition_info_efi_by_name(dev_desc, cmd, &info);
+ if (ret) {
+ error("cannot find partition: '%s'", cmd);
+ fastboot_fail("cannot find partition");
+ return;
+ }
+
+ /* Align blocks to erase group size to avoid erasing other partitions */
+ grp_size = mmc->erase_grp_size;
+ blks_start = (info.start + grp_size - 1) & ~(grp_size - 1);
+ if (info.size >= grp_size)
+ blks_size = (info.size - (blks_start - info.start)) &
+ (~(grp_size - 1));
+ else
+ blks_size = 0;
+
+ printf("Erasing blocks " LBAFU " to " LBAFU " due to alignment\n",
+ blks_start, blks_start + blks_size);
+
+ blks = dev_desc->block_erase(dev_desc->dev, blks_start, blks_size);
+ if (blks != blks_size) {
+ error("failed erasing from device %d", dev_desc->dev);
+ fastboot_fail("failed erasing from device");
+ return;
+ }
+
+ printf("........ erased " LBAFU " bytes from '%s'\n",
+ blks_size * info.blksz, cmd);
+ fastboot_okay("");
+}
diff --git a/common/spl/spl.c b/common/spl/spl.c
index ded0f30478..cd75bbc4ce 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -281,3 +281,38 @@ void preloader_console_init(void)
spl_display_print();
#endif
}
+
+/**
+ * spl_relocate_stack_gd() - Relocate stack ready for board_init_r() execution
+ *
+ * Sometimes board_init_f() runs with a stack in SRAM but we want to use SDRAM
+ * for the main board_init_r() execution. This is typically because we need
+ * more stack space for things like the MMC sub-system.
+ *
+ * This function calculates the stack position, copies the global_data into
+ * place and returns the new stack position. The caller is responsible for
+ * setting up the sp register.
+ *
+ * @return new stack location, or 0 to use the same stack
+ */
+ulong spl_relocate_stack_gd(void)
+{
+#ifdef CONFIG_SPL_STACK_R
+ gd_t *new_gd;
+ ulong ptr;
+
+ /* Get stack position: use 8-byte alignment for ABI compliance */
+ ptr = CONFIG_SPL_STACK_R - sizeof(gd_t);
+ ptr &= ~7;
+ new_gd = (gd_t *)ptr;
+ memcpy(new_gd, (void *)gd, sizeof(gd_t));
+ gd = new_gd;
+
+ /* Clear the BSS. */
+ memset(__bss_start, 0, __bss_end - __bss_start);
+
+ return ptr;
+#else
+ return 0;
+#endif
+}