diff --git a/mmc.c b/mmc.c index c27fc24..6927b70 100644 --- a/mmc.c +++ b/mmc.c @@ -65,6 +65,11 @@ static struct Command commands[] = { "Set the eMMC writeprotect status of .", NULL }, + { do_write_boot_en, -3, + "bootpart enable", " " " " "\n" + "Enable the boot partition for the .\nTo receive acknowledgment of boot from the card set \nto 1, else set it to 0.", + NULL + }, { 0, 0, 0, 0 } }; diff --git a/mmc.h b/mmc.h index 3af36f1..cedfae1 100644 --- a/mmc.h +++ b/mmc.h @@ -35,6 +35,7 @@ #define EXT_CSD_PART_SWITCH_TIME 199 #define EXT_CSD_BOOT_CFG 179 #define EXT_CSD_BOOT_WP 173 +#define EXT_CSD_PART_CONFIG 179 /* * EXT_CSD field definitions @@ -52,6 +53,11 @@ #define EXT_CSD_BOOT_CFG_ACK (1<<6) #define EXT_CSD_BOOT_CFG_EN (0x38) #define EXT_CSD_BOOT_CFG_ACC (0x03) +#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7) +#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1) +#define EXT_CSD_PART_CONFIG_ACC_BOOT1 (0x2) +#define EXT_CSD_PART_CONFIG_ACC_USER_AREA (0x7) +#define EXT_CSD_PART_CONFIG_ACC_ACK (0x40) /* From kernel linux/mmc/core.h */ #define MMC_RSP_PRESENT (1 << 0) diff --git a/mmc_cmds.c b/mmc_cmds.c index 4562cef..2ab4185 100644 --- a/mmc_cmds.c +++ b/mmc_cmds.c @@ -168,6 +168,73 @@ int do_writeprotect_set(int nargs, char **argv) return ret; } +int do_write_boot_en(int nargs, char **argv) +{ + __u8 ext_csd[512]; + __u8 value = 0; + int fd, ret; + char *device; + int boot_area, send_ack; + + CHECK(nargs != 4, "Usage: mmc bootpart enable " + " \n", exit(1)); + + /* + * If is 1, the device will send acknowledgment + * pattern "010" to the host when boot operation begins. + * If is 0, it won't. + */ + boot_area = strtol(argv[1], NULL, 10); + send_ack = strtol(argv[2], NULL, 10); + device = argv[3]; + + fd = open(device, O_RDWR); + if (fd < 0) { + perror("open"); + exit(1); + } + + ret = read_extcsd(fd, ext_csd); + if (ret) { + fprintf(stderr, "Could not read EXT_CSD from %s\n", device); + exit(1); + } + + value = ext_csd[EXT_CSD_PART_CONFIG]; + + switch (boot_area) { + case EXT_CSD_PART_CONFIG_ACC_BOOT0: + value |= (1 << 3); + value &= ~(3 << 4); + break; + case EXT_CSD_PART_CONFIG_ACC_BOOT1: + value |= (1 << 4); + value &= ~(1 << 3); + value &= ~(1 << 5); + break; + case EXT_CSD_PART_CONFIG_ACC_USER_AREA: + value |= (boot_area << 3); + break; + default: + fprintf(stderr, "Cannot enable the boot area\n"); + exit(1); + } + if (send_ack) + value |= EXT_CSD_PART_CONFIG_ACC_ACK; + else + value &= ~EXT_CSD_PART_CONFIG_ACC_ACK; + + ret = write_extcsd_value(fd, EXT_CSD_PART_CONFIG, value); + if (ret) { + fprintf(stderr, "Could not write 0x%02x to " + "EXT_CSD[%d] in %s\n", + value, EXT_CSD_PART_CONFIG, device); + exit(1); + } + return ret; +} + + int do_read_extcsd(int nargs, char **argv) { __u8 ext_csd[512], ext_csd_rev, reg; diff --git a/mmc_cmds.h b/mmc_cmds.h index 66e9acb..264409a 100644 --- a/mmc_cmds.h +++ b/mmc_cmds.h @@ -19,3 +19,4 @@ int do_read_extcsd(int nargs, char **argv); int do_write_extcsd(int nargs, char **argv); int do_writeprotect_get(int nargs, char **argv); int do_writeprotect_set(int nargs, char **argv); +int do_write_boot_en(int nargs, char **argv);