diff options
-rw-r--r-- | commands/mmc_extcsd.c | 2783 | ||||
-rw-r--r-- | include/mci.h | 7 |
2 files changed, 1603 insertions, 1187 deletions
diff --git a/commands/mmc_extcsd.c b/commands/mmc_extcsd.c index 4c8537fe86..7a6d39075d 100644 --- a/commands/mmc_extcsd.c +++ b/commands/mmc_extcsd.c @@ -26,39 +26,39 @@ #define EXT_CSD_BLOCKSIZE 512 /* Access types */ -#define R "R" -#define RW "R/W" -#define RWaR "R/W & R" -#define RWaRWE "R/W & R/W/E" -#define RWaRWC_P "R/W & R/W/C_P" -#define RWaRWC_PaRWE_P "R/W, R/W/C_P & R/W/E_P" -#define WE "W/E" -#define RWE "R/W/E" -#define RWEaR "R/W/E & R" -#define RWEaRWE_P "R/W/E & R/W/E_P" -#define RWC_P "R/W/C_P" -#define RWE_P "R/W/E_P" -#define WE_P "W/E_P" - -#define print_field_caption(reg_name, access_mode) \ - do { \ - printf(#reg_name"[%u]:\n", EXT_CSD_##reg_name); \ - printf("\tValue: %#02x\n", reg[index]); \ - printf("\tAccess: "access_mode"\n"); \ - } while (false); - -#define print_field_caption_with_offset(reg_name, offset, access_mode) \ - do { \ - printf(#reg_name"[%u]:\n", EXT_CSD_##reg_name + offset); \ - printf("\tValue: %#02x\n", reg[index]); \ - printf("\tAccess: "access_mode"\n"); \ - } while (false); -#define get_field_val(reg_name, offset, mask) \ - ((reg[EXT_CSD_##reg_name] >> offset) & mask) +#define ACC_R 0 +#define ACC_RW 1 +#define ACC_RWaR 2 +#define ACC_RWaRWE 3 +#define ACC_RWaRWC_P 4 +#define ACC_RWaRWC_PaRWE_P 5 +#define ACC_WE 6 +#define ACC_RWE 7 +#define ACC_RWEaR 8 +#define ACC_RWEaRWE_P 9 +#define ACC_RWC_P 10 +#define ACC_RWE_P 11 +#define ACC_WE_P 12 + +static char *access_types[] = { + [ACC_R] = "R", + [ACC_RW] = "R/W", + [ACC_RWaR] = "R/W & R", + [ACC_RWaRWE] = "R/W & R/W/E", + [ACC_RWaRWC_P] = "R/W & R/W/C_P", + [ACC_RWaRWC_PaRWE_P] = "R/W, R/W/C_P & R/W/E_P", + [ACC_WE] = "W/E", + [ACC_RWE] = "R/W/E", + [ACC_RWEaR] = "R/W/E & R", + [ACC_RWEaRWE_P] = "R/W/E & R/W/E_P", + [ACC_RWC_P] = "R/W/C_P", + [ACC_RWE_P] = "R/W/E_P", + [ACC_WE_P] = "W/E_P", +}; -#define get_field_val_with_index(index, offset, mask) \ - ((reg[index] >> offset) & mask) +#define get_field_val(reg_name, offset, mask) \ + ((reg[reg_name] >> offset) & mask) static void print_access_type_key(void) { @@ -69,714 +69,1261 @@ static void print_access_type_key(void) "E_P:\tValue cleared by power failure and CMD0\n"); } -static int print_field_ge_v7(u8 *reg, int index) +struct extcsd_reg { + const char *name; + unsigned char access; + unsigned char width; +}; + +static struct extcsd_reg extcsd[] = { + [EXT_CSD_CMDQ_MODE_EN] = { + .name = "EXT_CSD_CMDQ_MODE_EN", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_SECURE_REMOVAL_TYPE] = { + .name = "EXT_CSD_SECURE_REMOVAL_TYPE", + .access = ACC_RWaR, + .width = 1, + }, + [EXT_CSD_PRODUCT_ST8_AWARENSS_ENABLEMENT] = { + .name = "EXT_CSD_PRODUCT_ST8_AWARENSS_ENABLEMENT", + .access = ACC_RWEaR, + .width = 1, + }, + [EXT_CSD_MAX_PRE_LOADING_DATA_SIZE] = { + .name = "EXT_CSD_MAX_PRE_LOADING_DATA_SIZE", + .access = ACC_R, + .width = 4, + }, + [EXT_CSD_PRE_LOADING_DATA_SIZE] = { + .name = "EXT_CSD_PRE_LOADING_DATA_SIZE", + .access = ACC_RWE_P, + .width = 4, + }, + [EXT_CSD_FFU_STATUS] = { + .name = "EXT_CSD_FFU_STATUS", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_MODE_CONFIG] = { + .name = "EXT_CSD_MODE_CONFIG", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_BARRIER_CTRL] = { + .name = "EXT_CSD_BARRIER_CTRL", + .access = ACC_RW, + .width = 1, + }, + [EXT_CSD_CACHE_CTRL] = { + .name = "EXT_CSD_CACHE_CTRL", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_POWER_OFF_NOTIFICATION] = { + .name = "EXT_CSD_POWER_OFF_NOTIFICATION", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_PACKED_FAILURE_INDEX] = { + .name = "EXT_CSD_PACKED_FAILURE_INDEX", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_PACKED_COMMAND_STATUS] = { + .name = "EXT_CSD_PACKED_COMMAND_STATUS", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_CONTEXT_CONF(1)] = { + .name = "EXT_CSD_CONTEXT_CONF1", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_CONTEXT_CONF(2)] = { + .name = "EXT_CSD_CONTEXT_CONF2", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_CONTEXT_CONF(3)] = { + .name = "EXT_CSD_CONTEXT_CONF3", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_CONTEXT_CONF(4)] = { + .name = "EXT_CSD_CONTEXT_CONF4", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_CONTEXT_CONF(5)] = { + .name = "EXT_CSD_CONTEXT_CONF5", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_CONTEXT_CONF(6)] = { + .name = "EXT_CSD_CONTEXT_CONF6", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_CONTEXT_CONF(7)] = { + .name = "EXT_CSD_CONTEXT_CONF7", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_CONTEXT_CONF(8)] = { + .name = "EXT_CSD_CONTEXT_CONF8", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_CONTEXT_CONF(9)] = { + .name = "EXT_CSD_CONTEXT_CONF9", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_CONTEXT_CONF(10)] = { + .name = "EXT_CSD_CONTEXT_CONF10", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_CONTEXT_CONF(11)] = { + .name = "EXT_CSD_CONTEXT_CONF11", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_CONTEXT_CONF(12)] = { + .name = "EXT_CSD_CONTEXT_CONF12", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_CONTEXT_CONF(13)] = { + .name = "EXT_CSD_CONTEXT_CONF13", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_CONTEXT_CONF(14)] = { + .name = "EXT_CSD_CONTEXT_CONF14", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_CONTEXT_CONF(15)] = { + .name = "EXT_CSD_CONTEXT_CONF15", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_EXT_PARTITIONS_ATTRIBUTE] = { + .name = "EXT_CSD_EXT_PARTITIONS_ATTRIBUTE", + .access = ACC_RW, + .width = 2, + }, + [EXT_CSD_EXCEPTION_EVENTS_STATUS] = { + .name = "EXT_CSD_EXCEPTION_EVENTS_STATUS", + .access = ACC_R, + .width = 2, + }, + [EXT_CSD_EXCEPTION_EVENTS_STATUS] = { + .name = "EXT_CSD_EXCEPTION_EVENTS_STATUS", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_EXCEPTION_EVENTS_CTRL] = { + .name = "EXT_CSD_EXCEPTION_EVENTS_CTRL", + .access = ACC_RWE_P, + .width = 2, + }, + [EXT_CSD_CLASS_6_CTRL] = { + .name = "EXT_CSD_CLASS_6_CTRL", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_INI_TIMEOUT_EMU] = { + .name = "EXT_CSD_INI_TIMEOUT_EMU", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_DATA_SECTOR_SIZE] = { + .name = "EXT_CSD_DATA_SECTOR_SIZE", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_USE_NATIVE_SECTOR] = { + .name = "EXT_CSD_USE_NATIVE_SECTOR", + .access = ACC_RW, + .width = 1, + }, + [EXT_CSD_NATIVE_SECTOR_SIZE] = { + .name = "EXT_CSD_NATIVE_SECTOR_SIZE", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_PROGRAM_CID_CSD_DDR_SUPPORT] = { + .name = "EXT_CSD_PROGRAM_CID_CSD_DDR_SUPPORT", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_PERIODIC_WAKEUP] = { + .name = "EXT_CSD_PERIODIC_WAKEUP", + .access = ACC_RWE, + .width = 1, + }, + [EXT_CSD_TCASE_SUPPORT] = { + .name = "EXT_CSD_TCASE_SUPPORT", + .access = ACC_WE_P, + .width = 1, + }, + [EXT_CSD_PRODUCTION_STATE_AWARENESS] = { + .name = "EXT_CSD_PRODUCTION_STATE_AWARENESS", + .access = ACC_RWE, + .width = 1, + }, + [EXT_CSD_SEC_BAD_BLK_MGMNT] = { + .name = "EXT_CSD_SEC_BAD_BLK_MGMNT", + .access = ACC_RW, + .width = 1, + }, + [EXT_CSD_ENH_START_ADDR] = { + .name = "EXT_CSD_ENH_START_ADDR", + .access = ACC_RW, + .width = 4, + }, + [EXT_CSD_ENH_SIZE_MULT] = { + .name = "EXT_CSD_ENH_SIZE_MULT", + .access = ACC_RW, + .width = 3, + }, + [EXT_CSD_GP_SIZE_MULT0] = { + .name = "EXT_CSD_GP_SIZE_MULT0", + .access = ACC_RW, + .width = 3, + }, + [EXT_CSD_GP_SIZE_MULT1] = { + .name = "EXT_CSD_GP_SIZE_MULT1", + .access = ACC_RW, + .width = 3, + }, + [EXT_CSD_GP_SIZE_MULT2] = { + .name = "EXT_CSD_GP_SIZE_MULT2", + .access = ACC_RW, + .width = 3, + }, + [EXT_CSD_GP_SIZE_MULT3] = { + .name = "EXT_CSD_GP_SIZE_MULT3", + .access = ACC_RW, + .width = 3, + }, + [EXT_CSD_PARTITION_SETTING_COMPLETED] = { + .name = "EXT_CSD_PARTITION_SETTING_COMPLETED", + .access = ACC_RW, + .width = 1, + }, + [EXT_CSD_PARTITIONS_ATTRIBUTE] = { + .name = "EXT_CSD_PARTITIONS_ATTRIBUTE", + .access = ACC_RW, + .width = 1, + }, + [EXT_CSD_MAX_ENH_SIZE_MULT] = { + .name = "EXT_CSD_MAX_ENH_SIZE_MULT", + .access = ACC_R, + .width = 3, + }, + [EXT_CSD_PARTITIONING_SUPPORT] = { + .name = "EXT_CSD_PARTITIONING_SUPPORT", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_HPI_MGMT] = { + .name = "EXT_CSD_HPI_MGMT", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_RST_N_FUNCTION] = { + .name = "EXT_CSD_RST_N_FUNCTION", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_BKOPS_EN] = { + .name = "EXT_CSD_BKOPS_EN", + .access = ACC_RWaRWE, + .width = 1, + }, + [EXT_CSD_BKOPS_START] = { + .name = "EXT_CSD_BKOPS_START", + .access = ACC_WE_P, + .width = 1, + }, + [EXT_CSD_SANITIZE_START] = { + .name = "EXT_CSD_SANITIZE_START", + .access = ACC_WE_P, + .width = 1, + }, + [EXT_CSD_WR_REL_PARAM] = { + .name = "EXT_CSD_WR_REL_PARAM", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_WR_REL_SET] = { + .name = "EXT_CSD_WR_REL_SET", + .access = ACC_RW, + .width = 1, + }, + [EXT_CSD_RPMB_SIZE_MULT] = { + .name = "EXT_CSD_RPMB_SIZE_MULT", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_FW_CONFIG] = { + .name = "EXT_CSD_FW_CONFIG", + .access = ACC_RW, + .width = 1, + }, + [EXT_CSD_USER_WP] = { + .name = "EXT_CSD_USER_WP", + .access = ACC_RWaRWC_PaRWE_P, + .width = 1, + }, + [EXT_CSD_BOOT_WP] = { + .name = "EXT_CSD_BOOT_WP", + .access = ACC_RWaRWC_P, + .width = 1, + }, + [EXT_CSD_BOOT_WP_STATUS] = { + .name = "EXT_CSD_BOOT_WP_STATUS", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_ERASE_GROUP_DEF] = { + .name = "EXT_CSD_ERASE_GROUP_DEF", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_BOOT_BUS_CONDITIONS] = { + .name = "EXT_CSD_BOOT_BUS_CONDITIONS", + .access = ACC_RWE, + .width = 1, + }, + [EXT_CSD_BOOT_CONFIG_PROT] = { + .name = "EXT_CSD_BOOT_CONFIG_PROT", + .access = ACC_RWaRWC_P, + .width = 1, + }, + [EXT_CSD_PARTITION_CONFIG] = { + .name = "EXT_CSD_PARTITION_CONFIG", + .access = ACC_RWEaRWE_P, + .width = 1, + }, + [EXT_CSD_ERASED_MEM_CONT] = { + .name = "EXT_CSD_ERASED_MEM_CONT", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_BUS_WIDTH] = { + .name = "EXT_CSD_BUS_WIDTH", + .access = ACC_WE_P, + .width = 1, + }, + [EXT_CSD_STROBE_SUPPORT] = { + .name = "EXT_CSD_STROBE_SUPPORT", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_HS_TIMING] = { + .name = "EXT_CSD_HS_TIMING", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_POWER_CLASS] = { + .name = "EXT_CSD_POWER_CLASS", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_CMD_SET_REV] = { + .name = "EXT_CSD_CMD_SET_REV", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_CMD_SET] = { + .name = "EXT_CSD_CMD_SET", + .access = ACC_RWE_P, + .width = 1, + }, + [EXT_CSD_REV] = { + .name = "EXT_CSD_REV", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_CSD_STRUCTURE] = { + .name = "EXT_CSD_CSD_STRUCTURE", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_DEVICE_TYPE] = { + .name = "EXT_CSD_DEVICE_TYPE", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_DRIVER_STRENGTH] = { + .name = "EXT_CSD_DRIVER_STRENGTH", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_OUT_OF_INTERRUPT_TIME] = { + .name = "EXT_CSD_OUT_OF_INTERRUPT_TIME", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_PARTITION_SWITCH_TIME] = { + .name = "EXT_CSD_PARTITION_SWITCH_TIME", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_PWR_CL_52_195] = { + .name = "EXT_CSD_PWR_CL_52_195", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_PWR_CL_26_195] = { + .name = "EXT_CSD_PWR_CL_26_195", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_PWR_CL_52_360] = { + .name = "EXT_CSD_PWR_CL_52_360", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_PWR_CL_26_360] = { + .name = "EXT_CSD_PWR_CL_26_360", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_MIN_PERF_R_4_26] = { + .name = "EXT_CSD_MIN_PERF_R_4_26", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_MIN_PERF_W_4_26] = { + .name = "EXT_CSD_MIN_PERF_W_4_26", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_MIN_PERF_R_8_26_4_52] = { + .name = "EXT_CSD_MIN_PERF_R_8_26_4_52", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_MIN_PERF_W_8_26_4_52] = { + .name = "EXT_CSD_MIN_PERF_W_8_26_4_52", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_MIN_PERF_R_8_52] = { + .name = "EXT_CSD_MIN_PERF_R_8_52", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_MIN_PERF_W_8_52] = { + .name = "EXT_CSD_MIN_PERF_W_8_52", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_SECURE_WP_INFO] = { + .name = "EXT_CSD_SECURE_WP_INFO", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_SEC_COUNT] = { + .name = "EXT_CSD_SEC_COUNT", + .access = ACC_R, + .width = 4, + }, + [EXT_CSD_SLEEP_NOTIFICATION_TIME] = { + .name = "EXT_CSD_SLEEP_NOTIFICATION_TIME", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_S_A_TIMEOUT] = { + .name = "EXT_CSD_S_A_TIMEOUT", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_PRODUCTION_ST8_AWARENSS_TIMEOUT] = { + .name = "EXT_CSD_PRODUCTION_ST8_AWARENSS_TIMEOUT", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_S_C_VCCQ] = { + .name = "EXT_CSD_S_C_VCCQ", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_S_C_VCC] = { + .name = "EXT_CSD_S_C_VCC", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_HC_WP_GRP_SIZE] = { + .name = "EXT_CSD_HC_WP_GRP_SIZE", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_REL_WR_SEC_C] = { + .name = "EXT_CSD_REL_WR_SEC_C", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_ERASE_TIMEOUT_MULT] = { + .name = "EXT_CSD_ERASE_TIMEOUT_MULT", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_HC_ERASE_GRP_SIZE] = { + .name = "EXT_CSD_HC_ERASE_GRP_SIZE", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_ACC_SIZE] = { + .name = "EXT_CSD_ACC_SIZE", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_BOOT_SIZE_MULT] = { + .name = "EXT_CSD_BOOT_SIZE_MULT", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_BOOT_INFO] = { + .name = "EXT_CSD_BOOT_INFO", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_SEC_TRIM_MULT] = { + .name = "EXT_CSD_SEC_TRIM_MULT", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_SEC_ERASE_MULT] = { + .name = "EXT_CSD_SEC_ERASE_MULT", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_SEC_FEATURE_SUPPORT] = { + .name = "EXT_CSD_SEC_FEATURE_SUPPORT", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_TRIM_MULT] = { + .name = "EXT_CSD_TRIM_MULT", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_MIN_PERF_DDR_R_8_52] = { + .name = "EXT_CSD_MIN_PERF_DDR_R_8_52", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_MIN_PERF_DDR_W_8_52] = { + .name = "EXT_CSD_MIN_PERF_DDR_W_8_52", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_PWR_CL_200_195] = { + .name = "EXT_CSD_PWR_CL_200_195", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_PWR_CL_200_360] = { + .name = "EXT_CSD_PWR_CL_200_360", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_PWR_CL_DDR_52_195] = { + .name = "EXT_CSD_PWR_CL_DDR_52_195", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_PWR_CL_DDR_52_360] = { + .name = "EXT_CSD_PWR_CL_DDR_52_360", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_CACHE_FLUSH_POLICY] = { + .name = "EXT_CSD_CACHE_FLUSH_POLICY", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_INI_TIMEOUT_AP] = { + .name = "EXT_CSD_INI_TIMEOUT_AP", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_CORRECTLY_PRG_SECTORS_NUM] = { + .name = "EXT_CSD_CORRECTLY_PRG_SECTORS_NUM", + .access = ACC_R, + .width = 4, + }, + [EXT_CSD_BKOPS_STATUS] = { + .name = "EXT_CSD_BKOPS_STATUS", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_POWER_OFF_LONG_TIME] = { + .name = "EXT_CSD_POWER_OFF_LONG_TIME", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_GENERIC_CMD6_TIME] = { + .name = "EXT_CSD_GENERIC_CMD6_TIME", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_CACHE_SIZE] = { + .name = "EXT_CSD_CACHE_SIZE", + .access = ACC_R, + .width = 4, + }, + [EXT_CSD_OPTIMAL_WRITE_SIZE] = { + .name = "EXT_CSD_OPTIMAL_WRITE_SIZE", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_OPTIMAL_READ_SIZE] = { + .name = "EXT_CSD_OPTIMAL_READ_SIZE", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_PRE_EOL_INFO] = { + .name = "EXT_CSD_PRE_EOL_INFO", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A] = { + .name = "EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B] = { + .name = "EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_NMBR_OF_FW_SCTRS_CRRCTLY_PRGRMD] = { + .name = "EXT_CSD_NMBR_OF_FW_SCTRS_CRRCTLY_PRGRMD", + .access = ACC_R, + .width = 4, + }, + [EXT_CSD_CMDQ_DEPTH] = { + .name = "EXT_CSD_CMDQ_DEPTH", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_CMDQ_SUPPORT] = { + .name = "EXT_CSD_CMDQ_SUPPORT", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_BARRIER_SUPPORT] = { + .name = "EXT_CSD_BARRIER_SUPPORT", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_FFU_ARG] = { + .name = "EXT_CSD_FFU_ARG", + .access = ACC_R, + .width = 4, + }, + [EXT_CSD_OPERATION_CODES_TIMEOUT] = { + .name = "EXT_CSD_OPERATION_CODES_TIMEOUT", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_FFU_FEATURES] = { + .name = "EXT_CSD_FFU_FEATURES", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_SUPPORTED_MODES] = { + .name = "EXT_CSD_SUPPORTED_MODES", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_EXT_SUPPORT] = { + .name = "EXT_CSD_EXT_SUPPORT", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_LARGE_UNIT_SIZE_M1] = { + .name = "EXT_CSD_LARGE_UNIT_SIZE_M1", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_CONTEXT_CAPABILITIES] = { + .name = "EXT_CSD_CONTEXT_CAPABILITIES", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_TAG_RES_SIZE] = { + .name = "EXT_CSD_TAG_RES_SIZE", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_TAG_UNIT_SIZE] = { + .name = "EXT_CSD_TAG_UNIT_SIZE", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_DATA_TAG_SUPPORT] = { + .name = "EXT_CSD_DATA_TAG_SUPPORT", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_MAX_PACKED_WRITES] = { + .name = "EXT_CSD_MAX_PACKED_WRITES", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_MAX_PACKED_READS] = { + .name = "EXT_CSD_MAX_PACKED_READS", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_BKOPS_SUPPORT] = { + .name = "EXT_CSD_BKOPS_SUPPORT", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_HPI_FEATURES] = { + .name = "EXT_CSD_HPI_FEATURES", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_S_CMD_SET] = { + .name = "EXT_CSD_S_CMD_SET", + .access = ACC_R, + .width = 1, + }, + [EXT_CSD_EXT_SECURITY_ERR] = { + .name = "EXT_CSD_EXT_SECURITY_ERR", + .access = ACC_R, + .width = 1, + }, +}; + +static int print_field(u8 *reg, int index) { - int rev; - u32 val; - u32 tmp; - u64 tmp64; + u32 val, tmp; + u64 tmp64 = 0; char *str = NULL; + struct extcsd_reg *ext; + int i; + + if (index >= ARRAY_SIZE(extcsd)) + return 0; + + ext = &extcsd[index]; + + if (!ext->name) + return 0; - rev = reg[EXT_CSD_REV]; + for (i = 0; i < ext->width; i++) + tmp64 |= (u64)reg[index + i] << (i * 8); + + if (ext->width > 1) + printf("%s[%u-%u]:\n", ext->name, index, index + ext->width - 1); + else + printf("%s[%u]:\n", ext->name, index); + printf("\tValue: 0x%02llx\n", tmp64); + printf("\tAccess: %s\n", access_types[ext->access]); + + val = tmp64; switch (index) { - case EXT_CSD_CMDQ_MODE_EN: - print_field_caption(CMDQ_MODE_EN, RWE_P); - val = get_field_val(CMDQ_MODE_EN, 0, 0x1); - printf("\tCommand queuing is %sabled\n", val ? "en" : "dis"); + case EXT_CSD_ERASE_GROUP_DEF: + val = get_field_val(EXT_CSD_ERASE_GROUP_DEF, 0, 0x1); + printf("\t[0] ENABLE: Use %s size definition\n", + val ? "high-capacity" : "old"); return 1; - case EXT_CSD_SECURE_REMOVAL_TYPE: - print_field_caption(SECURE_REMOVAL_TYPE, RWaR); - val = get_field_val(SECURE_REMOVAL_TYPE, 0, 0xF); + case EXT_CSD_BOOT_BUS_CONDITIONS: + val = get_field_val(EXT_CSD_BOOT_BUS_CONDITIONS, 0, 0x3); switch (val) { case 0x0: - str = "erase"; + str = "x1 (sdr) or x4 (ddr)"; break; case 0x1: - str = "overwrite, then erase"; + str = "x4 (sdr/ddr)"; break; case 0x2: - str = "overwrite, complement, then random"; - break; - case 0x3: - str = "vendor defined"; + str = "x8 (sdr/ddr)"; break; } - printf("\t[3-0] Supported Secure Removal Type: %s\n", str); - val = get_field_val(SECURE_REMOVAL_TYPE, 4, 0xF); + printf("\t[1-0] BOOT_BUS_WIDTH: %s bus width in boot operation mode\n", + str); + val = get_field_val(EXT_CSD_BOOT_BUS_CONDITIONS, 2, 0x1); + if (val) + str = "Reset bus width to x1, SDR and backward compatible timings after boot operation"; + else + str = "Retain BOOT_BUS_WIDTH and BOOT_MODE values after boot operation"; + printf("\t[2] RESET_BOOT_BUS_CONDITIONS: %s", str); + val = get_field_val(EXT_CSD_BOOT_BUS_CONDITIONS, 3, 0x3); switch (val) { case 0x0: - str = "erase"; + str = "Use SDR + backward compatible timings in boot operation"; break; case 0x1: - str = "overwrite, then erase"; + str = "Use SDR + HS timings in boot operation mode"; break; case 0x2: - str = "overwrite, complement, then random"; - break; - case 0x3: - str = "vendor defined"; + str = "Use DDR in boot operation"; break; } - printf("\t[7-4] Configure Secure Removal Type: %s\n", str); - return 1; - - case EXT_CSD_PRODUCT_ST8_AWARENSS_ENABLEMENT: - print_field_caption(PRODUCT_ST8_AWARENSS_ENABLEMENT, RWEaR); - val = get_field_val(PRODUCT_ST8_AWARENSS_ENABLEMENT, 0, 0x1); - printf("\t[0] Manual mode is %ssupported\n", - val ? "" : "not "); - val = get_field_val(PRODUCT_ST8_AWARENSS_ENABLEMENT, 1, 0x1); - printf("\t[1] Auto mode is %ssupported\n", (val ? "" : "not ")); - val = get_field_val(PRODUCT_ST8_AWARENSS_ENABLEMENT, 4, 0x1); - printf("\t[4] Production State Awareness is %sabled\n", - val ? "en" : "dis"); - val = get_field_val(PRODUCT_ST8_AWARENSS_ENABLEMENT, 5, 0x1); - printf("\t[5] Auto mode is %sabled\n", (val ? "en" : "dis")); - return 1; - - /* EXT_CSD_MAX_PRE_LOADING_DATA_SIZE */ - case 25: - case 24: - case 23: - case 22: - print_field_caption_with_offset(MAX_PRE_LOADING_DATA_SIZE, - index - EXT_CSD_MAX_PRE_LOADING_DATA_SIZE, R); - tmp64 = get_field_val(MAX_PRE_LOADING_DATA_SIZE, 0, 0xFF); - tmp64 = tmp64 | get_field_val( - MAX_PRE_LOADING_DATA_SIZE + 1, 0, 0xFF) << 8; - tmp64 = tmp64 | get_field_val( - MAX_PRE_LOADING_DATA_SIZE + 2, 0, 0xFF) << 16; - tmp64 = tmp64 | get_field_val( - MAX_PRE_LOADING_DATA_SIZE + 3, 0, 0xFF) << 24; - tmp = get_field_val(DATA_SECTOR_SIZE, 0, 0x1); - if (tmp64 == 0xFFFFFFFF) - if (tmp) - str = strdup("16 TB"); - else - str = strdup("2 TB"); - else - if (tmp) - str = basprintf("%llu B", tmp64 * 4096); - else - str = basprintf("%llu B", tmp64 * 512); - printf("\tMax_Pre_Loading_Data_Size: %s\n", str); - free(str); + printf("\t[3] BOOT_MODE: %s\n", str); return 1; - /* EXT_CSD_PRE_LOADING_DATA_SIZE */ - case 21: - case 20: - case 19: - case 18: - print_field_caption_with_offset(PRE_LOADING_DATA_SIZE, - index - EXT_CSD_PRE_LOADING_DATA_SIZE, RWE_P); - tmp64 = get_field_val(PRE_LOADING_DATA_SIZE, 0, 0xFF); - tmp64 = tmp64 | get_field_val( - PRE_LOADING_DATA_SIZE + 1, 0, 0xFF) << 8; - tmp64 = tmp64 | get_field_val( - PRE_LOADING_DATA_SIZE + 2, 0, 0xFF) << 16; - tmp64 = tmp64 | get_field_val( - PRE_LOADING_DATA_SIZE + 3, 0, 0xFF) << 24; - tmp = get_field_val(DATA_SECTOR_SIZE, 0, 0x1); - if (tmp64 == 0xFFFFFFFF) - if (tmp) - str = strdup("16 TB"); - else - str = strdup("2 TB"); - else - if (tmp) - str = basprintf("%llu B", tmp64 * 4096); - else - str = basprintf("%llu B", tmp64 * 512); - printf("\tPre_Loading_Data_Size: %s\n", str); - free(str); + case EXT_CSD_BOOT_CONFIG_PROT: + val = get_field_val(EXT_CSD_BOOT_CONFIG_PROT, 0, 0x1); + printf("\t[0] PWR_BOOT_CONFIG_PROT: %u\n", val); + val = get_field_val(EXT_CSD_BOOT_CONFIG_PROT, 4, 0x1); + printf("\t[4] PERM_BOOT_CONFIG_PROT: %u\n", val); return 1; - case EXT_CSD_FFU_STATUS: - print_field_caption(FFU_STATUS, R); - val = get_field_val(FFU_STATUS, 0, 0x13); + case EXT_CSD_PARTITION_CONFIG: + val = get_field_val(EXT_CSD_PARTITION_CONFIG, 0, 0x7); switch (val) { case 0x0: - str = "success"; + str = "No access to boot partition"; break; - case 0x10: - str = "general error"; + case 0x1: + str = "R/W boot partition 1"; break; - case 0x11: - str = "firmware install error"; + case 0x2: + str = "R/W boot partition 2"; break; - case 0x12: - str = "firmware download error"; + case 0x3: + str = "R/W Replay Protected Memory Block (RPMB)"; + break; + case 0x4: + str = "Access to General Purpose partition 1"; + break; + case 0x5: + str = "Access to General Purpose partition 2"; + break; + case 0x6: + str = "Access to General Purpose partition 3"; + break; + case 0x7: + str = "Access to General Purpose partition 4"; break; } - printf("\t[5-0] Code: %s\n", str); - return 1; - - case EXT_CSD_MODE_CONFIG: - print_field_caption(MODE_CONFIG, RWE_P); - val = get_field_val(MODE_CONFIG, 0, 0xFF); + printf("\t[2-0] PARTITION_ACCESS: %s\n", str); + val = get_field_val(EXT_CSD_PARTITION_CONFIG, 3, 0x7); switch (val) { case 0x0: - str = "normal"; + str = "Device not boot enabled"; break; case 0x1: - str = "FFU"; + str = "Boot partition 1 enabled for boot"; break; - case 0x10: - str = "vendor"; + case 0x2: + str = "Boot partition 2 enabled for boot"; + break; + case 0x7: + str = "User area enabled for boot"; break; } - printf("\t[7-0] Value: %s\n", str); - return 1; - - case EXT_CSD_BARRIER_CTRL: - print_field_caption(BARRIER_CTRL, RW); - val = get_field_val(BARRIER_CTRL, 0, 0x1); - printf("\t[0] BARRIER_EN: %s\n", val ? "ON" : "OFF"); - return 1; - - case EXT_CSD_OUT_OF_INTERRUPT_TIME: - print_field_caption(OUT_OF_INTERRUPT_TIME, R); - val = get_field_val(OUT_OF_INTERRUPT_TIME, 0, 0xFF); - val = val * 10; - if (val) - printf("\tOut-of-interrupt timeout definition: %u ms\n", - val); - else - printf("\tNot Defined\n"); - return 1; - - case EXT_CSD_PARTITION_SWITCH_TIME: - print_field_caption(PARTITION_SWITCH_TIME, R); - val = get_field_val(PARTITION_SWITCH_TIME, 0, 0xFF); - val = val * 10; - if (val) - printf("\tPartition switch timeout definition: %u ms\n", - val); - else - printf("\tNot Defined\n"); - return 1; - - case EXT_CSD_DRIVER_STRENGTH: - print_field_caption(DRIVER_STRENGTH, R); - val = get_field_val(DRIVER_STRENGTH, 0, 0x1); - printf("\t[0] Type 0: %ssupported\n", val ? "" : "not "); - val = get_field_val(DRIVER_STRENGTH, 1, 0x1); - printf("\t[1] Type 1: %ssupported\n", val ? "" : "not "); - val = get_field_val(DRIVER_STRENGTH, 2, 0x1); - printf("\t[2] Type 2: %ssupported\n", val ? "" : "not "); - val = get_field_val(DRIVER_STRENGTH, 3, 0x1); - printf("\t[3] Type 3: %ssupported\n", val ? "" : "not "); - val = get_field_val(DRIVER_STRENGTH, 4, 0x1); - printf("\t[4] Type 4: %ssupported\n", val ? "" : "not "); - return 1; - - case EXT_CSD_CACHE_FLUSH_POLICY: - print_field_caption(CACHE_FLUSH_POLICY, R); - val = get_field_val(CACHE_FLUSH_POLICY, 0, 0x1); + printf("\t[5-3] BOOT_PARTITION_ENABLE: %s\n", str); + val = get_field_val(EXT_CSD_PARTITION_CONFIG, 6, 0x1); if (val) - str = "FIFO policy for cache"; + str = "Boot acknowledge sent during boot operation Bit"; else - str = "not provided"; - printf("\t[0] Device flushing: %s", str); - return 1; - - case EXT_CSD_OPTIMAL_READ_SIZE: - print_field_caption(OPTIMAL_READ_SIZE, R); - val = get_field_val(OPTIMAL_READ_SIZE, 0, 0xFF); - val = val * 4048; - printf("\t[7-0] Minimum optimal read unit size: %u\n", val); + str = "No boot acknowledge sent"; + printf("\t[6] BOOT_ACK: %s\n", str); return 1; - case EXT_CSD_OPTIMAL_WRITE_SIZE: - print_field_caption(OPTIMAL_WRITE_SIZE, R); - val = get_field_val(OPTIMAL_WRITE_SIZE, 0, 0xFF); - val = val * 4048; - printf("\t[7-0] Minimum optimal write unit size: %u\n", val); + case EXT_CSD_ERASED_MEM_CONT: + val = get_field_val(EXT_CSD_ERASED_MEM_CONT, 0, 0x1); + printf("\t[0] Erased Memory Content: %u\n", val); return 1; - case EXT_CSD_PRE_EOL_INFO: - print_field_caption(PRE_EOL_INFO, R); - val = get_field_val(PRE_EOL_INFO, 0, 0x3); + case EXT_CSD_BUS_WIDTH: + val = get_field_val(EXT_CSD_BUS_WIDTH, 0, 0xF); switch (val) { + case 0: + str = "1 bit data bus"; + break; case 1: - str = "normal"; + str = "4 bit data bus"; break; case 2: - str = "warning"; + str = "8 bit data bus"; break; - case 3: - str = "urgent"; + case 5: + str = "4 bit data bus (dual data rate)"; + break; + case 6: + str = "8 bit data bus (DDR)"; break; - default: - str = "Not defined"; } - printf("\t[1-0] Device life time: %s\n", str); - return 1; - - case EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A: - print_field_caption(DEVICE_LIFE_TIME_EST_TYP_A, R); - val = get_field_val(DEVICE_LIFE_TIME_EST_TYP_A, 0, 0xFF); - val = val * 10; - if (val == 0) - str = strdup("not defined"); - else if (val == 0xB) - str = strdup("maximum"); - else - str = basprintf("%u%% - %u%%", (val - 10), val); - printf("\tDevice life time, type A (estimation): %s\n", str); - free(str); - return 1; - - case EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B: - print_field_caption(DEVICE_LIFE_TIME_EST_TYP_B, R); - val = get_field_val(DEVICE_LIFE_TIME_EST_TYP_B, 0, 0xFF); - val = val * 10; - if (val == 0) - str = strdup("not defined"); - else if (val == 0xB) - str = strdup("maximum"); - else - str = basprintf("%u%% - %u%%", (val - 10), val); - printf("\tDevice life time, type B (estimation): %s\n", str); - free(str); - return 1; - - /* EXT_CSD_NMBR_OF_FW_SCTRS_CRRCTLY_PRGRMD */ - case 305: - case 304: - case 303: - case 302: - print_field_caption_with_offset(NMBR_OF_FW_SCTRS_CRRCTLY_PRGRMD, - index - EXT_CSD_NMBR_OF_FW_SCTRS_CRRCTLY_PRGRMD, R); - return 1; - - case EXT_CSD_CMDQ_DEPTH: - print_field_caption(CMDQ_DEPTH, R); - val = get_field_val(CMDQ_DEPTH, 0, 0xF); - ++val; - printf("\t[3-0] Queue Depth: %u", val); - return 1; - - case EXT_CSD_CMDQ_SUPPORT: - print_field_caption(CMDQ_SUPPORT, R); - val = get_field_val(CMDQ_SUPPORT, 0, 0x1); - printf("\t[0] Command queuing: %ssupported\n", - val ? "" : "not "); + printf("\t[3-0] Bus Mode: %s\n", str); + val = get_field_val(EXT_CSD_BUS_WIDTH, 7, 0x1); + printf("\t[7] Strobe is provided during Data Out, CRC response%s\n", + val ? ", CMD Response" : ""); return 1; - case EXT_CSD_BARRIER_SUPPORT: - print_field_caption(BARRIER_SUPPORT, R); - val = get_field_val(BARRIER_SUPPORT, 0, 0x1); - printf("\t[0] Barrier command: %ssupported\n", + case EXT_CSD_STROBE_SUPPORT: + val = get_field_val(EXT_CSD_STROBE_SUPPORT, 0, 0x1); + printf("\t[0] Enhanced Strobe mode: %ssupported\n", val ? "" : "not "); return 1; - /* EXT_CSD_FFU_ARG */ - case 490: - case 489: - case 488: - case 487: - print_field_caption_with_offset(FFU_ARG, - index - EXT_CSD_FFU_ARG, R); - return 1; - - case EXT_CSD_OPERATION_CODES_TIMEOUT: - print_field_caption(OPERATION_CODES_TIMEOUT, R); - val = get_field_val(OPERATION_CODES_TIMEOUT, 0, 0xFF); - printf("\t[7-0] Timeout Values: %#02x\n", val); + case EXT_CSD_HS_TIMING: + val = get_field_val(EXT_CSD_HS_TIMING, 0, 0xF); + switch (val) { + case 0x0: + str = "Selecting backwards compatibility interface timing"; + break; + case 0x1: + str = "High Speed"; + break; + case 0x2: + str = "HS200"; + break; + case 0x3: + str = "HS400"; + break; + } + printf("\t[3-0] Timing Interface: %s\n", str); return 1; - case EXT_CSD_FFU_FEATURES: - print_field_caption(FFU_FEATURES, R); - val = get_field_val(FFU_FEATURES, 0, 0x1); - printf("\t[0] NUMBER_OF_FW_SECTORS_CORRECTLY_PROGRAMMED: " - "%ssupported\n", val ? "" : " not"); + case EXT_CSD_POWER_CLASS: + val = get_field_val(EXT_CSD_POWER_CLASS, 0, 0xFF); + printf("\t[7-0] Device power class code: %#02x\n", val); return 1; - case EXT_CSD_SUPPORTED_MODES: - print_field_caption(SUPPORTED_MODES, R); - val = get_field_val(SUPPORTED_MODES, 0, 0x1); - printf("\t[0] FFU: %ssupported\n", val ? "" : "not "); - val = get_field_val(SUPPORTED_MODES, 1, 0x1); - printf("\t[1] VSM: %ssupported\n", val ? "" : "not "); + case EXT_CSD_CMD_SET_REV: + val = get_field_val(EXT_CSD_CMD_SET_REV, 0, 0xFF); + printf("\t[7-0] Command set revisions: %#02x\n", val); return 1; - } - return 0; -} -static int print_field_ge_v6(u8 *reg, int index) -{ - int rev; - u32 val; - u32 tmp; - char *str = NULL; - rev = reg[EXT_CSD_REV]; - - switch (index) { - case EXT_CSD_CACHE_CTRL: - print_field_caption(CACHE_CTRL, RWE_P); - val = get_field_val(CACHE_CTRL, 0, 0x1); - printf("\t[0] CACHE_EN: %s\n", val ? "ON" : "OFF"); + case EXT_CSD_CMD_SET: + val = get_field_val(EXT_CSD_CMD_SET, 0, 0xFF); + printf("\t[7-0] Command set that is currently active in the Device: %#02x\n", + val); return 1; - case EXT_CSD_POWER_OFF_NOTIFICATION: - print_field_caption(POWER_OFF_NOTIFICATION, RWE_P); - val = get_field_val(POWER_OFF_NOTIFICATION, 0, 0x7); + case EXT_CSD_REV: + val = get_field_val(EXT_CSD_REV, 0, 0x1F); switch (val) { - case 0x0: - printf("\t[2-0] NO_POWER_NOTIFICATION\n"); + case 0: + str = "1.0 (for MMC v4.0)"; break; - case 0x1: - printf("\t[2-0] POWERED_ON\n"); + case 1: + str = "1.1 (for MMC v4.1)"; break; - case 0x2: - printf("\t[2-0] POWER_OFF_SHORT\n"); + case 2: + str = "1.2 (for MMC v4.2)"; break; - case 0x3: - printf("\t[2-0] POWER_OFF_LONG\n"); + case 3: + str = "1.3 (for MMC v4.3)"; break; - case 0x4: - printf("\t[2-0] SLEEP_NOTIFICATION\n"); + case 4: + str = "1.4 (Obsolete)"; + break; + case 5: + str = "1.5 (for MMC v4.41)"; + break; + case 6: + str = "1.6 (for MMC v4.5, v4.51)"; + break; + case 7: + str = "1.7 (for MMC v5.0, v5.01)"; + break; + case 8: + str = "1.8 (for MMC v5.1)"; break; } + printf("\t[4-0] Extended CSD Revision: Revision %s\n", str); return 1; - case EXT_CSD_PACKED_FAILURE_INDEX: - print_field_caption(PACKED_FAILURE_INDEX, R); - val = get_field_val(PACKED_FAILURE_INDEX, 0, 0xFF); - printf("\t[7-0] PACKED_FAILURE_INDEX: %u\n", val); - return 1; - - case EXT_CSD_PACKED_COMMAND_STATUS: - print_field_caption(PACKED_COMMAND_STATUS, R); - val = get_field_val(PACKED_COMMAND_STATUS, 0, 0x1); - printf("\t[0] Error: %u\n", val); - val = get_field_val(PACKED_COMMAND_STATUS, 1, 0x1); - printf("\t[1] Indexed Error: %u\n", val); - return 1; - - /* EXT_CSD_CONTEXT_CONF */ - case 51: - case 50: - case 49: - case 48: - case 47: - case 46: - case 45: - case 44: - case 43: - case 42: - case 41: - case 40: - case 39: - case 38: - case 37: - print_field_caption_with_offset(CONTEXT_CONF, - index - EXT_CSD_CONTEXT_CONF, RWE_P); - val = get_field_val_with_index(index, 0, 0x3); + case EXT_CSD_CSD_STRUCTURE: + val = get_field_val(EXT_CSD_CSD_STRUCTURE, 0, 0x3); switch (val) { case 0x0: - str = "closed, not active"; + str = "0"; break; case 0x1: - str = "configured and activated as write-only"; + str = "1"; break; case 0x2: - str = "configured and activated as read-only"; - break; - case 0x3: - str = "configured and activated as read/write"; + str = "2"; break; } - printf("\t[1-0] Activation and direction: context is %s\n", + printf("\t[1-0] CSD structure version: CSD version No. 1.%s\n", str); - val = get_field_val_with_index(index, 2, 0x1); - if (val) - str = "follows rules"; - else - str = "doesn't follow rules"; - printf("\t[2] Large Unit context: %s\n", str); - val = get_field_val_with_index(index, 3, 0x3); - printf("\t[5-3] Large Unit multiplier: %u\n", val); - val = get_field_val_with_index(index, 0, 0x3); + return 1; + + case EXT_CSD_DEVICE_TYPE: + val = get_field_val(EXT_CSD_DEVICE_TYPE, 0, 0xFF); switch (val) { - case 0x0: - str = "MODE0"; - break; case 0x1: - str = "MODE1"; + str = "HS eMMC @26MHz - at rated device voltage(s)"; break; case 0x2: - str = "MODE2"; + str = "HS eMMC @52MHz - at rated device voltage(s)"; + break; + case 0x4: + str = "HS Dual Data Rate eMMC @52MHz 1.8V or 3VI/O"; + break; + case 0x8: + str = "HS Dual Data Rate eMMC @52MHz 1.2VI/O"; + break; + case 0x10: + str = "HS200 Single Data Rate eMMC @200MHz 1.8VI/O"; + break; + case 0x20: + str = "HS200 Single Data Rate eMMC @200MHz 1.2VI/O"; break; } - printf("\t[7-6] Reliability mode: %s\n", str); + printf("\t%s\n", str); return 1; - /* EXT_CSD_EXT_PARTITIONS_ATTRIBUTE */ - case 52: - print_field_caption_with_offset( - EXT_PARTITIONS_ATTRIBUTE, - index - EXT_CSD_EXT_PARTITIONS_ATTRIBUTE, RW); - printf("\t[3-0] EXT_1\n"); - printf("\t[7-4] EXT_2\n"); + /* TODO: missing JEDEC documention */ + case EXT_CSD_PWR_CL_52_195: + val = get_field_val(EXT_CSD_PWR_CL_52_195, 0, 0xFF); + printf("\tPower class for 52 MHz at 1.95 V 1 R: %#02x\n", val); return 1; - case 53: - print_field_caption_with_offset( - EXT_PARTITIONS_ATTRIBUTE, - index - EXT_CSD_EXT_PARTITIONS_ATTRIBUTE, RW); - printf("\t[11-8] EXT_3\n"); - printf("\t[15-12] EXT_4\n"); + + case EXT_CSD_PWR_CL_26_195: + val = get_field_val(EXT_CSD_PWR_CL_26_195, 0, 0xFF); + printf("\tPower class for 26 MHz at 1.95 V 1 R: %#02x\n", val); return 1; - /* EXT_CSD_EXCEPTION_EVENTS_STATUS */ - case 54: - print_field_caption_with_offset( - EXCEPTION_EVENTS_STATUS, - index - EXT_CSD_EXCEPTION_EVENTS_STATUS, R); - val = get_field_val(EXCEPTION_EVENTS_STATUS, 0, 0x1); - printf("\t[0] URGENT_BKOPS: %i\n", val); - val = get_field_val(EXCEPTION_EVENTS_STATUS, 1, 0x1); - printf("\t[1] DYNCAP_NEEDED: %i\n", val); - val = get_field_val(EXCEPTION_EVENTS_STATUS, 2, 0x1); - printf("\t[2] SYSPOOL_EXHAUSTED: %i\n", val); - val = get_field_val(EXCEPTION_EVENTS_STATUS, 3, 0x1); - printf("\t[3] PACKED_FAILURE: %i\n", val); - val = get_field_val(EXCEPTION_EVENTS_STATUS, 4, 0x1); - printf("\t[4] EXTENDED_SECURITY_FAILURE: %i\n", val); + case EXT_CSD_PWR_CL_52_360: + val = get_field_val(EXT_CSD_PWR_CL_52_360, 0, 0xFF); + printf("\tPower class for 52 MHz at 3.6 V 1 R: %#02x\n", val); return 1; - case 55: - print_field_caption_with_offset( - EXCEPTION_EVENTS_STATUS, - index - EXT_CSD_EXCEPTION_EVENTS_STATUS, R); + + case EXT_CSD_PWR_CL_26_360: + val = get_field_val(EXT_CSD_PWR_CL_26_360, 0, 0xFF); + printf("\tPower class for 26 MHz at 3.6 V 1 R: %#02x\n", val); return 1; - /* EXT_CSD_EXCEPTION_EVENTS_CTRL */ - case 56: - print_field_caption_with_offset(EXCEPTION_EVENTS_CTRL, - index - EXT_CSD_EXCEPTION_EVENTS_CTRL, RWE_P); - val = get_field_val(EXCEPTION_EVENTS_CTRL, 1, 0x1); - printf("\t[1] DYNCAP_EVENT_EN: %i\n", val); - val = get_field_val(EXCEPTION_EVENTS_CTRL, 2, 0x1); - printf("\t[2] SYSPOOL_EVENT_EN: %i\n", val); - val = get_field_val(EXCEPTION_EVENTS_CTRL, 3, 0x1); - printf("\t[3] PACKED_EVENT_EN: %i\n", val); - val = get_field_val(EXCEPTION_EVENTS_CTRL, 4, 0x1); - printf("\t[4] EXTENDED_SECURITY_EN: %i\n", val); + case EXT_CSD_MIN_PERF_R_4_26: + val = get_field_val(EXT_CSD_MIN_PERF_R_4_26, 0, 0xFF); + printf("\tMinimum Read Performance for 4bit at 26 MHz: %#02x\n", + val); return 1; - case 57: - print_field_caption(EXCEPTION_EVENTS_CTRL, RWE_P); - printf("\tR/W/E_P\n"); - printf("\tValue: %#02x\n", reg[index]); + + case EXT_CSD_MIN_PERF_W_4_26: + val = get_field_val(EXT_CSD_MIN_PERF_W_4_26, 0, 0xFF); + printf("\tMinimum Write Performance for 4bit at 26 MHz: %#02x\n", + val); return 1; - case EXT_CSD_CLASS_6_CTRL: - print_field_caption(CLASS_6_CTRL, RWE_P); - val = get_field_val(CLASS_6_CTRL, 0, 0x1); - if (val) - printf("\t[0] Dynamic Capacity\n"); - else - printf("\t[0] Write Protect\n"); + case EXT_CSD_MIN_PERF_R_8_26_4_52: + val = get_field_val(EXT_CSD_MIN_PERF_R_8_26_4_52, 0, 0xFF); + printf("\tMinimum Read Performance for 8bit at 26 MHz, for 4bit at 52MHz: %#02x\n", + val); return 1; - case EXT_CSD_INI_TIMEOUT_EMU: - print_field_caption(INI_TIMEOUT_EMU, R); - val = get_field_val(INI_TIMEOUT_EMU, 0, 0xFF); - val = val * 100; - printf("\tInitialization Time out value: %u ms\n", val); + case EXT_CSD_MIN_PERF_W_8_26_4_52: + val = get_field_val(EXT_CSD_MIN_PERF_W_8_26_4_52, 0, 0xFF); + printf("\tMinimum Write Performance for 8bit at 26 MHz, for 4bit at 52MHz: %#02x\n", + val); return 1; - case EXT_CSD_DATA_SECTOR_SIZE: - print_field_caption(DATA_SECTOR_SIZE, R); - val = get_field_val(DATA_SECTOR_SIZE, 0, 0x1); + case EXT_CSD_MIN_PERF_R_8_52: + val = get_field_val(EXT_CSD_MIN_PERF_R_8_52, 0, 0xFF); + printf("\tMinimum Read Performance for 8bit at 52 MHz: %#02x\n", + val); + return 1; + + case EXT_CSD_MIN_PERF_W_8_52: + val = get_field_val(EXT_CSD_MIN_PERF_W_8_52, 0, 0xFF); + printf("\tMinimum Write Performance for 8bit at52 MHz: %#02x\n", + val); + return 1; + + case EXT_CSD_SECURE_WP_INFO: + val = get_field_val(EXT_CSD_SECURE_WP_INFO, 0, 0x1); + printf("\t[0] SECURE_WP_SUPPORT: %ssupported\n", + val ? "" : " not"); + val = get_field_val(EXT_CSD_SECURE_WP_INFO, 1, 0x1); + printf("\t[1] SECURE_WP_EN_STATUS: %s Write Protection mode\n", + val ? "Secure" : "Legacy"); + return 1; + + case EXT_CSD_SEC_COUNT: + tmp64 = val * 512; + printf("\tDevice density: %llu B\n", tmp64); + return 1; + + case EXT_CSD_SLEEP_NOTIFICATION_TIME: + val = get_field_val(EXT_CSD_SLEEP_NOTIFICATION_TIME, 0, 0xFF); + val = 100 << val; if (val) - str = "4 KB"; + str = basprintf("Sleep Notification timeout values: %u us", + val); else - str = "512 B"; - printf("\t[0] Data sector size is %s\n", str); + str = strdup("Not defined"); + printf("\t[7-0] %s\n", str); + free(str); return 1; - case EXT_CSD_USE_NATIVE_SECTOR: - print_field_caption(USE_NATIVE_SECTOR, RW); - val = get_field_val(USE_NATIVE_SECTOR, 0, 0x1); + case EXT_CSD_S_A_TIMEOUT: + val = get_field_val(EXT_CSD_S_A_TIMEOUT, 0, 0xFF); + val = 100 << val; if (val) - printf("\t[0] Device sector size is larger than 512 B\n"); + str = basprintf("Sleep/awake timeout values: %u ns", val); else - printf("\t[0] Device sector size is 512 B (emulated or native)\n"); + str = strdup("Not defined"); + printf("\t[7-0] %s\n", str); + free(str); return 1; - case EXT_CSD_NATIVE_SECTOR_SIZE: - print_field_caption(NATIVE_SECTOR_SIZE, R); - val = get_field_val(NATIVE_SECTOR_SIZE, 0, 0x1); + case EXT_CSD_PRODUCTION_ST8_AWARENSS_TIMEOUT: + val = get_field_val(EXT_CSD_PRODUCTION_ST8_AWARENSS_TIMEOUT, 0, 0xFF); + val = 100 << val; if (val) - str = "4 KB"; + str = basprintf( + "Production State Awareness timeout definition: %u us", + val); else - str = "512 B"; - printf("\t[0] Native sector size is %s\n", str); + str = strdup("Not defined"); + printf("\t[7-0] %s\n", str); + free(str); return 1; - case EXT_CSD_PROGRAM_CID_CSD_DDR_SUPPORT: - print_field_caption(PROGRAM_CID_CSD_DDR_SUPPORT, R); - val = get_field_val(PROGRAM_CID_CSD_DDR_SUPPORT, 0, 0x1); + case EXT_CSD_S_C_VCCQ: + val = get_field_val(EXT_CSD_S_C_VCCQ, 0, 0xF); + val = 1 << val; if (val) - str = "single data rate and dual data rate"; + str = basprintf("S_C_VCCQ Sleep Current: %u uA", val); else - str = "single data rate"; - printf("\t[0] PROGRAM_CID_CSD_DDR_SUPPORT: CMD26 and CMD27 %s mode\n", - str); + str = strdup("Not defined"); + printf("\t[3-0] %s\n", str); + free(str); return 1; - case EXT_CSD_PERIODIC_WAKEUP: - print_field_caption(PERIODIC_WAKEUP, RWE); - val = get_field_val(PERIODIC_WAKEUP, 0, 0x1F); - printf("\t[5-0] WAKEUP_PERIOD: %u\n", val); - val = get_field_val(PERIODIC_WAKEUP, 5, 0x7); - switch (val) { - case 0x0: - str = "infinity"; - break; - case 0x1: - str = "months"; - break; - case 0x2: - str = "weeks"; - break; - case 0x3: - str = "days"; - break; - case 0x4: - str = "hours"; - break; - case 0x5: - str = "minutes"; - break; - } - printf("\t[7-5] WAKEUP_UNIT: %s\n", str); + case EXT_CSD_S_C_VCC: + val = get_field_val(EXT_CSD_S_C_VCC, 0, 0xFF); + val = 1 << val; + if (val) + str = basprintf("S_C_VCC Sleep Current: %u uA", val); + else + str = strdup("Not defined"); + printf("\t[3-0] %s\n", str); + free(str); return 1; - case EXT_CSD_PWR_CL_200_195: - print_field_caption(PWR_CL_200_195, R); - val = get_field_val(PWR_CL_200_195, 0, 0xFF); - printf("\tPower class for 200MHz, at 1.95V %#02x\n", val); + case EXT_CSD_HC_WP_GRP_SIZE: + val = get_field_val(EXT_CSD_HC_WP_GRP_SIZE, 0, 0xFF); + if (val) + str = basprintf("Write protect group size: %u", val); + else + str = strdup("No support"); + printf("\t[7-0] %s\n", str); + free(str); return 1; - case EXT_CSD_PWR_CL_200_360: - print_field_caption(PWR_CL_200_360, R); - val = get_field_val(PWR_CL_200_360, 0, 0xFF); - printf("\tPower class for 200MHz, at 3.6V %#02x\n", val); + case EXT_CSD_REL_WR_SEC_C: + val = get_field_val(EXT_CSD_REL_WR_SEC_C, 0, 0xFF); + printf("\t[7-0] Reliable Write Sector Count: %u\n", val); return 1; - case EXT_CSD_POWER_OFF_LONG_TIME: - print_field_caption(POWER_OFF_LONG_TIME, R); - val = get_field_val(POWER_OFF_LONG_TIME, 0, 0xFF); - val = val * 10; - printf("\tGeneric Switch Timeout Definition: %u ms\n", val); + case EXT_CSD_ERASE_TIMEOUT_MULT: + val = get_field_val(EXT_CSD_ERASE_TIMEOUT_MULT, 0, 0xFF); + val = val * 300; + if (val) + str = basprintf("Erase timeout values: %u", val); + else + str = strdup("No support"); + printf("\t[7-0] %s\n", str); + free(str); return 1; - case EXT_CSD_GENERIC_CMD6_TIME: - print_field_caption(GENERIC_CMD6_TIME, R); - val = get_field_val(GENERIC_CMD6_TIME, 0, 0xFF); - val = val * 10; - printf("\tGeneric Switch Timeout Definition: %u ms\n", val); + case EXT_CSD_HC_ERASE_GRP_SIZE: + val = get_field_val(EXT_CSD_HC_ERASE_GRP_SIZE, 0, 0xFF); + val = val * 524288; + if (val) + str = basprintf("Erase-unit size: %u", val); + else + str = strdup("No support"); + printf("\t[7-0] %s\n", str); + free(str); return 1; - /* EXT_CSD_CACHE_SIZE */ - case 252: - case 251: - case 250: - case 249: - print_field_caption_with_offset(CACHE_SIZE, - index - EXT_CSD_CACHE_SIZE, R); - val = get_field_val(CACHE_SIZE, 0, 0xFF); - val = val | get_field_val(CACHE_SIZE + 1, 0, 0xFF) << 8; - val = val | get_field_val(CACHE_SIZE + 2, 0, 0xFF) << 16; - val = val | get_field_val(CACHE_SIZE + 3, 0, 0xFF) << 24; - printf("\tCache Size: %u KiB\n", val); + case EXT_CSD_ACC_SIZE: + val = get_field_val(EXT_CSD_ACC_SIZE, 0, 0xF); + val = val * 512; + if (val) + str = basprintf("Superpage size: %u", val); + else + str = strdup("Not defined"); + printf("\t[3-0] %s\n", str); + free(str); return 1; - case EXT_CSD_EXT_SUPPORT: - print_field_caption(EXT_SUPPORT, R); - val = get_field_val(EXT_SUPPORT, 0, 0x1); - printf("\t[0] System code: %ssupported\n", val ? "" : "not "); - val = get_field_val(EXT_SUPPORT, 1, 0x1); - printf("\t[1] Non-persistent: %ssupported\n", - val ? "" : "not "); + case EXT_CSD_BOOT_SIZE_MULT: + val = get_field_val(EXT_CSD_BOOT_SIZE_MULT, 0, 0xFF); + val = val * 131072; + printf("\tBoot partition size: %u\n", val); return 1; - case EXT_CSD_LARGE_UNIT_SIZE_M1: - print_field_caption(LARGE_UNIT_SIZE_M1, R); - val = get_field_val(LARGE_UNIT_SIZE_M1, 0, 0xFF); - printf("\tLarge Unit size: %#02x\n", val); + case EXT_CSD_BOOT_INFO: + val = get_field_val(EXT_CSD_BOOT_INFO, 0, 0x1); + printf("\t[0] ALT_BOOT_MODE: %ssupported\n", val ? "" : "not "); + val = get_field_val(EXT_CSD_BOOT_INFO, 1, 0x1); + printf("\t[1] DDR_BOOT_MODE: %ssupported\n", val ? "" : "not "); + val = get_field_val(EXT_CSD_BOOT_INFO, 2, 0x1); + printf("\t[2] HS_BOOT_MODE: %ssupported\n", val ? "" : "not "); return 1; - case EXT_CSD_CONTEXT_CAPABILITIES: - print_field_caption(CONTEXT_CAPABILITIES, R); - val = get_field_val(CONTEXT_CAPABILITIES, 0, 0xF); - printf("\t[3-0] MAX_CONTEXT_ID: %#02x\n", val); - val = get_field_val(CONTEXT_CAPABILITIES, 4, 0x7); - printf("\t[6-4] LARGE_UNIT_MAX_MULTIPLIER_M1: %#02x\n", val); + case EXT_CSD_BKOPS_SUPPORT: + val = get_field_val(EXT_CSD_BKOPS_SUPPORT, 0, 0x1); + printf("\t[0] SUPPORTED: %u\n", val); return 1; - case EXT_CSD_TAG_RES_SIZE: - print_field_caption(TAG_RES_SIZE, R); - val = get_field_val(TAG_RES_SIZE, 0, 0xFF); - printf("\tSystem Data Tag Resources Size: %#02x\n", val); + case EXT_CSD_HPI_FEATURES: + val = get_field_val(EXT_CSD_HPI_FEATURES, 0, 0x1); + printf("\t[0] HPI_SUPPORTED: %u\n", val); + val = get_field_val(EXT_CSD_HPI_FEATURES, 1, 0x1); + printf("\t[1] HPI_FEATURES: implementation based on CMD1%s\n", + val ? "2" : "3"); return 1; - case EXT_CSD_TAG_UNIT_SIZE: - print_field_caption(TAG_UNIT_SIZE, R); - tmp = get_field_val(NATIVE_SECTOR_SIZE, 0, 0x1); - tmp = (tmp == 0) ? 512 : 4048; - val = 2 << (1 - get_field_val(TAG_UNIT_SIZE, 0, 0xFF)); - val = val * tmp; - printf("\tTag Unit Size: %u\n", val); + case EXT_CSD_S_CMD_SET: + val = get_field_val(EXT_CSD_S_CMD_SET, 0, 0xFF); + printf("\t[7-0] Command Set: %#02x\n", val); return 1; - case EXT_CSD_DATA_TAG_SUPPORT: - print_field_caption(DATA_TAG_SUPPORT, R); - val = get_field_val(DATA_TAG_SUPPORT, 0, 0x1); - printf("\t[0] SYSTEM_DATA_TAG_SUPPORT: %u\n", val); + case EXT_CSD_EXT_SECURITY_ERR: + val = get_field_val(EXT_CSD_EXT_SECURITY_ERR, 0, 0x1); + printf("\t[0] SEC_INVALID_COMMAND_PARAMETERS: %u\n", val); + val = get_field_val(EXT_CSD_EXT_SECURITY_ERR, 1, 0x1); + printf("\t[1] ACCESS_DENIED: %u\n", val); return 1; - case EXT_CSD_MAX_PACKED_WRITES: - print_field_caption(MAX_PACKED_WRITES, R); - val = get_field_val(MAX_PACKED_WRITES, 0, 0xFF); - printf("\tmaximum number of commands in write command: %u\n", - val); + case EXT_CSD_SEC_TRIM_MULT: + val = get_field_val(EXT_CSD_SEC_TRIM_MULT, 0, 0xFF); + val = val * 300 * get_field_val(EXT_CSD_ERASE_TIMEOUT_MULT, 0, + 0xFF); + printf("\tSecure Trim time-out value: %u\n", val); return 1; - case EXT_CSD_MAX_PACKED_READS: - print_field_caption(MAX_PACKED_READS, R); - val = get_field_val(MAX_PACKED_READS, 0, 0xFF); - printf("\tmaximum number of commands in read command: %u\n", - val); + case EXT_CSD_SEC_ERASE_MULT: + val = get_field_val(EXT_CSD_SEC_ERASE_MULT, 0, 0xFF); + val = val * 300 * get_field_val(EXT_CSD_ERASE_TIMEOUT_MULT, 0, + 0xFF); + printf("\tSecure Erase time-out value: %u\n", val); return 1; - } - return 0; -} -static int print_field_ge_v5(u8 *reg, int index) -{ - int rev; - u32 val; - u32 tmp; - u64 tmp64; - char *str = NULL; - rev = reg[EXT_CSD_REV]; - - switch (index) { case EXT_CSD_TCASE_SUPPORT: - print_field_caption(TCASE_SUPPORT, WE_P); - val = get_field_val(TCASE_SUPPORT, 0, 0xFF); + val = get_field_val(EXT_CSD_TCASE_SUPPORT, 0, 0xFF); printf("\t[7-0] TCASE_SUPPORT: %#02x\n", val); return 1; case EXT_CSD_PRODUCTION_STATE_AWARENESS: - print_field_caption(PRODUCTION_STATE_AWARENESS, RWE); - val = get_field_val(PRODUCTION_STATE_AWARENESS, 0, 0xFF); + val = get_field_val(EXT_CSD_PRODUCTION_STATE_AWARENESS, 0, 0xFF); switch (val) { case 0x0: str = "NORMAL"; @@ -795,138 +1342,87 @@ static int print_field_ge_v5(u8 *reg, int index) return 1; case EXT_CSD_SEC_BAD_BLK_MGMNT: - print_field_caption(SEC_BAD_BLK_MGMNT, RW); - val = get_field_val(SEC_BAD_BLK_MGMNT, 0, 0x1); + val = get_field_val(EXT_CSD_SEC_BAD_BLK_MGMNT, 0, 0x1); printf("\t[0] SEC_BAD_BLK: %sabled\n", val ? "en" : "dis"); return 1; - /* EXT_CSD_ENH_START_ADDR */ - case 139: - case 138: - case 137: - case 136: - print_field_caption_with_offset(ENH_START_ADDR, - index - EXT_CSD_ENH_START_ADDR, RW); - val = get_field_val(ENH_START_ADDR, 0, 0xFF); - val = val | get_field_val(ENH_START_ADDR + 1, 0, 0xFF) << 8; - val = val | get_field_val(ENH_START_ADDR + 2, 0, 0xFF) << 16; - val = val | get_field_val(ENH_START_ADDR + 3, 0, 0xFF) << 24; + case EXT_CSD_ENH_START_ADDR: printf("\tEnhanced User Data Start Address: 0x%x\n", val); return 1; - /* EXT_CSD_ENH_SIZE_MULT */ - case 142: - case 141: - case 140: - print_field_caption_with_offset(ENH_SIZE_MULT, - index - EXT_CSD_ENH_SIZE_MULT, RW); - val = get_field_val(ENH_SIZE_MULT, 0, 0xFF); - val = val | get_field_val(ENH_SIZE_MULT + 1, 0, 0xFF) << 8; - val = val | get_field_val(ENH_SIZE_MULT + 2, 0, 0xFF) << 16; - tmp = get_field_val(HC_WP_GRP_SIZE, 0, 0xFF); - tmp = tmp + get_field_val(HC_ERASE_GRP_SIZE, 0, 0xFF); + case EXT_CSD_ENH_SIZE_MULT: + tmp = get_field_val(EXT_CSD_HC_WP_GRP_SIZE, 0, 0xFF); + tmp = tmp + get_field_val(EXT_CSD_HC_ERASE_GRP_SIZE, 0, 0xFF); tmp64 = val * tmp * 524288; printf("\tEnhanced User Data Area %i Size: %llu B\n", index - EXT_CSD_ENH_SIZE_MULT, tmp64); return 1; - /* EXT_CSD_GP_SIZE_MULT_GPX */ - case 154: - case 153: - case 152: - tmp = index - EXT_CSD_GP_SIZE_MULT; - print_field_caption_with_offset(GP_SIZE_MULT, tmp, RW); - val = get_field_val_with_index(tmp, 0, 0xFF); - val = val | get_field_val_with_index(tmp + 1, 0, 0xFF) << 8; - val = val | get_field_val_with_index(tmp + 2, 0, 0xFF) << 16; - tmp = get_field_val(HC_WP_GRP_SIZE, 0, 0xFF); - tmp = tmp + get_field_val(HC_ERASE_GRP_SIZE, 0, 0xFF); + case EXT_CSD_GP_SIZE_MULT3: + tmp = get_field_val(EXT_CSD_HC_WP_GRP_SIZE, 0, 0xFF); + tmp = tmp + get_field_val(EXT_CSD_HC_ERASE_GRP_SIZE, 0, 0xFF); tmp64 = val * tmp * 524288; - printf("\tGeneral_Purpose_Partition_%i Size: %llu B\n", - index - EXT_CSD_GP_SIZE_MULT, tmp64); + printf("\tGeneral_Purpose_Partition_3 Size: %llu B\n", tmp64); return 1; - case 151: - case 150: - case 149: - tmp = index - EXT_CSD_GP_SIZE_MULT; - print_field_caption_with_offset(GP_SIZE_MULT, tmp, RW); - val = get_field_val_with_index(tmp, 0, 0xFF); - val = val | get_field_val_with_index(tmp + 1, 0, 0xFF) << 8; - val = val | get_field_val_with_index(tmp + 2, 0, 0xFF) << 16; - tmp = get_field_val(HC_WP_GRP_SIZE, 0, 0xFF); - tmp = tmp + get_field_val(HC_ERASE_GRP_SIZE, 0, 0xFF); + + case EXT_CSD_GP_SIZE_MULT2: + tmp = get_field_val(EXT_CSD_HC_WP_GRP_SIZE, 0, 0xFF); + tmp = tmp + get_field_val(EXT_CSD_HC_ERASE_GRP_SIZE, 0, 0xFF); tmp64 = val * tmp * 524288; - printf("\tGeneral_Purpose_Partition_%i Size: %llu B\n", - index - EXT_CSD_GP_SIZE_MULT, tmp64); + printf("\tGeneral_Purpose_Partition_2 Size: %llu B\n", tmp64); return 1; - case 148: - case 147: - case 146: - tmp = index - EXT_CSD_GP_SIZE_MULT; - print_field_caption_with_offset(GP_SIZE_MULT, tmp, RW); - val = get_field_val_with_index(tmp, 0, 0xFF); - val = val | get_field_val_with_index(tmp + 1, 0, 0xFF) << 8; - val = val | get_field_val_with_index(tmp + 2, 0, 0xFF) << 16; - tmp = get_field_val(HC_WP_GRP_SIZE, 0, 0xFF); - tmp = tmp + get_field_val(HC_ERASE_GRP_SIZE, 0, 0xFF); + + case EXT_CSD_GP_SIZE_MULT1: + tmp = get_field_val(EXT_CSD_HC_WP_GRP_SIZE, 0, 0xFF); + tmp = tmp + get_field_val(EXT_CSD_HC_ERASE_GRP_SIZE, 0, 0xFF); tmp64 = val * tmp * 524288; - printf("\tGeneral_Purpose_Partition_%i Size: %llu B\n", - index - EXT_CSD_GP_SIZE_MULT, tmp64); + printf("\tGeneral_Purpose_Partition_1 Size: %llu B\n", tmp64); return 1; - case 145: - case 144: - case 143: - tmp = index - EXT_CSD_GP_SIZE_MULT; - print_field_caption_with_offset(GP_SIZE_MULT, tmp, RW); - val = get_field_val_with_index(tmp, 0, 0xFF); - val = val | get_field_val_with_index(tmp + 1, 0, 0xFF) << 8; - val = val | get_field_val_with_index(tmp + 2, 0, 0xFF) << 16; - tmp = get_field_val(HC_WP_GRP_SIZE, 0, 0xFF); - tmp = tmp + get_field_val(HC_ERASE_GRP_SIZE, 0, 0xFF); + + case EXT_CSD_GP_SIZE_MULT0: + tmp = get_field_val(EXT_CSD_HC_WP_GRP_SIZE, 0, 0xFF); + tmp = tmp + get_field_val(EXT_CSD_HC_ERASE_GRP_SIZE, 0, 0xFF); tmp64 = val * tmp * 524288; - printf("\tGeneral_Purpose_Partition_%i Size: %llu B\n", - index - EXT_CSD_GP_SIZE_MULT, tmp64); + printf("\tGeneral_Purpose_Partition_0 Size: %llu B\n", tmp64); return 1; case EXT_CSD_PARTITION_SETTING_COMPLETED: - print_field_caption(PARTITION_SETTING_COMPLETED, RW); - val = get_field_val(PARTITION_SETTING_COMPLETED, 0, 0x1); + val = get_field_val(EXT_CSD_PARTITION_SETTING_COMPLETED, 0, 0x1); printf("\t[0] PARTITION_SETTING_COMPLETED: %u\n", val); return 1; case EXT_CSD_PARTITIONS_ATTRIBUTE: - print_field_caption(PARTITIONS_ATTRIBUTE, RW); - val = get_field_val(PARTITIONS_ATTRIBUTE, 0, 0x1); + val = get_field_val(EXT_CSD_PARTITIONS_ATTRIBUTE, 0, 0x1); if (val) str = "enhanced attribute in user data area"; else str = "default"; printf("\t[0] ENH_USR: %s\n", str); - val = get_field_val(PARTITIONS_ATTRIBUTE, 1, 0x1); + val = get_field_val(EXT_CSD_PARTITIONS_ATTRIBUTE, 1, 0x1); if (val) str = "enhanced attribute in general purpose part 1"; else str = "default"; printf("\t[1] ENH_1: %s\n", str); - val = get_field_val(PARTITIONS_ATTRIBUTE, 2, 0x1); + val = get_field_val(EXT_CSD_PARTITIONS_ATTRIBUTE, 2, 0x1); if (val) str = "enhanced attribute in general purpose part 2"; else str = "default"; printf("\t[2] ENH_2: %s\n", str); - val = get_field_val(PARTITIONS_ATTRIBUTE, 3, 0x1); + val = get_field_val(EXT_CSD_PARTITIONS_ATTRIBUTE, 3, 0x1); if (val) str = "enhanced attribute in general purpose part 3"; else str = "default"; printf("\t[3] ENH_3: %s\n", str); - val = get_field_val(PARTITIONS_ATTRIBUTE, 4, 0x1); + val = get_field_val(EXT_CSD_PARTITIONS_ATTRIBUTE, 4, 0x1); if (val) str = "enhanced attribute in general purpose part 4"; else str = "default"; printf("\t[4] ENH_4: %s\n", str); - val = get_field_val(PARTITIONS_ATTRIBUTE, 5, 0x1); + val = get_field_val(EXT_CSD_PARTITIONS_ATTRIBUTE, 5, 0x1); if (val) str = "enhanced attribute in general purpose part 5"; else @@ -934,43 +1430,32 @@ static int print_field_ge_v5(u8 *reg, int index) printf("\t[5] ENH_5: %s\n", str); return 1; - /* EXT_CSD_MAX_ENH_SIZE_MULT */ - case 159: - case 158: - case 157: - print_field_caption_with_offset(MAX_ENH_SIZE_MULT, - index - EXT_CSD_MAX_ENH_SIZE_MULT, R); - val = get_field_val(MAX_ENH_SIZE_MULT, 0, 0xFF); - val = val | get_field_val(MAX_ENH_SIZE_MULT + 1, 0, 0xFF) << 8; - val = val | get_field_val(MAX_ENH_SIZE_MULT + 2, 0, 0xFF) << 16; - tmp = get_field_val(HC_WP_GRP_SIZE, 0, 0xFF); - tmp = tmp + get_field_val(HC_ERASE_GRP_SIZE, 0, 0xFF); + case EXT_CSD_MAX_ENH_SIZE_MULT: + tmp = get_field_val(EXT_CSD_HC_WP_GRP_SIZE, 0, 0xFF); + tmp = tmp + get_field_val(EXT_CSD_HC_ERASE_GRP_SIZE, 0, 0xFF); tmp64 = val * tmp * 524288; printf("\tMax Enhanced Area: %llu B\n", tmp64); return 1; case EXT_CSD_PARTITIONING_SUPPORT: - print_field_caption(PARTITIONING_SUPPORT, R); - val = get_field_val(PARTITIONING_SUPPORT, 0, 0x1); + val = get_field_val(EXT_CSD_PARTITIONING_SUPPORT, 0, 0x1); printf("\t[0] PARTITIONING_EN: %ssupported\n", val ? "" : "not "); - val = get_field_val(PARTITIONING_SUPPORT, 1, 0x1); + val = get_field_val(EXT_CSD_PARTITIONING_SUPPORT, 1, 0x1); printf("\t[1] ENH_ATTRIBUTE_EN: %ssupported\n", val ? "" : "not "); - val = get_field_val(PARTITIONING_SUPPORT, 2, 0x1); + val = get_field_val(EXT_CSD_PARTITIONING_SUPPORT, 2, 0x1); printf("\t[2] EXT_ATTRIBUTE_EN: %ssupported\n", val ? "" : "not "); return 1; case EXT_CSD_HPI_MGMT: - print_field_caption(HPI_MGMT, R); - val = get_field_val(HPI_MGMT, 0, 0xFF); + val = get_field_val(EXT_CSD_HPI_MGMT, 0, 0xFF); printf("\t[7-0] HPI_EN: %sactivated\n", val ? "" : "not "); return 1; case EXT_CSD_RST_N_FUNCTION: - print_field_caption(RST_N_FUNCTION, R); - val = get_field_val(RST_N_FUNCTION, 0, 0x3); + val = get_field_val(EXT_CSD_RST_N_FUNCTION, 0, 0x3); switch (val) { case 0x0: str = "temporarily disabled"; @@ -986,14 +1471,13 @@ static int print_field_ge_v5(u8 *reg, int index) return 1; case EXT_CSD_BKOPS_EN: - print_field_caption(BKOPS_EN, RWaRWE); - val = get_field_val(BKOPS_EN, 0, 0x1); + val = get_field_val(EXT_CSD_BKOPS_EN, 0, 0x1); if (val) str = "Host is indicated"; else str = "not supported by Host"; printf("\t[0] MANUAL_EN: %s\n", str); - val = get_field_val(BKOPS_EN, 1, 0x1); + val = get_field_val(EXT_CSD_BKOPS_EN, 1, 0x1); if (val) str = "may"; else @@ -1003,62 +1487,58 @@ static int print_field_ge_v5(u8 *reg, int index) return 1; case EXT_CSD_BKOPS_START: - print_field_caption(BKOPS_START, WE_P); printf("\t[7-0] Writing shall start a background operations.\n"); return 1; case EXT_CSD_SANITIZE_START: - print_field_caption(SANITIZE_START, WE_P); printf("\t[7-0] Writing shall start a sanitize operation.\n"); return 1; case EXT_CSD_WR_REL_PARAM: - print_field_caption(WR_REL_PARAM, R); - val = get_field_val(WR_REL_PARAM, 0, 0x1); + val = get_field_val(EXT_CSD_WR_REL_PARAM, 0, 0x1); if (val) str = "all the WR_DATA_REL parameters in the WR_REL_SET registers are R/W"; else str = "obsolete"; printf("\t[0] HS_CTRL_REL: %s\n", str); - val = get_field_val(WR_REL_PARAM, 2, 0x1); + val = get_field_val(EXT_CSD_WR_REL_PARAM, 2, 0x1); if (val) str = "the device supports the enhanced definition of reliable write"; else str = "obsolete"; printf("\t[2] EN_REL_WR: %s\n", str); - val = get_field_val(WR_REL_PARAM, 4, 0x1); + val = get_field_val(EXT_CSD_WR_REL_PARAM, 4, 0x1); printf("\t[4] EN_RPMB_REL_WR: RPMB transfer size is either\n" "\t 256B (1 512B frame), 512B (2 512B frame)%s\n", val ? ", 8KB (32 512B frames)" : ""); return 1; case EXT_CSD_WR_REL_SET: - print_field_caption(WR_REL_SET, RW); - val = get_field_val(WR_REL_SET, 0, 0x1); + val = get_field_val(EXT_CSD_WR_REL_SET, 0, 0x1); if (val) str = "the device protects previously written data if power failure occurs"; else str = "optimized for performance,data could be at risk if on power failure"; printf("\t[0] WR_DATA_REL_USR: %s\n", str); - val = get_field_val(WR_REL_SET, 1, 0x1); + val = get_field_val(EXT_CSD_WR_REL_SET, 1, 0x1); if (val) str = "the device protects previously written data if power failure occurs"; else str = "optimized for performance,data could be at risk if on power failure"; printf("\t[1] WR_DATA_REL_1: %s\n", str); - val = get_field_val(WR_REL_SET, 2, 0x1); + val = get_field_val(EXT_CSD_WR_REL_SET, 2, 0x1); if (val) str = "the device protects previously written data if power failure occurs"; else str = "optimized for performance,data could be at risk if on power failure"; printf("\t[2] WR_DATA_REL_2: %s\n", str); - val = get_field_val(WR_REL_SET, 3, 0x1); + val = get_field_val(EXT_CSD_WR_REL_SET, 3, 0x1); if (val) str = "the device protects previously written data if power failure occurs"; else str = "optimized for performance,data could be at risk if on power failure"; printf("\t[3] WR_DATA_REL_3: %s\n", str); - val = get_field_val(WR_REL_SET, 4, 0x1); + val = get_field_val(EXT_CSD_WR_REL_SET, 4, 0x1); if (val) str = "the device protects previously written data if power failure occurs"; else @@ -1067,89 +1547,85 @@ static int print_field_ge_v5(u8 *reg, int index) return 1; case EXT_CSD_RPMB_SIZE_MULT: - print_field_caption(RPMB_SIZE_MULT, R); - val = get_field_val(RPMB_SIZE_MULT, 0, 0xFF); + val = get_field_val(EXT_CSD_RPMB_SIZE_MULT, 0, 0xFF); val = val * 131072; printf("\t[7-0] RPMB Partition Size: %u KB\n", val); return 1; case EXT_CSD_FW_CONFIG: - print_field_caption(FW_CONFIG, RW); - val = get_field_val(FW_CONFIG, 0, 0x1); + val = get_field_val(EXT_CSD_FW_CONFIG, 0, 0x1); printf("\t[0] Update_Disable: FW update %sabled\n", val ? "dis" : "en"); return 1; case EXT_CSD_USER_WP: - print_field_caption(USER_WP, RWaRWC_PaRWE_P); - val = get_field_val(USER_WP, 0, 0x1); + val = get_field_val(EXT_CSD_USER_WP, 0, 0x1); if (val) str = "apply Power-On Period protection to the protection group indicated by CMD28"; else str = "power-on write protection is not applied when CMD28 is issued"; printf("\t[0] US_PWR_WP_EN: %s\n", str); - val = get_field_val(USER_WP, 2, 0x1); + val = get_field_val(EXT_CSD_USER_WP, 2, 0x1); if (val) str = "apply permanent write protection to the protection group indicated by CMD28"; else str = "permanent write protection is not applied when CMD28 is issued"; printf("\t[2] US_PERM_WP_EN: %s\n", str); - val = get_field_val(USER_WP, 3, 0x1); + val = get_field_val(EXT_CSD_USER_WP, 3, 0x1); if (val) str = "disable the use of power-on period write protection"; else str = "power-on write protection can be applied to write protection groups"; printf("\t[3] US_PWR_WP_DIS: %s\n", str); - val = get_field_val(USER_WP, 4, 0x1); + val = get_field_val(EXT_CSD_USER_WP, 4, 0x1); if (val) str = "permanently disable the use of permanent write protection"; else str = "permanent write protection can be applied to write protection groups"; printf("\t[4] US_PERM_WP_DIS: %s\n", str); - val = get_field_val(USER_WP, 6, 0x1); + val = get_field_val(EXT_CSD_USER_WP, 6, 0x1); if (val) str = "disable the use of PERM_WRITE_PROTECT (CSD[13])"; else str = "host is permitted to set PERM_WRITE_PROTECT (CSD[13])"; printf("\t[6] CD_PERM_WP_DIS: %s\n", str); - val = get_field_val(USER_WP, 7, 0x1); + val = get_field_val(EXT_CSD_USER_WP, 7, 0x1); printf("\t[7] PERM_PSWD_DS: Password protection features " "are %sabled\n", val ? "dis" : "en"); return 1; case EXT_CSD_BOOT_WP: - print_field_caption(BOOT_WP, RWaRWC_P); - val = get_field_val(BOOT_WP, 0, 0x1); + val = get_field_val(EXT_CSD_BOOT_WP, 0, 0x1); if (val) str = "enable Power-On Period write protection to the boot area"; else str = "boot region is not power-on write protected"; printf("\t[0] B_PWR_WP_EN: %s\n", str); - val = get_field_val(BOOT_WP, 1, 0x1); + val = get_field_val(EXT_CSD_BOOT_WP, 1, 0x1); printf("\t[1] B_PWR_WP_SEC_SEL: B_PWR_WP_EN(Bit 0) applies\n" "\t to boot Area%s only, if B_SEC_WP_SEL (bit 7 is set)\n", val ? "2" : "1"); - val = get_field_val(BOOT_WP, 2, 0x1); + val = get_field_val(EXT_CSD_BOOT_WP, 2, 0x1); printf("\t[2] B_PERM_WP_EN: Boot region is %spermanently\n" "\t write protected\n", val ? "" : "not "); - val = get_field_val(BOOT_WP, 3, 0x1); + val = get_field_val(EXT_CSD_BOOT_WP, 3, 0x1); printf("\t[3] B_PERM_WP_SEC_SEL: B_PERM_WP_EN(Bit 2) applies\n" "\t to boot Area%s only, if B_SEC_WP_SEL (bit 7 is set)\n", val ? "2" : "1"); - val = get_field_val(BOOT_WP, 4, 0x1); + val = get_field_val(EXT_CSD_BOOT_WP, 4, 0x1); if (val) str = "permanently disable the use of"; else str = "master is permitted to use"; printf("\t[4] B_PERM_WP_DIS: %s B_PERM_WP_EN(bit 2)\n", str); - val = get_field_val(BOOT_WP, 6, 0x1); + val = get_field_val(EXT_CSD_BOOT_WP, 6, 0x1); if (val) str = "disable the use of"; else str = "master is permitted to set"; printf("\t[5] B_PWR_WP_DIS: %s B_PWR_WP_EN(bit 0)\n", str); - val = get_field_val(BOOT_WP, 7, 0x1); + val = get_field_val(EXT_CSD_BOOT_WP, 7, 0x1); if (val) str = "boot partition selected by B_PERM_WP_SEC_SEL (bit 3) and B_PWR_WP_SEC_SEL (bit 1)"; else @@ -1159,8 +1635,7 @@ static int print_field_ge_v5(u8 *reg, int index) return 1; case EXT_CSD_BOOT_WP_STATUS: - print_field_caption(BOOT_WP_STATUS, R); - val = get_field_val(BOOT_WP_STATUS, 0, 0x3); + val = get_field_val(EXT_CSD_BOOT_WP_STATUS, 0, 0x3); switch (val) { case 0x0: str = "not protected"; @@ -1173,7 +1648,7 @@ static int print_field_ge_v5(u8 *reg, int index) break; } printf("\t[1-0] B_AREA_1_WP: Boot Area 1 is %s\n", str); - val = get_field_val(BOOT_WP_STATUS, 2, 0x3); + val = get_field_val(EXT_CSD_BOOT_WP_STATUS, 2, 0x3); switch (val) { case 0x0: str = "not protected"; @@ -1189,78 +1664,57 @@ static int print_field_ge_v5(u8 *reg, int index) return 1; case EXT_CSD_SEC_FEATURE_SUPPORT: - print_field_caption(SEC_FEATURE_SUPPORT, R); - val = get_field_val(SEC_FEATURE_SUPPORT, 0, 0x1); + val = get_field_val(EXT_CSD_SEC_FEATURE_SUPPORT, 0, 0x1); printf("\t[0] SECURE_ER_EN: %ssupported\n", val ? "" : "not "); - val = get_field_val(SEC_FEATURE_SUPPORT, 2, 0x1); + val = get_field_val(EXT_CSD_SEC_FEATURE_SUPPORT, 2, 0x1); printf("\t[1] SEC_BD_BLK_EN: %ssupported\n", val ? "" : "not "); - val = get_field_val(SEC_FEATURE_SUPPORT, 4, 0x1); + val = get_field_val(EXT_CSD_SEC_FEATURE_SUPPORT, 4, 0x1); printf("\t[4] SEC_GB_CL_EN: %ssupported\n", val ? "" : "not "); - val = get_field_val(SEC_FEATURE_SUPPORT, 6, 0x1); + val = get_field_val(EXT_CSD_SEC_FEATURE_SUPPORT, 6, 0x1); printf("\t[6] SEC_SANITIZE: %ssupported\n", val ? "" : "not "); return 1; case EXT_CSD_TRIM_MULT: - print_field_caption(TRIM_MULT, R); - val = get_field_val(TRIM_MULT, 0, 0xFF); + val = get_field_val(EXT_CSD_TRIM_MULT, 0, 0xFF); val = val * 300; printf("\t[7-0] TRIM/DISCARD Time out value: %u\n", val); return 1; case EXT_CSD_MIN_PERF_DDR_R_8_52: - print_field_caption(MIN_PERF_DDR_R_8_52, R); - val = get_field_val(MIN_PERF_DDR_R_8_52, 0, 0xFF); + val = get_field_val(EXT_CSD_MIN_PERF_DDR_R_8_52, 0, 0xFF); printf("\t[7-0] Minimum Read Performance for 8bit at 52MHz in " "DDR mode %#02x\n", val); return 1; case EXT_CSD_MIN_PERF_DDR_W_8_52: - print_field_caption(MIN_PERF_DDR_W_8_52, R); - val = get_field_val(MIN_PERF_DDR_W_8_52, 0, 0xFF); + val = get_field_val(EXT_CSD_MIN_PERF_DDR_W_8_52, 0, 0xFF); printf("\tMinimum Write Performance for 8bit at 52MHz in DDR " "mode %#02x\n", val); return 1; case EXT_CSD_PWR_CL_DDR_52_195: - print_field_caption(PWR_CL_DDR_52_195, R); - val = get_field_val(PWR_CL_DDR_52_195, 0, 0xFF); + val = get_field_val(EXT_CSD_PWR_CL_DDR_52_195, 0, 0xFF); printf("\tPower class for 52MHz, DDR at 1.95V %#02x\n", val); return 1; case EXT_CSD_PWR_CL_DDR_52_360: - print_field_caption(PWR_CL_DDR_52_360, R); - val = get_field_val(PWR_CL_DDR_52_360, 0, 0xFF); + val = get_field_val(EXT_CSD_PWR_CL_DDR_52_360, 0, 0xFF); printf("\tPower class for 52MHz, DDR at 3.6V %#02x\n", val); return 1; case EXT_CSD_INI_TIMEOUT_AP: - print_field_caption(INI_TIMEOUT_AP, R); - val = get_field_val(INI_TIMEOUT_AP, 0, 0xFF); + val = get_field_val(EXT_CSD_INI_TIMEOUT_AP, 0, 0xFF); val = val * 100; printf("\tInitialization Time out value: %u ms\n", val); return 1; - /* EXT_CSD_CORRECTLY_PRG_SECTORS_NUM */ - case 245: - case 244: - case 243: - case 242: - print_field_caption_with_offset(CORRECTLY_PRG_SECTORS_NUM, - index - EXT_CSD_CORRECTLY_PRG_SECTORS_NUM, R); - val = get_field_val(CORRECTLY_PRG_SECTORS_NUM, 0, 0xFF); - val = val | get_field_val(CORRECTLY_PRG_SECTORS_NUM + 1, 0, - 0xFF) << 8; - val = val | get_field_val(CORRECTLY_PRG_SECTORS_NUM + 2, 0, - 0xFF) << 16; - val = val | get_field_val(CORRECTLY_PRG_SECTORS_NUM + 3, 0, - 0xFF) << 24; + case EXT_CSD_CORRECTLY_PRG_SECTORS_NUM: printf("\tNumber of correctly programmed sectors: %u\n", val); return 1; case EXT_CSD_BKOPS_STATUS: - print_field_caption(BKOPS_STATUS, R); - val = get_field_val(BKOPS_STATUS, 0, 0x3); + val = get_field_val(EXT_CSD_BKOPS_STATUS, 0, 0x3); switch (val) { case 0: str = "not required"; @@ -1278,575 +1732,534 @@ static int print_field_ge_v5(u8 *reg, int index) printf("\t[1-0] Operations %s\n", str); return 1; - } - - return 0; -} -static int print_field_eq_v5(u8 *reg, int index) -{ - int rev; - u32 val; - - rev = reg[EXT_CSD_REV]; - - switch (index) { - case EXT_CSD_SEC_TRIM_MULT: - print_field_caption(SEC_TRIM_MULT, R); - val = get_field_val(SEC_TRIM_MULT, 0, 0xFF); - val = val * 300 * get_field_val(ERASE_TIMEOUT_MULT, 0, - 0xFF); - printf("\tSecure Trim time-out value: %u\n", val); - return 1; - - case EXT_CSD_SEC_ERASE_MULT: - print_field_caption(SEC_ERASE_MULT, R); - val = get_field_val(SEC_ERASE_MULT, 0, 0xFF); - val = val * 300 * get_field_val(ERASE_TIMEOUT_MULT, 0, - 0xFF); - printf("\tSecure Erase time-out value: %u\n", val); - return 1; - - } - - return 0; -} - -static int print_field(u8 *reg, int index) -{ - int rev; - u32 val; - u64 tmp64; - char *str = NULL; - - rev = reg[EXT_CSD_REV]; - - if (rev >= 7) - return print_field_ge_v7(reg, index); - if (rev >= 6) - return print_field_ge_v6(reg, index); - if (rev >= 5) - return print_field_ge_v5(reg, index); - if (rev == 5) - return print_field_eq_v5(reg, index); - - switch (index) { - case EXT_CSD_ERASE_GROUP_DEF: - print_field_caption(ERASE_GROUP_DEF, RWE_P); - val = get_field_val(ERASE_GROUP_DEF, 0, 0x1); - printf("\t[0] ENABLE: Use %s size definition\n", - val ? "high-capacity" : "old"); + case EXT_CSD_CACHE_CTRL: + val = get_field_val(EXT_CSD_CACHE_CTRL, 0, 0x1); + printf("\t[0] CACHE_EN: %s\n", val ? "ON" : "OFF"); return 1; - case EXT_CSD_BOOT_BUS_CONDITIONS: - print_field_caption(BOOT_BUS_CONDITIONS, RWE); - val = get_field_val(BOOT_BUS_CONDITIONS, 0, 0x3); + case EXT_CSD_POWER_OFF_NOTIFICATION: + val = get_field_val(EXT_CSD_POWER_OFF_NOTIFICATION, 0, 0x7); switch (val) { case 0x0: - str = "x1 (sdr) or x4 (ddr)"; + printf("\t[2-0] NO_POWER_NOTIFICATION\n"); break; case 0x1: - str = "x4 (sdr/ddr)"; + printf("\t[2-0] POWERED_ON\n"); break; case 0x2: - str = "x8 (sdr/ddr)"; - break; - } - printf("\t[1-0] BOOT_BUS_WIDTH: %s bus width in boot operation mode\n", - str); - val = get_field_val(BOOT_BUS_CONDITIONS, 2, 0x1); - if (val) - str = "Reset bus width to x1, SDR and backward compatible timings after boot operation"; - else - str = "Retain BOOT_BUS_WIDTH and BOOT_MODE values after boot operation"; - printf("\t[2] RESET_BOOT_BUS_CONDITIONS: %s", str); - val = get_field_val(BOOT_BUS_CONDITIONS, 3, 0x3); - switch (val) { - case 0x0: - str = "Use SDR + backward compatible timings in boot operation"; + printf("\t[2-0] POWER_OFF_SHORT\n"); break; - case 0x1: - str = "Use SDR + HS timings in boot operation mode"; + case 0x3: + printf("\t[2-0] POWER_OFF_LONG\n"); break; - case 0x2: - str = "Use DDR in boot operation"; + case 0x4: + printf("\t[2-0] SLEEP_NOTIFICATION\n"); break; } - printf("\t[3] BOOT_MODE: %s\n", str); return 1; - case EXT_CSD_BOOT_CONFIG_PROT: - print_field_caption(BOOT_CONFIG_PROT, RWaRWC_P); - val = get_field_val(BOOT_CONFIG_PROT, 0, 0x1); - printf("\t[0] PWR_BOOT_CONFIG_PROT: %u\n", val); - val = get_field_val(BOOT_CONFIG_PROT, 4, 0x1); - printf("\t[4] PERM_BOOT_CONFIG_PROT: %u\n", val); + case EXT_CSD_PACKED_FAILURE_INDEX: + val = get_field_val(EXT_CSD_PACKED_FAILURE_INDEX, 0, 0xFF); + printf("\t[7-0] PACKED_FAILURE_INDEX: %u\n", val); return 1; - case EXT_CSD_PARTITION_CONFIG: - print_field_caption(PARTITION_CONFIG, RWEaRWE_P); - val = get_field_val(PARTITION_CONFIG, 0, 0x7); + case EXT_CSD_PACKED_COMMAND_STATUS: + val = get_field_val(EXT_CSD_PACKED_COMMAND_STATUS, 0, 0x1); + printf("\t[0] Error: %u\n", val); + val = get_field_val(EXT_CSD_PACKED_COMMAND_STATUS, 1, 0x1); + printf("\t[1] Indexed Error: %u\n", val); + return 1; + + /* EXT_CSD_CONTEXT_CONF */ + case EXT_CSD_CONTEXT_CONF(1) ... EXT_CSD_CONTEXT_CONF(15): + val = get_field_val(index, 0, 0x3); switch (val) { case 0x0: - str = "No access to boot partition"; + str = "closed, not active"; break; case 0x1: - str = "R/W boot partition 1"; + str = "configured and activated as write-only"; break; case 0x2: - str = "R/W boot partition 2"; + str = "configured and activated as read-only"; break; case 0x3: - str = "R/W Replay Protected Memory Block (RPMB)"; - break; - case 0x4: - str = "Access to General Purpose partition 1"; - break; - case 0x5: - str = "Access to General Purpose partition 2"; - break; - case 0x6: - str = "Access to General Purpose partition 3"; - break; - case 0x7: - str = "Access to General Purpose partition 4"; + str = "configured and activated as read/write"; break; } - printf("\t[2-0] PARTITION_ACCESS: %s\n", str); - val = get_field_val(PARTITION_CONFIG, 3, 0x7); + printf("\t[1-0] Activation and direction: context is %s\n", + str); + val = get_field_val(index, 2, 0x1); + if (val) + str = "follows rules"; + else + str = "doesn't follow rules"; + printf("\t[2] Large Unit context: %s\n", str); + val = get_field_val(index, 3, 0x3); + printf("\t[5-3] Large Unit multiplier: %u\n", val); + val = get_field_val(index, 0, 0x3); switch (val) { case 0x0: - str = "Device not boot enabled"; + str = "MODE0"; break; case 0x1: - str = "Boot partition 1 enabled for boot"; + str = "MODE1"; break; case 0x2: - str = "Boot partition 2 enabled for boot"; - break; - case 0x7: - str = "User area enabled for boot"; + str = "MODE2"; break; } - printf("\t[5-3] BOOT_PARTITION_ENABLE: %s\n", str); - val = get_field_val(PARTITION_CONFIG, 6, 0x1); - if (val) - str = "Boot acknowledge sent during boot operation Bit"; - else - str = "No boot acknowledge sent"; - printf("\t[6] BOOT_ACK: %s\n", str); + printf("\t[7-6] Reliability mode: %s\n", str); return 1; - case EXT_CSD_ERASED_MEM_CONT: - print_field_caption(ERASED_MEM_CONT, R); - val = get_field_val(ERASED_MEM_CONT, 0, 0x1); - printf("\t[0] Erased Memory Content: %u\n", val); + case EXT_CSD_EXT_PARTITIONS_ATTRIBUTE: + printf("\t[3-0] EXT_1\n"); + printf("\t[7-4] EXT_2\n"); + printf("\t[11-8] EXT_3\n"); + printf("\t[15-12] EXT_4\n"); return 1; - case EXT_CSD_BUS_WIDTH: - print_field_caption(BUS_WIDTH, WE_P); - val = get_field_val(BUS_WIDTH, 0, 0xF); - switch (val) { - case 0: - str = "1 bit data bus"; - break; - case 1: - str = "4 bit data bus"; - break; - case 2: - str = "8 bit data bus"; - break; - case 5: - str = "4 bit data bus (dual data rate)"; - break; - case 6: - str = "8 bit data bus (DDR)"; - break; - } - printf("\t[3-0] Bus Mode: %s\n", str); - val = get_field_val(BUS_WIDTH, 7, 0x1); - printf("\t[7] Strobe is provided during Data Out, CRC response%s\n", - val ? ", CMD Response" : ""); + case EXT_CSD_EXCEPTION_EVENTS_STATUS: + val = get_field_val(EXT_CSD_EXCEPTION_EVENTS_STATUS, 0, 0x1); + printf("\t[0] URGENT_BKOPS: %i\n", val); + val = get_field_val(EXT_CSD_EXCEPTION_EVENTS_STATUS, 1, 0x1); + printf("\t[1] DYNCAP_NEEDED: %i\n", val); + val = get_field_val(EXT_CSD_EXCEPTION_EVENTS_STATUS, 2, 0x1); + printf("\t[2] SYSPOOL_EXHAUSTED: %i\n", val); + val = get_field_val(EXT_CSD_EXCEPTION_EVENTS_STATUS, 3, 0x1); + printf("\t[3] PACKED_FAILURE: %i\n", val); + val = get_field_val(EXT_CSD_EXCEPTION_EVENTS_STATUS, 4, 0x1); + printf("\t[4] EXTENDED_SECURITY_FAILURE: %i\n", val); return 1; - case EXT_CSD_STROBE_SUPPORT: - print_field_caption(STROBE_SUPPORT, R); - val = get_field_val(STROBE_SUPPORT, 0, 0x1); - printf("\t[0] Enhanced Strobe mode: %ssupported\n", - val ? "" : "not "); + case EXT_CSD_EXCEPTION_EVENTS_CTRL: + val = get_field_val(EXT_CSD_EXCEPTION_EVENTS_CTRL, 1, 0x1); + printf("\t[1] DYNCAP_EVENT_EN: %i\n", val); + val = get_field_val(EXT_CSD_EXCEPTION_EVENTS_CTRL, 2, 0x1); + printf("\t[2] SYSPOOL_EVENT_EN: %i\n", val); + val = get_field_val(EXT_CSD_EXCEPTION_EVENTS_CTRL, 3, 0x1); + printf("\t[3] PACKED_EVENT_EN: %i\n", val); + val = get_field_val(EXT_CSD_EXCEPTION_EVENTS_CTRL, 4, 0x1); + printf("\t[4] EXTENDED_SECURITY_EN: %i\n", val); return 1; - case EXT_CSD_HS_TIMING: - print_field_caption(HS_TIMING, RWE_P); - val = get_field_val(HS_TIMING, 0, 0xF); - switch (val) { - case 0x0: - str = "Selecting backwards compatibility interface timing"; - break; - case 0x1: - str = "High Speed"; - break; - case 0x2: - str = "HS200"; - break; - case 0x3: - str = "HS400"; - break; - } - printf("\t[3-0] Timing Interface: %s\n", str); + case EXT_CSD_CLASS_6_CTRL: + val = get_field_val(EXT_CSD_CLASS_6_CTRL, 0, 0x1); + if (val) + printf("\t[0] Dynamic Capacity\n"); + else + printf("\t[0] Write Protect\n"); return 1; - case EXT_CSD_POWER_CLASS: - print_field_caption(POWER_CLASS, RWE_P); - val = get_field_val(POWER_CLASS, 0, 0xFF); - printf("\t[7-0] Device power class code: %#02x\n", val); + case EXT_CSD_INI_TIMEOUT_EMU: + val = get_field_val(EXT_CSD_INI_TIMEOUT_EMU, 0, 0xFF); + val = val * 100; + printf("\tInitialization Time out value: %u ms\n", val); return 1; - case EXT_CSD_CMD_SET_REV: - print_field_caption(CMD_SET_REV, R); - val = get_field_val(CMD_SET_REV, 0, 0xFF); - printf("\t[7-0] Command set revisions: %#02x\n", val); + case EXT_CSD_DATA_SECTOR_SIZE: + val = get_field_val(EXT_CSD_DATA_SECTOR_SIZE, 0, 0x1); + if (val) + str = "4 KB"; + else + str = "512 B"; + printf("\t[0] Data sector size is %s\n", str); return 1; - case EXT_CSD_CMD_SET: - print_field_caption(CMD_SET, RWE_P); - val = get_field_val(CMD_SET, 0, 0xFF); - printf("\t[7-0] Command set that is currently active in the Device: %#02x\n", - val); + case EXT_CSD_USE_NATIVE_SECTOR: + val = get_field_val(EXT_CSD_USE_NATIVE_SECTOR, 0, 0x1); + if (val) + printf("\t[0] Device sector size is larger than 512 B\n"); + else + printf("\t[0] Device sector size is 512 B (emulated or native)\n"); return 1; - case EXT_CSD_REV: - print_field_caption(REV, R); - val = get_field_val(REV, 0, 0x1F); - switch (val) { - case 0: - str = "1.0 (for MMC v4.0)"; - break; - case 1: - str = "1.1 (for MMC v4.1)"; - break; - case 2: - str = "1.2 (for MMC v4.2)"; - break; - case 3: - str = "1.3 (for MMC v4.3)"; - break; - case 4: - str = "1.4 (Obsolete)"; - break; - case 5: - str = "1.5 (for MMC v4.41)"; - break; - case 6: - str = "1.6 (for MMC v4.5, v4.51)"; - break; - case 7: - str = "1.7 (for MMC v5.0, v5.01)"; - break; - case 8: - str = "1.8 (for MMC v5.1)"; - break; - } - printf("\t[4-0] Extended CSD Revision: Revision %s\n", str); + case EXT_CSD_NATIVE_SECTOR_SIZE: + val = get_field_val(EXT_CSD_NATIVE_SECTOR_SIZE, 0, 0x1); + if (val) + str = "4 KB"; + else + str = "512 B"; + printf("\t[0] Native sector size is %s\n", str); return 1; - case EXT_CSD_CSD_STRUCTURE: - print_field_caption(CSD_STRUCTURE, R); - val = get_field_val(CSD_STRUCTURE, 0, 0x3); + case EXT_CSD_PROGRAM_CID_CSD_DDR_SUPPORT: + val = get_field_val(EXT_CSD_PROGRAM_CID_CSD_DDR_SUPPORT, 0, 0x1); + if (val) + str = "single data rate and dual data rate"; + else + str = "single data rate"; + printf("\t[0] PROGRAM_CID_CSD_DDR_SUPPORT: CMD26 and CMD27 %s mode\n", + str); + return 1; + + case EXT_CSD_PERIODIC_WAKEUP: + val = get_field_val(EXT_CSD_PERIODIC_WAKEUP, 0, 0x1F); + printf("\t[5-0] WAKEUP_PERIOD: %u\n", val); + val = get_field_val(EXT_CSD_PERIODIC_WAKEUP, 5, 0x7); switch (val) { case 0x0: - str = "0"; + str = "infinity"; break; case 0x1: - str = "1"; + str = "months"; break; case 0x2: - str = "2"; - break; - } - printf("\t[1-0] CSD structure version: CSD version No. 1.%s\n", - str); - return 1; - - case EXT_CSD_DEVICE_TYPE: - print_field_caption(DEVICE_TYPE, R); - val = get_field_val(DEVICE_TYPE, 0, 0xFF); - switch (val) { - case 0x1: - str = "HS eMMC @26MHz - at rated device voltage(s)"; + str = "weeks"; break; - case 0x2: - str = "HS eMMC @52MHz - at rated device voltage(s)"; + case 0x3: + str = "days"; break; case 0x4: - str = "HS Dual Data Rate eMMC @52MHz 1.8V or 3VI/O"; - break; - case 0x8: - str = "HS Dual Data Rate eMMC @52MHz 1.2VI/O"; - break; - case 0x10: - str = "HS200 Single Data Rate eMMC @200MHz 1.8VI/O"; + str = "hours"; break; - case 0x20: - str = "HS200 Single Data Rate eMMC @200MHz 1.2VI/O"; + case 0x5: + str = "minutes"; break; } - printf("\t%s\n", str); + printf("\t[7-5] WAKEUP_UNIT: %s\n", str); return 1; - /* TODO: missing JEDEC documention */ - case EXT_CSD_PWR_CL_52_195: - print_field_caption(PWR_CL_52_195, R) - val = get_field_val(PWR_CL_52_195, 0, 0xFF); - printf("\tPower class for 52 MHz at 1.95 V 1 R: %#02x\n", val); + case EXT_CSD_PWR_CL_200_195: + val = get_field_val(EXT_CSD_PWR_CL_200_195, 0, 0xFF); + printf("\tPower class for 200MHz, at 1.95V %#02x\n", val); return 1; - case EXT_CSD_PWR_CL_26_195: - print_field_caption(PWR_CL_26_195, R) - val = get_field_val(PWR_CL_26_195, 0, 0xFF); - printf("\tPower class for 26 MHz at 1.95 V 1 R: %#02x\n", val); + case EXT_CSD_PWR_CL_200_360: + val = get_field_val(EXT_CSD_PWR_CL_200_360, 0, 0xFF); + printf("\tPower class for 200MHz, at 3.6V %#02x\n", val); return 1; - case EXT_CSD_PWR_CL_52_360: - print_field_caption(PWR_CL_52_360, R) - val = get_field_val(PWR_CL_52_360, 0, 0xFF); - printf("\tPower class for 52 MHz at 3.6 V 1 R: %#02x\n", val); + case EXT_CSD_POWER_OFF_LONG_TIME: + val = get_field_val(EXT_CSD_POWER_OFF_LONG_TIME, 0, 0xFF); + val = val * 10; + printf("\tGeneric Switch Timeout Definition: %u ms\n", val); return 1; - case EXT_CSD_PWR_CL_26_360: - print_field_caption(PWR_CL_26_360, R) - val = get_field_val(PWR_CL_26_360, 0, 0xFF); - printf("\tPower class for 26 MHz at 3.6 V 1 R: %#02x\n", val); + case EXT_CSD_GENERIC_CMD6_TIME: + val = get_field_val(EXT_CSD_GENERIC_CMD6_TIME, 0, 0xFF); + val = val * 10; + printf("\tGeneric Switch Timeout Definition: %u ms\n", val); return 1; - case EXT_CSD_MIN_PERF_R_4_26: - print_field_caption(MIN_PERF_R_4_26, R) - val = get_field_val(MIN_PERF_R_4_26, 0, 0xFF); - printf("\tMinimum Read Performance for 4bit at 26 MHz: %#02x\n", - val); + case EXT_CSD_CACHE_SIZE: + printf("\tCache Size: %u KiB\n", val); return 1; - case EXT_CSD_MIN_PERF_W_4_26: - print_field_caption(MIN_PERF_W_4_26, R) - val = get_field_val(MIN_PERF_W_4_26, 0, 0xFF); - printf("\tMinimum Write Performance for 4bit at 26 MHz: %#02x\n", - val); + case EXT_CSD_EXT_SUPPORT: + val = get_field_val(EXT_CSD_EXT_SUPPORT, 0, 0x1); + printf("\t[0] System code: %ssupported\n", val ? "" : "not "); + val = get_field_val(EXT_CSD_EXT_SUPPORT, 1, 0x1); + printf("\t[1] Non-persistent: %ssupported\n", + val ? "" : "not "); return 1; - case EXT_CSD_MIN_PERF_R_8_26_4_52: - print_field_caption(MIN_PERF_R_8_26_4_52, R) - val = get_field_val(MIN_PERF_R_8_26_4_52, 0, 0xFF); - printf("\tMinimum Read Performance for 8bit at 26 MHz, for 4bit at 52MHz: %#02x\n", - val); + case EXT_CSD_LARGE_UNIT_SIZE_M1: + val = get_field_val(EXT_CSD_LARGE_UNIT_SIZE_M1, 0, 0xFF); + printf("\tLarge Unit size: %#02x\n", val); return 1; - case EXT_CSD_MIN_PERF_W_8_26_4_52: - print_field_caption(MIN_PERF_W_8_26_4_52, R) - val = get_field_val(MIN_PERF_W_8_26_4_52, 0, 0xFF); - printf("\tMinimum Write Performance for 8bit at 26 MHz, for 4bit at 52MHz: %#02x\n", - val); + case EXT_CSD_CONTEXT_CAPABILITIES: + val = get_field_val(EXT_CSD_CONTEXT_CAPABILITIES, 0, 0xF); + printf("\t[3-0] MAX_CONTEXT_ID: %#02x\n", val); + val = get_field_val(EXT_CSD_CONTEXT_CAPABILITIES, 4, 0x7); + printf("\t[6-4] LARGE_UNIT_MAX_MULTIPLIER_M1: %#02x\n", val); return 1; - case EXT_CSD_MIN_PERF_R_8_52: - print_field_caption(MIN_PERF_R_8_52, R) - val = get_field_val(MIN_PERF_R_8_52, 0, 0xFF); - printf("\tMinimum Read Performance for 8bit at 52 MHz: %#02x\n", + case EXT_CSD_TAG_RES_SIZE: + val = get_field_val(EXT_CSD_TAG_RES_SIZE, 0, 0xFF); + printf("\tSystem Data Tag Resources Size: %#02x\n", val); + return 1; + + case EXT_CSD_TAG_UNIT_SIZE: + tmp = get_field_val(EXT_CSD_NATIVE_SECTOR_SIZE, 0, 0x1); + tmp = (tmp == 0) ? 512 : 4048; + val = 2 << (1 - get_field_val(EXT_CSD_TAG_UNIT_SIZE, 0, 0xFF)); + val = val * tmp; + printf("\tTag Unit Size: %u\n", val); + return 1; + + case EXT_CSD_DATA_TAG_SUPPORT: + val = get_field_val(EXT_CSD_DATA_TAG_SUPPORT, 0, 0x1); + printf("\t[0] SYSTEM_DATA_TAG_SUPPORT: %u\n", val); + return 1; + + case EXT_CSD_MAX_PACKED_WRITES: + val = get_field_val(EXT_CSD_MAX_PACKED_WRITES, 0, 0xFF); + printf("\tmaximum number of commands in write command: %u\n", val); return 1; - case EXT_CSD_MIN_PERF_W_8_52: - print_field_caption(MIN_PERF_W_8_52, R) - val = get_field_val(MIN_PERF_W_8_52, 0, 0xFF); - printf("\tMinimum Write Performance for 8bit at52 MHz: %#02x\n", + case EXT_CSD_MAX_PACKED_READS: + val = get_field_val(EXT_CSD_MAX_PACKED_READS, 0, 0xFF); + printf("\tmaximum number of commands in read command: %u\n", val); return 1; - case EXT_CSD_SECURE_WP_INFO: - print_field_caption(SECURE_WP_INFO, R); - val = get_field_val(SECURE_WP_INFO, 0, 0x1); - printf("\t[0] SECURE_WP_SUPPORT: %ssupported\n", - val ? "" : "not "); - val = get_field_val(SECURE_WP_INFO, 1, 0x1); - printf("\t[1] SECURE_WP_EN_STATUS: %s Write Protection mode\n", - val ? "Secure" : "Legacy"); + case EXT_CSD_CMDQ_MODE_EN: + val = get_field_val(EXT_CSD_CMDQ_MODE_EN, 0, 0x1); + printf("\tCommand queuing is %sabled\n", val ? "en" : "dis"); return 1; - /* EXT_CSD_SEC_COUNT */ - case 215: - case 214: - case 213: - case 212: - print_field_caption_with_offset(SEC_COUNT, - index - EXT_CSD_SEC_COUNT, R); - val = get_field_val(SEC_COUNT, 0, 0xFF); - val = val | get_field_val(SEC_COUNT + 1, 0, 0xFF) << 8; - val = val | get_field_val(SEC_COUNT + 2, 0, 0xFF) << 16; - val = val | get_field_val(SEC_COUNT + 3, 0, 0xFF) << 24; - tmp64 = val * 512; - printf("\tDevice density: %llu B\n", tmp64); + case EXT_CSD_SECURE_REMOVAL_TYPE: + val = get_field_val(EXT_CSD_SECURE_REMOVAL_TYPE, 0, 0xF); + switch (val) { + case 0x0: + str = "erase"; + break; + case 0x1: + str = "overwrite, then erase"; + break; + case 0x2: + str = "overwrite, complement, then random"; + break; + case 0x3: + str = "vendor defined"; + break; + } + printf("\t[3-0] Supported Secure Removal Type: %s\n", str); + val = get_field_val(EXT_CSD_SECURE_REMOVAL_TYPE, 4, 0xF); + switch (val) { + case 0x0: + str = "erase"; + break; + case 0x1: + str = "overwrite, then erase"; + break; + case 0x2: + str = "overwrite, complement, then random"; + break; + case 0x3: + str = "vendor defined"; + break; + } + printf("\t[7-4] Configure Secure Removal Type: %s\n", str); return 1; - case EXT_CSD_SLEEP_NOTIFICATION_TIME: - print_field_caption(SLEEP_NOTIFICATION_TIME, R); - val = get_field_val(SLEEP_NOTIFICATION_TIME, 0, 0xFF); - val = 100 << val; - if (val) - str = basprintf("Sleep Notification timeout values: %u us", - val); + case EXT_CSD_PRODUCT_ST8_AWARENSS_ENABLEMENT: + val = get_field_val(EXT_CSD_PRODUCT_ST8_AWARENSS_ENABLEMENT, 0, 0x1); + printf("\t[0] Manual mode is %ssupported\n", + val ? "" : "not "); + val = get_field_val(EXT_CSD_PRODUCT_ST8_AWARENSS_ENABLEMENT, 1, 0x1); + printf("\t[1] Auto mode is %ssupported\n", (val ? "" : "not ")); + val = get_field_val(EXT_CSD_PRODUCT_ST8_AWARENSS_ENABLEMENT, 4, 0x1); + printf("\t[4] Production State Awareness is %sabled\n", + val ? "en" : "dis"); + val = get_field_val(EXT_CSD_PRODUCT_ST8_AWARENSS_ENABLEMENT, 5, 0x1); + printf("\t[5] Auto mode is %sabled\n", (val ? "en" : "dis")); + return 1; + + case EXT_CSD_MAX_PRE_LOADING_DATA_SIZE: + tmp = get_field_val(EXT_CSD_DATA_SECTOR_SIZE, 0, 0x1); + if (tmp64 == 0xFFFFFFFF) + if (tmp) + str = strdup("16 TB"); + else + str = strdup("2 TB"); else - str = strdup("Not defined"); - printf("\t[7-0] %s\n", str); + if (tmp) + str = basprintf("%llu B", tmp64 * 4096); + else + str = basprintf("%llu B", tmp64 * 512); + printf("\tMax_Pre_Loading_Data_Size: %s\n", str); free(str); return 1; - case EXT_CSD_S_A_TIMEOUT: - print_field_caption(S_A_TIMEOUT, R); - val = get_field_val(S_A_TIMEOUT, 0, 0xFF); - val = 100 << val; - if (val) - str = basprintf("Sleep/awake timeout values: %u ns", val); + case EXT_CSD_PRE_LOADING_DATA_SIZE: + tmp = get_field_val(EXT_CSD_DATA_SECTOR_SIZE, 0, 0x1); + if (tmp64 == 0xFFFFFFFF) + if (tmp) + str = strdup("16 TB"); + else + str = strdup("2 TB"); else - str = strdup("Not defined"); - printf("\t[7-0] %s\n", str); + if (tmp) + str = basprintf("%llu B", tmp64 * 4096); + else + str = basprintf("%llu B", tmp64 * 512); + printf("\tPre_Loading_Data_Size: %s\n", str); free(str); return 1; - case EXT_CSD_PRODUCTION_ST8_AWARENSS_TIMEOUT: - print_field_caption(PRODUCTION_ST8_AWARENSS_TIMEOUT, R); - val = get_field_val(PRODUCTION_ST8_AWARENSS_TIMEOUT, 0, 0xFF); - val = 100 << val; + case EXT_CSD_FFU_STATUS: + val = get_field_val(EXT_CSD_FFU_STATUS, 0, 0x13); + switch (val) { + case 0x0: + str = "success"; + break; + case 0x10: + str = "general error"; + break; + case 0x11: + str = "firmware install error"; + break; + case 0x12: + str = "firmware download error"; + break; + } + printf("\t[5-0] Code: %s\n", str); + return 1; + + case EXT_CSD_MODE_CONFIG: + val = get_field_val(EXT_CSD_MODE_CONFIG, 0, 0xFF); + switch (val) { + case 0x0: + str = "normal"; + break; + case 0x1: + str = "FFU"; + break; + case 0x10: + str = "vendor"; + break; + } + printf("\t[7-0] Value: %s\n", str); + return 1; + + case EXT_CSD_BARRIER_CTRL: + val = get_field_val(EXT_CSD_BARRIER_CTRL, 0, 0x1); + printf("\t[0] BARRIER_EN: %s\n", val ? "ON" : "OFF"); + return 1; + + case EXT_CSD_OUT_OF_INTERRUPT_TIME: + val = get_field_val(EXT_CSD_OUT_OF_INTERRUPT_TIME, 0, 0xFF); + val = val * 10; if (val) - str = basprintf( - "Production State Awareness timeout definition: %u us", + printf("\tOut-of-interrupt timeout definition: %u ms\n", val); else - str = strdup("Not defined"); - printf("\t[7-0] %s\n", str); - free(str); + printf("\tNot Defined\n"); return 1; - case EXT_CSD_S_C_VCCQ: - print_field_caption(S_C_VCCQ, R); - val = get_field_val(S_C_VCCQ, 0, 0xF); - val = 1 << val; + case EXT_CSD_PARTITION_SWITCH_TIME: + val = get_field_val(EXT_CSD_PARTITION_SWITCH_TIME, 0, 0xFF); + val = val * 10; if (val) - str = basprintf("S_C_VCCQ Sleep Current: %u uA", val); + printf("\tPartition switch timeout definition: %u ms\n", + val); else - str = strdup("Not defined"); - printf("\t[3-0] %s\n", str); - free(str); + printf("\tNot Defined\n"); return 1; - case EXT_CSD_S_C_VCC: - print_field_caption(S_C_VCC, R); - val = get_field_val(S_C_VCC, 0, 0xFF); - val = 1 << val; - if (val) - str = basprintf("S_C_VCC Sleep Current: %u uA", val); - else - str = strdup("Not defined"); - printf("\t[3-0] %s\n", str); - free(str); + case EXT_CSD_DRIVER_STRENGTH: + val = get_field_val(EXT_CSD_DRIVER_STRENGTH, 0, 0x1); + printf("\t[0] Type 0: %ssupported\n", val ? "" : "not "); + val = get_field_val(EXT_CSD_DRIVER_STRENGTH, 1, 0x1); + printf("\t[1] Type 1: %ssupported\n", val ? "" : "not "); + val = get_field_val(EXT_CSD_DRIVER_STRENGTH, 2, 0x1); + printf("\t[2] Type 2: %ssupported\n", val ? "" : "not "); + val = get_field_val(EXT_CSD_DRIVER_STRENGTH, 3, 0x1); + printf("\t[3] Type 3: %ssupported\n", val ? "" : "not "); + val = get_field_val(EXT_CSD_DRIVER_STRENGTH, 4, 0x1); + printf("\t[4] Type 4: %ssupported\n", val ? "" : "not "); return 1; - case EXT_CSD_HC_WP_GRP_SIZE: - print_field_caption(HC_WP_GRP_SIZE, R); - val = get_field_val(HC_WP_GRP_SIZE, 0, 0xFF); + case EXT_CSD_CACHE_FLUSH_POLICY: + val = get_field_val(EXT_CSD_CACHE_FLUSH_POLICY, 0, 0x1); if (val) - str = basprintf("Write protect group size: %u", val); + str = "FIFO policy for cache"; else - str = strdup("No support"); - printf("\t[7-0] %s\n", str); - free(str); + str = "not provided"; + printf("\t[0] Device flushing: %s", str); return 1; - case EXT_CSD_REL_WR_SEC_C: - print_field_caption(REL_WR_SEC_C, R); - val = get_field_val(REL_WR_SEC_C, 0, 0xFF); - printf("\t[7-0] Reliable Write Sector Count: %u\n", val); + case EXT_CSD_OPTIMAL_READ_SIZE: + val = get_field_val(EXT_CSD_OPTIMAL_READ_SIZE, 0, 0xFF); + val = val * 4048; + printf("\t[7-0] Minimum optimal read unit size: %u\n", val); return 1; - case EXT_CSD_ERASE_TIMEOUT_MULT: - print_field_caption(ERASE_TIMEOUT_MULT, R); - val = get_field_val(ERASE_TIMEOUT_MULT, 0, 0xFF); - val = val * 300; - if (val) - str = basprintf("Erase timeout values: %u", val); - else - str = strdup("No support"); - printf("\t[7-0] %s\n", str); - free(str); + case EXT_CSD_OPTIMAL_WRITE_SIZE: + val = get_field_val(EXT_CSD_OPTIMAL_WRITE_SIZE, 0, 0xFF); + val = val * 4048; + printf("\t[7-0] Minimum optimal write unit size: %u\n", val); return 1; - case EXT_CSD_HC_ERASE_GRP_SIZE: - print_field_caption(HC_ERASE_GRP_SIZE, R); - val = get_field_val(HC_ERASE_GRP_SIZE, 0, 0xFF); - val = val * 524288; - if (val) - str = basprintf("Erase-unit size: %u", val); + case EXT_CSD_PRE_EOL_INFO: + val = get_field_val(EXT_CSD_PRE_EOL_INFO, 0, 0x3); + switch (val) { + case 1: + str = "normal"; + break; + case 2: + str = "warning"; + break; + case 3: + str = "urgent"; + break; + default: + str = "Not defined"; + } + printf("\t[1-0] Device life time: %s\n", str); + return 1; + + case EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A: + val = get_field_val(EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A, 0, 0xFF); + val = val * 10; + if (val == 0) + str = strdup("not defined"); + else if (val == 0xB) + str = strdup("maximum"); else - str = strdup("No support"); - printf("\t[7-0] %s\n", str); + str = basprintf("%u%% - %u%%", (val - 10), val); + printf("\tDevice life time, type A (estimation): %s\n", str); free(str); return 1; - case EXT_CSD_ACC_SIZE: - print_field_caption(ACC_SIZE, R); - val = get_field_val(ACC_SIZE, 0, 0xF); - val = val * 512; - if (val) - str = basprintf("Superpage size: %u", val); + case EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B: + val = get_field_val(EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B, 0, 0xFF); + val = val * 10; + if (val == 0) + str = strdup("not defined"); + else if (val == 0xB) + str = strdup("maximum"); else - str = strdup("Not defined"); - printf("\t[3-0] %s\n", str); + str = basprintf("%u%% - %u%%", (val - 10), val); + printf("\tDevice life time, type B (estimation): %s\n", str); free(str); return 1; - case EXT_CSD_BOOT_SIZE_MULT: - print_field_caption(BOOT_SIZE_MULT, R); - val = get_field_val(BOOT_SIZE_MULT, 0, 0xFF); - val = val * 131072; - printf("\tBoot partition size: %u\n", val); + case EXT_CSD_NMBR_OF_FW_SCTRS_CRRCTLY_PRGRMD: return 1; - case EXT_CSD_BOOT_INFO: - print_field_caption(BOOT_INFO, R); - val = get_field_val(BOOT_INFO, 0, 0x1); - printf("\t[0] ALT_BOOT_MODE: %ssupported\n", val ? "" : "not "); - val = get_field_val(BOOT_INFO, 1, 0x1); - printf("\t[1] DDR_BOOT_MODE: %ssupported\n", val ? "" : "not "); - val = get_field_val(BOOT_INFO, 2, 0x1); - printf("\t[2] HS_BOOT_MODE: %ssupported\n", val ? "" : "not "); + case EXT_CSD_CMDQ_DEPTH: + val = get_field_val(EXT_CSD_CMDQ_DEPTH, 0, 0xF); + ++val; + printf("\t[3-0] Queue Depth: %u", val); return 1; - case EXT_CSD_BKOPS_SUPPORT: - print_field_caption(BKOPS_SUPPORT, R); - val = get_field_val(BKOPS_SUPPORT, 0, 0x1); - printf("\t[0] SUPPORTED: %u\n", val); + case EXT_CSD_CMDQ_SUPPORT: + val = get_field_val(EXT_CSD_CMDQ_SUPPORT, 0, 0x1); + printf("\t[0] Command queuing: %ssupported\n", + val ? "" : "not "); return 1; - case EXT_CSD_HPI_FEATURES: - print_field_caption(HPI_FEATURES, R); - val = get_field_val(HPI_FEATURES, 0, 0x1); - printf("\t[0] HPI_SUPPORTED: %u\n", val); - val = get_field_val(HPI_FEATURES, 1, 0x1); - printf("\t[1] HPI_FEATURES: implementation based on CMD1%s\n", - val ? "2" : "3"); + case EXT_CSD_BARRIER_SUPPORT: + val = get_field_val(EXT_CSD_BARRIER_SUPPORT, 0, 0x1); + printf("\t[0] Barrier command: %ssupported\n", + val ? "" : "not "); return 1; - case EXT_CSD_S_CMD_SET: - print_field_caption(S_CMD_SET, R); - val = get_field_val(S_CMD_SET, 0, 0xFF); - printf("\t[7-0] Command Set: %#02x\n", val); + case EXT_CSD_FFU_ARG: return 1; - case EXT_CSD_EXT_SECURITY_ERR: - print_field_caption(EXT_SECURITY_ERR, R); - val = get_field_val(EXT_SECURITY_ERR, 0, 0x1); - printf("\t[0] SEC_INVALID_COMMAND_PARAMETERS: %u\n", val); - val = get_field_val(EXT_SECURITY_ERR, 1, 0x1); - printf("\t[1] ACCESS_DENIED: %u\n", val); + case EXT_CSD_OPERATION_CODES_TIMEOUT: + val = get_field_val(EXT_CSD_OPERATION_CODES_TIMEOUT, 0, 0xFF); + printf("\t[7-0] Timeout Values: %#02x\n", val); return 1; + case EXT_CSD_FFU_FEATURES: + val = get_field_val(EXT_CSD_FFU_FEATURES, 0, 0x1); + printf("\t[0] NUMBER_OF_FW_SECTORS_CORRECTLY_PROGRAMMED: " + "%ssupported\n", val ? "" : " not"); + return 1; + + case EXT_CSD_SUPPORTED_MODES: + val = get_field_val(EXT_CSD_SUPPORTED_MODES, 0, 0x1); + printf("\t[0] FFU: %ssupported\n", val ? "" : "not "); + val = get_field_val(EXT_CSD_SUPPORTED_MODES, 1, 0x1); + printf("\t[1] VSM: %ssupported\n", val ? "" : "not "); + return 1; } return 0; diff --git a/include/mci.h b/include/mci.h index bc7d9c95b2..d3115e8cc6 100644 --- a/include/mci.h +++ b/include/mci.h @@ -160,7 +160,7 @@ #define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */ #define EXT_CSD_PACKED_FAILURE_INDEX 35 /* RO */ #define EXT_CSD_PACKED_COMMAND_STATUS 36 /* RO */ -#define EXT_CSD_CONTEXT_CONF 37 /* R/W, 15 bytes */ +#define EXT_CSD_CONTEXT_CONF(index) (37 + (index) - 1) /* R/W, 15 bytes */ #define EXT_CSD_EXT_PARTITIONS_ATTRIBUTE 52 /* R/W, 2 bytes */ #define EXT_CSD_EXCEPTION_EVENTS_STATUS 54 /* RO, 2 bytes */ #define EXT_CSD_EXCEPTION_EVENTS_CTRL 56 /* R/W, 2 bytes */ @@ -176,7 +176,10 @@ #define EXT_CSD_SEC_BAD_BLK_MGMNT 134 /* R/W */ #define EXT_CSD_ENH_START_ADDR 136 /* R/W, 4 bytes */ #define EXT_CSD_ENH_SIZE_MULT 140 /* R/W, 3 bytes */ -#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */ +#define EXT_CSD_GP_SIZE_MULT0 143 /* R/W */ +#define EXT_CSD_GP_SIZE_MULT1 146 /* R/W */ +#define EXT_CSD_GP_SIZE_MULT2 149 /* R/W */ +#define EXT_CSD_GP_SIZE_MULT3 152 /* R/W */ #define EXT_CSD_PARTITION_SETTING_COMPLETED 155 /* R/W */ #define EXT_CSD_PARTITIONS_ATTRIBUTE 156 /* R/W */ #define EXT_CSD_MAX_ENH_SIZE_MULT 157 /* RO, 3 bytes */ |