diff options
-rw-r--r-- | mmc.c | 5 | ||||
-rw-r--r-- | mmc.h | 6 | ||||
-rw-r--r-- | mmc_cmds.c | 67 | ||||
-rw-r--r-- | mmc_cmds.h | 1 |
4 files changed, 79 insertions, 0 deletions
@@ -65,6 +65,11 @@ static struct Command commands[] = { "Set the eMMC writeprotect status of <device>.", NULL }, + { do_write_boot_en, -3, + "bootpart enable", "<boot_partition> " "<send_ack> " "<device>\n" + "Enable the boot partition for the <device>.\nTo receive acknowledgment of boot from the card set <send_ack>\nto 1, else set it to 0.", + NULL + }, { 0, 0, 0, 0 } }; @@ -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) @@ -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 <partition_number> " + "<send_ack> </path/to/mmcblkX>\n", exit(1)); + + /* + * If <send_ack> is 1, the device will send acknowledgment + * pattern "010" to the host when boot operation begins. + * If <send_ack> 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; @@ -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); |