#include #include #include #include #include extern u8 saved_ext_csd[MMC_MAX_BLOCK_LEN]; char* get_mmc_info(u32 ext_idx, u8 ext_value) { int i; // printf("ext_idx =%d ext_value = %d\n",ext_idx ,ext_value ); for (i = 0 ; i >3) + 8)); printf("%s\n", get_mmc_info(EXT_CSD_PART_CONF, (ext_value & EXT_CSD_BOOT_CFG_ACC))); printf("%s\n", get_mmc_info(EXT_CSD_PART_CONF, ((ext_value & EXT_CSD_BOOT_CFG_ACK)>>6) + 16)); printf("=============================================\n"); } void print_mmc_life(void) { u8 ext_eol = saved_ext_csd[EXT_CSD_PRE_EOL_INFO]; u8 life_timeA = saved_ext_csd[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A]; u8 life_timeB = saved_ext_csd[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B]; printf("=============================================\n"); printf("Pre EOL info = %s\n", (ext_eol > 0x4)?pre_eol_info[0x4] : pre_eol_info[ext_eol]); printf("Life time typeA = %s\n", (life_timeA > 0x4)?life_time_typeAorB[0xC] : life_time_typeAorB[life_timeA]); printf("Life time typeB = %s\n", (life_timeB > 0x4)?life_time_typeAorB[0xC] : life_time_typeAorB[life_timeB]); printf("=============================================\n"); } void print_mmc_ext_csd(void) { int i; char *ext_info; u8 ext_value = 0, ext_csd_rev = 0; ext_csd_rev = saved_ext_csd[EXT_CSD_REV] ; u32 value = 0; ext_info = get_mmc_info(EXT_CSD_REV, ext_csd_rev); printf("=============================================\n"); printf(" Extended CSD rev 1.%d (MMC %s)\n", ext_csd_rev, ext_info); printf("=============================================\n\n"); if (ext_csd_rev < 3) { printf("No ext_csd\n"); return; } /* Parse the Extended CSD registers. * Reserved bit should be read as "0" in case of spec older * than A441. */ ext_info = get_mmc_info(EXT_CSD_S_CMD_SET, saved_ext_csd[EXT_CSD_S_CMD_SET]); printf("=============================================\n"); printf("[S_CMD_SET]:\n"); printf("%s\n", ext_info); printf("=============================================\n"); if (ext_value & EXT_CSD_HPI_SUPP) { printf("=============================================\n"); printf("[EXT_CSD_HPI_FEATURE] =%s\n",get_mmc_info(EXT_CSD_HPI_FEATURE, saved_ext_csd[EXT_CSD_HPI_FEATURE] & EXT_CSD_HPI_SUPP)); printf("%s\n",get_mmc_info(EXT_CSD_HPI_FEATURE, (saved_ext_csd[EXT_CSD_HPI_FEATURE] & EXT_CSD_HPI_SUPP) & EXT_CSD_HPI_IMPL)+2); printf("=============================================\n"); } printf("=============================================\n"); printf("[BKOPS_SUPPORT]=%s\n", get_mmc_info(EXT_CSD_BKOPS_SUPPORT, saved_ext_csd[EXT_CSD_BKOPS_SUPPORT])); printf("=============================================\n"); if (ext_csd_rev >= 6) { printf("=============================================\n"); printf("[Max Packet Read Cmd]:\n"); printf("0x%02x\n",saved_ext_csd[501]); printf("=============================================\n"); printf("[Max Packet Write Cmd [MAX_PACKED_WRITES]:\n"); printf("0x%02x\n",saved_ext_csd[500]); printf("=============================================\n"); printf("[DATA_TAG_SUPPORT]:\n"); printf("%s\n", get_mmc_info(499, saved_ext_csd[499])); printf("=============================================\n"); printf("[Data TAG Unit Size]:\n"); printf("0x%02x\n", saved_ext_csd[498]); printf("=============================================\n"); printf("[Tag Resources Size]:\n"); printf("0x%02x\n",saved_ext_csd[497]); printf("=============================================\n"); printf("[Context Management Capabilities]:\n"); printf("0x%02x\n", saved_ext_csd[496]); printf("=============================================\n"); printf("[Large Unit Size]:\n"); printf("0x%02x]\n", saved_ext_csd[495]); printf("=============================================\n"); printf("[Extended partition attribute support]:\n"); printf("0x%02x\n", saved_ext_csd[494]); printf("=============================================\n"); printf("[Generic CMD6 Timer]:\n"); printf("0x%02x\n", saved_ext_csd[248]); printf("=============================================\n"); printf("[Power off notification]:\n"); printf("0x%02x\n", saved_ext_csd[247]); printf("=============================================\n"); printf("[Cache Size]:\n"); printf("%d KiB\n",saved_ext_csd[249] << 0 | (saved_ext_csd[250] << 8) | (saved_ext_csd[251] << 16) | (saved_ext_csd[252] << 24)); printf("=============================================\n"); } /* A441: Reserved [501:247] A43: reserved [246:229] */ if (ext_csd_rev >= 5) { printf("=============================================\n"); printf("[BKOPS_STATUS]:\n"); printf("%s\n", get_mmc_info(246, saved_ext_csd[246])); printf("=============================================\n"); /* CORRECTLY_PRG_SECTORS_NUM [245:242] TODO */ printf("=============================================\n"); printf("[CORRECTLY_PRG_SECTORS_NUM_0]:\n"); printf("0x%02x\n", saved_ext_csd[242]); printf("[CORRECTLY_PRG_SECTORS_NUM_1]:\n"); printf("0x%02x\n", saved_ext_csd[243]); printf("[CORRECTLY_PRG_SECTORS_NUM_2]:\n"); printf("0x%02x\n", saved_ext_csd[244]); printf("[CORRECTLY_PRG_SECTORS_NUM_3]:\n"); printf("0x%02x\n", saved_ext_csd[245]); printf("=============================================\n"); printf("[1st Initialisation Time after programmed sector]:\n"); printf("0x%02x\n", saved_ext_csd[241]); printf("=============================================\n"); /* A441: reserved [237-236] */ /* A441: reserved [240] */ printf("[Power class for 52MHz, DDR at 3.6V (4 bit bus)]:\n"); printf("[Max RMS Current:Max Peak Current]=%s\n", get_mmc_info(239, saved_ext_csd[239]&0xf)); printf("[Power class for 52MHz, DDR at 3.6V (8 bit bus)]:\n"); printf("[Max RMS Current:Max Peak Current]=%s\n", get_mmc_info(239, (saved_ext_csd[239]>>4)&0xf)); printf("[Power class for 52MHz, DDR at 1.95V (4 bit bus)]:\n"); printf("[Max RMS Current:Max Peak Current]=%s\n", get_mmc_info(238, saved_ext_csd[238]&0xf)); printf("[Power class for 52MHz, DDR at 1.95V (8 bit bus)]:\n"); printf("[Max RMS Current:Max Peak Current]=%s\n", get_mmc_info(238, (saved_ext_csd[238]>>4)&0xf)); printf("=============================================\n"); if (ext_csd_rev >= 6) { printf("[Power class for 200MHz at 3.6V (4 bit bus)]:\n"); printf("[Max RMS Current:Max Peak Current]=%s\n", get_mmc_info(237, saved_ext_csd[237]&0xf)); printf("[Power class for 200MHz at 3.6V (8 bit bus)]:\n"); printf("[Max RMS Current:Max Peak Current]=%s\n", get_mmc_info(237, (saved_ext_csd[237]>>4)&0xf)); printf("[Power class for 200MHz, at 1.95V (4 bit bus)]:\n"); printf("[Max RMS Current:Max Peak Current]=%s\n", get_mmc_info(236, saved_ext_csd[236]&0xf)); printf("[Power class for 200MHz, at 1.95V (8 bit bus)]:\n"); printf("[Max RMS Current:Max Peak Current]=%s\n", get_mmc_info(236, (saved_ext_csd[236]>>4)&0xf)); printf("=============================================\n"); } printf("[Minimum Performance for 8bit at 52MHz in DDR mode]:\n"); printf("[MIN_PERF_DDR_W_8_52]=%s\n", get_mmc_mim_perf(235, saved_ext_csd[235])); printf("[MIN_PERF_DDR_R_8_52]=%s\n", get_mmc_mim_perf(234, saved_ext_csd[234])); printf("=============================================\n"); /* A441: reserved [233] */ printf("[TRIM Multiplier]:\n"); printf("0x%02x\n", saved_ext_csd[232]); printf("=============================================\n"); printf("[SEC_FEATURE_SUPPORT]:\n"); if (saved_ext_csd[23l]&0x1) { printf("%s\n", get_mmc_info(231,1)); if (saved_ext_csd[23l]&0x4) printf("%s\n", get_mmc_info(231,3)); else printf("%s\n", get_mmc_info(231,2)); if (saved_ext_csd[23l]&0x10) printf("%s\n", get_mmc_info(231,5)); else printf("%s\n", get_mmc_info(231,4)); if (saved_ext_csd[23l]&0x40) printf("%s\n", get_mmc_info(231,7)); else printf("%s\n", get_mmc_info(231,6)); } else printf("%s\n", get_mmc_info(231,0)); printf("=============================================\n"); } if (ext_csd_rev == 5) { /* Obsolete in 4.5 */ printf("[Secure Erase Multiplier]:\n"); printf("0x%02x\n",saved_ext_csd[230]); printf("[Secure TRIM Multiplier]:\n"); printf("0x%02x]\n",saved_ext_csd[229]); printf("=============================================\n"); } ext_value = saved_ext_csd[EXT_CSD_BOOT_INFO]; printf("[Boot Information]:\n"); if (ext_value & EXT_CSD_BOOT_INFO_ALT) printf("%s\n", get_mmc_info(EXT_CSD_BOOT_INFO,1)); else printf("%s\n", get_mmc_info(EXT_CSD_BOOT_INFO,0)); if (ext_value & EXT_CSD_BOOT_INFO_DDR_DDR) printf("%s\n", get_mmc_info(EXT_CSD_BOOT_INFO,3)); else printf("%s\n", get_mmc_info(EXT_CSD_BOOT_INFO,2)); if (ext_value & EXT_CSD_BOOT_INFO_HS_MODE) printf("%s\n", get_mmc_info(EXT_CSD_BOOT_INFO,5)); else printf("%s\n", get_mmc_info(EXT_CSD_BOOT_INFO,4)); printf("=============================================\n"); /* A441/A43: reserved [227] */ printf("[Boot partition size]:\n"); printf("0x%02x\n", saved_ext_csd[226]); printf("[Access size]:\n"); printf("0x%02x\n", saved_ext_csd[225]); printf("=============================================\n"); ext_value = saved_ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; printf("[High-capacity erase unit size]:\n"); printf("0x%02x\n", saved_ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]); printf(" i.e. %u KiB\n", 512 * ext_value); printf("=============================================\n"); printf("[High-capacity erase timeout]:\n"); printf("0x%02x]\n",saved_ext_csd[223]); printf("=============================================\n"); printf("[Reliable write sector count]:\n"); printf("0x%02x\n",saved_ext_csd[222]); printf("=============================================\n"); ext_value = saved_ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; printf("[High-capacity W protect group size]:\n"); printf("0x%02x\n",ext_value); printf("i.e. %lu KiB\n", 512l * saved_ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * ext_value); printf("=============================================\n"); printf("[Sleep current]:\n"); printf("0x%02x\n", saved_ext_csd[220]); printf("[Sleep current]:\n"); printf("0x%02x\n", saved_ext_csd[219]); /* A441/A43: reserved [218] */ printf("[Sleep/awake timeout]:\n"); printf("0x%02x\n", saved_ext_csd[217]); /* A441/A43: reserved [216] */ printf("=============================================\n"); unsigned int sectors = (saved_ext_csd[EXT_CSD_SEC_COUNT_3] << 24) | (saved_ext_csd[EXT_CSD_SEC_COUNT_2] << 16) | (saved_ext_csd[EXT_CSD_SEC_COUNT_2] << 8) | saved_ext_csd[EXT_CSD_SEC_COUNT_2]; printf("[Sector Count]:\n"); printf("0x%08x\n", sectors); /* over 2GiB devices are block-addressed */ if (sectors > (2u * 1024 * 1024 * 1024) / 512) printf(" Device is block-addressed\n"); else printf(" Device is NOT block-addressed\n"); printf("=============================================\n"); /* A441/A43: reserved [211] */ printf("[Minimum Write Performance for 8bit]:\n"); printf("[MIN_PERF_W_8_52]= %s\n", get_mmc_mim_perf(210, saved_ext_csd[210])); printf("[MIN_PERF_R_8_52]= %s\n", get_mmc_mim_perf(209, saved_ext_csd[209])); printf("[MIN_PERF_W_8_26_4_52]= %s\n", get_mmc_mim_perf(208, saved_ext_csd[208])); printf("[MIN_PERF_R_8_26_4_52]= %s\n", get_mmc_mim_perf(207, saved_ext_csd[207])); printf("Minimum Write Performance for 4bit:\n"); printf("[MIN_PERF_W_4_26]= %s\n", get_mmc_mim_perf(206, saved_ext_csd[206])); printf("[MIN_PERF_R_4_26]= %s\n", get_mmc_mim_perf(205, saved_ext_csd[205])); printf("=============================================\n"); /* A441/A43: reserved [204] */ printf("[Power classes registers]:\n"); printf(" [PWR_CL_26_360: 0x%02x]\n", saved_ext_csd[203]); printf("Power class for 26MHz at 3.6V (4 bit bus)\n"); printf("[Max RMS Current:Max Peak Current]=%s\n", get_mmc_info(203, saved_ext_csd[203]&0xf)); printf("Power class for 26MHz at 3.6V (8 bit bus)\n"); printf("[Max RMS Current:Max Peak Current]=%s\n", get_mmc_info(203, (saved_ext_csd[203]>>4)&0xf)); printf("Power class for 52MHz at 3.6V (4 bit bus)\n"); printf("[Max RMS Current:Max Peak Current]=%s\n", get_mmc_info(202, saved_ext_csd[202]&0xf)); printf("Power class for 52MHz at 3.6V (8 bit bus)\n"); printf("[Max RMS Current:Max Peak Current]= %s\n", get_mmc_info(202, (saved_ext_csd[202]>>4)&0xf)); printf("Power class for 26MHz, at 1.95V (4 bit bus)\n"); printf("[Max RMS Current:Max Peak Current]= %s\n", get_mmc_info(201, saved_ext_csd[201]&0xf)); printf("Power class for 26MHz, at 1.95V (8 bit bus)\n"); printf("[Max RMS Current:Max Peak Current]= %s\n", get_mmc_info(201, (saved_ext_csd[201]>>4)&0xf)); printf("Power class for 52MHz, at 1.95V (4 bit bus)\n"); printf("[Max RMS Current:Max Peak Current]= %s\n", get_mmc_info(200, saved_ext_csd[200]&0xf)); printf("Power class for 52MHz, at 1.95V (8 bit bus)\n"); printf("[Max RMS Current:Max Peak Current]= %s\n", get_mmc_info(200, (saved_ext_csd[200]>>4)&0xf)); printf("=============================================\n"); /* A43: reserved [199:198] */ if (ext_csd_rev >= 5) { printf("[Partition switching timing]:\n"); printf("%d:ms\n", saved_ext_csd[199]*10); printf("[Out-of-interrupt busy timing]:\n"); printf("%d:ms\n", saved_ext_csd[198]*10); printf("=============================================\n"); } /* A441/A43: reserved [197] [195] [193] [190] [188] * [186] [184] [182] [180] [176] */ if (ext_csd_rev >= 6) { printf("[I/O Driver Strength]:\n"); printf("%s\n", get_mmc_info(197, saved_ext_csd[197])); printf("=============================================\n"); } /* DEVICE_TYPE in A45, CARD_TYPE in A441 */ ext_value = saved_ext_csd[196]; printf("[Card Type]:\n"); if (ext_value & 0x01) printf("%s\n", get_mmc_info(196, 0)); if (ext_value & 0x02) printf("%s\n", get_mmc_info(196, 1)); if (ext_value & 0x04) printf("%s\n", get_mmc_info(196, 2)); if (ext_value & 0x08) printf("%s\n", get_mmc_info(196, 3)); if (ext_value & 0x10) printf("%s\n", get_mmc_info(196, 4)); if (ext_value & 0x20) printf("%s\n", get_mmc_info(196, 5)); if (ext_value & 0x40) printf("%s\n", get_mmc_info(196, 6)); if (ext_value & 0x80) printf("%s\n", get_mmc_info(196, 7)); printf("=============================================\n"); printf("[CSD structure version]:\n"); printf("%s\n", get_mmc_info(194, saved_ext_csd[194])); /* ext_csd_rev = ext_csd[EXT_CSD_REV] (already done!!!) */ printf("=============================================\n"); printf("[Command set]:\n"); printf("0x%02x\n", saved_ext_csd[191]); printf("=============================================\n"); printf("[Command set revision]:\n"); printf("%s\n", get_mmc_info(189, saved_ext_csd[189])); printf("=============================================\n"); printf("[Power class]:\n"); printf("[Max RMS Current:Max Peak Current]= %s\n", get_mmc_info(187, saved_ext_csd[187]&0xf)); printf("=============================================\n"); printf("[High-speed interface timing]:\n"); ext_value = saved_ext_csd[185]; printf("%s\n", get_mmc_info(185, ext_value & 0xF)); printf("%s\n", get_mmc_info(185, ((ext_value >>4) & 0xF)+4)); printf("=============================================\n"); printf("[Strobe Support]:\n"); printf("%s\n", get_mmc_info(184,saved_ext_csd[184])); /* bus_width: ext_csd[183] not readable */ printf("=============================================\n"); printf("[Erased memory content]:\n"); printf("0x%02x\n", saved_ext_csd[181]); print_mmc_partition_cfg(); ext_value = saved_ext_csd[178]; printf("[Boot config protection]:\n"); if (ext_value & 0x01) printf("%s\n", get_mmc_info(178, 1)); else printf("%s\n", get_mmc_info(178, 0)); if (ext_value & 0x0E) printf("%s\n", get_mmc_info(178, 2)); if (ext_value & 0x10) printf("%s\n", get_mmc_info(178, 4)); else printf("%s\n", get_mmc_info(178, 3)); if (ext_value & 0xE0) printf("%s\n", get_mmc_info(178, 5)); printf("=============================================\n"); printf("[Boot bus Conditions]:\n"); printf("%s\n", get_mmc_info(177, saved_ext_csd[EXT_CSD_BOOT_BUS_WIDTH] & 0x3)); printf("%s\n", get_mmc_info(177, ((saved_ext_csd[EXT_CSD_BOOT_BUS_WIDTH] >> 2 ) & 0x1)+4)); printf("%s\n", get_mmc_info(177, ((saved_ext_csd[EXT_CSD_BOOT_BUS_WIDTH] >> 3) & 0x3)+6)); if (saved_ext_csd[177] & 0xE) printf("%s\n", get_mmc_info(177, 9)); printf("=============================================\n"); printf("[High-density erase group definition]:\n"); printf("%s\n", (saved_ext_csd[EXT_CSD_ERASE_GROUP_DEF])?"Enable":"Disable"); printf("=============================================\n"); printf("[Boot write protection status]:\n"); printf("%s\n", get_mmc_info(174, saved_ext_csd[EXT_CSD_BOOT_WP_STATUS] & 0x3)); printf("%s\n", get_mmc_info(174, ((saved_ext_csd[EXT_CSD_BOOT_WP_STATUS] >> 2) & 0x3) +4)); if (saved_ext_csd[174] & 0xF8) printf("%s\n", get_mmc_info(174, 8)); if (ext_csd_rev >= 5) { printf("=============================================\n"); /* A441]: reserved [172] */ ext_value = saved_ext_csd[171]; printf("[User area write protection]:"); if (ext_value & 0x01) printf("%s\n", get_mmc_info(171, 1)); else printf("%s\n", get_mmc_info(171, 0)); if (ext_value & 0x04) printf("%s\n", get_mmc_info(171, 3)); else printf("%s\n", get_mmc_info(171, 2)); if (ext_value & 0x08) printf("%s\n", get_mmc_info(171, 5)); else printf("%s\n", get_mmc_info(171, 4)); if (ext_value & 0x10) printf("%s\n", get_mmc_info(171, 7)); else printf("%s\n", get_mmc_info(171, 6)); if (ext_value & 0x40) printf("%s\n", get_mmc_info(171, 9)); else printf("%s\n", get_mmc_info(171, 8)); if (ext_value & 0x80) printf("%s\n", get_mmc_info(171, 11)); else printf("%s\n", get_mmc_info(171, 10)); /* A441]: reserved [170] */ printf("=============================================\n"); printf("[FW configuration]:\n"); printf("%s\n", (saved_ext_csd[169]&0x1)?"FW updates enabled":"FW update disabled permanently"); printf("=============================================\n"); printf("[RPMB Size]:\n"); if(saved_ext_csd[168]) printf("%d x 128Kbytes\n", (saved_ext_csd[168])); else printf("No RPMB partiiton available\n"); print_mmc_write_reliability(); /* sanitize_start ext_csd[165]]: not readable * bkops_start ext_csd[164]]: only writable */ ext_value = saved_ext_csd[163]; printf("[Enable background operations handshake]:\n"); if (ext_value & 0x01) printf("%s\n", get_mmc_info(163, 1)); else printf("%s\n", get_mmc_info(163, 0)); if (ext_value & 0x02) printf("%s\n", get_mmc_info(163, 3)); else printf("%s\n", get_mmc_info(163, 2)); printf("=============================================\n"); printf("[H/W reset function]:\n"); printf("%s\n", get_mmc_info(162, saved_ext_csd[162]&0x3)); printf("=============================================\n"); printf("HPI management]:\n"); printf("%s\n", get_mmc_info(161, saved_ext_csd[161]&0x1)); printf("=============================================\n"); ext_value = saved_ext_csd[160]; printf("[Partitioning Support]:\n"); if (ext_value & 0x01) printf("%s\n", get_mmc_info(160, 1)); else printf("%s\n", get_mmc_info(160, 0)); if (ext_value & 0x02) printf("%s\n", get_mmc_info(160, 3)); else printf("%s\n", get_mmc_info(160, 2)); if (ext_value & 0x04) printf("%s\n", get_mmc_info(160, 5)); else printf("%s\n", get_mmc_info(160, 4)); printf("=============================================\n"); ext_value = (saved_ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT_2] << 16) | (saved_ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT_1] << 8) | saved_ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT]; printf("[Max Enhanced Area Size]:\n"); printf(" i.e. %lu KiB\n", 512l * ext_value * saved_ext_csd[221] * saved_ext_csd[224]); printf("=============================================\n"); printf("[Partitions attribute]:\n"); if (ext_value & 0x01) printf("%s\n", get_mmc_info(156, 1)); else printf("%s\n", get_mmc_info(156, 0)); if (ext_value & 0x02) printf("%s\n", get_mmc_info(156, 3)); else printf("%s\n", get_mmc_info(156, 2)); if (ext_value & 0x04) printf("%s\n", get_mmc_info(156, 5)); else printf("%s\n", get_mmc_info(156, 4)); if (ext_value & 0x08) printf("%s\n", get_mmc_info(156, 7)); else printf("%s\n", get_mmc_info(156, 6)); if (ext_value & 0x10) printf("%s\n", get_mmc_info(156, 9)); else printf("%s\n", get_mmc_info(156, 8)); printf("[Partitioning Setting]:\n"); if (saved_ext_csd[EXT_CSD_PARTITION_SETTING]) printf("Device partition setting complete\n"); else printf("Device partition setting NOT complete\n"); printf("=============================================\n"); printf("[General Purpose Partition Size]:\n"); printf("[GP_SIZE_MULT_4]: 0x%06x\n", (saved_ext_csd[154] << 16) | (saved_ext_csd[153] << 8) | saved_ext_csd[152]); printf("[GP_SIZE_MULT_3]: 0x%06x\n", (saved_ext_csd[151] << 16) | (saved_ext_csd[150] << 8) | saved_ext_csd[149]); printf("[GP_SIZE_MULT_2]: 0x%06x\n", (saved_ext_csd[148] << 16) | (saved_ext_csd[147] << 8) | saved_ext_csd[146]); printf("[GP_SIZE_MULT_1]: 0x%06x\n", (saved_ext_csd[145] << 16) | (saved_ext_csd[144] << 8) | saved_ext_csd[143]); value = (saved_ext_csd[EXT_CSD_ENH_SIZE_MULT_2] << 16) | (saved_ext_csd[EXT_CSD_ENH_SIZE_MULT_1] << 8) | saved_ext_csd[EXT_CSD_ENH_SIZE_MULT]; printf("=============================================\n"); printf("[Enhanced User Data Area Size]:\n"); printf("[ENH_SIZE_MULT]: 0x%06x\n", value); printf("i.e. %lu KiB\n", 512l * value *saved_ext_csd[221] * saved_ext_csd[224]); value = (saved_ext_csd[EXT_CSD_ENH_START_ADDR_3] << 24) | (saved_ext_csd[EXT_CSD_ENH_START_ADDR_2] << 16) | (saved_ext_csd[EXT_CSD_ENH_START_ADDR_1] << 8) | saved_ext_csd[EXT_CSD_ENH_START_ADDR]; printf("=============================================\n"); printf("[Enhanced User Data Start Address]:\n"); printf(" i.e. %lu bytes offset\n", ((sectors > (2u * 1024 * 1024 * 1024) / 512) ? 512l : 1l) * value); printf("=============================================\n"); /* A441]: reserved [135] */ printf("[Bad Block Management mode]:\n"); if (saved_ext_csd[134]) printf("All data must be erased from defective " "memory array regions before they are retired from use.\n"); else printf("(Default) Feature disabled \n"); /* A441: reserved [133:0] */ } printf("=============================================\n"); /* B45 */ if (ext_csd_rev >= 6) { /* tcase_support ext_csd[132] not readable */ printf("[Periodic Wake-up}:\n"); printf("%d %s\n", saved_ext_csd[131]&0x1F, get_mmc_info(131, (saved_ext_csd[131]>>5)&0x7)); printf("=============================================\n"); printf("[Program CID/CSD in DDR mode support]:\n"); if (saved_ext_csd[130]) printf("CMD26 and CMD27 are considered legal in both single data rate and dual data rate mode.\n"); else printf("(Default) CMD26 and CMD27 must be used in single data rate mode.\n"); printf("=============================================\n"); printf("[Vendor Specific Fields]:\n"); for (i = 127; i >= 64; i--) printf("[VENDOR_SPECIFIC_FIELD[%d]]: 0x%02x\n", i, saved_ext_csd[i]); printf("=============================================\n"); printf("[Native sector size]:\n"); if (saved_ext_csd[63]) printf("Native sector size is 4KB\n"); else printf("Native sector size is 512B\n"); printf("=============================================\n"); printf("[Sector size emulation]:\n"); if (saved_ext_csd[62]) printf(":Device is using the larger than 512B native sector size\n"); else printf("Device is emulating a 512B sector size or uses a native 512B sector size\n"); printf("=============================================\n"); printf("[Sector size]:\n"); if (saved_ext_csd[61]) printf("Data sector size is 4KB\n"); else printf("Data sector size is 512B\n"); printf("=============================================\n"); printf("1st initialization after disabling sector size emulation\n"); printf("[INI_TIMEOUT_EMU]:\n"); printf("%d ms\n",saved_ext_csd[60]*100); printf("=============================================\n"); printf("[Class 6 commands control]:\n"); if (saved_ext_csd[59]) printf("Dynamic Capacity\n"); else printf("Write Protect (Default)\n"); printf("=============================================\n"); printf("[Number of addressed group to be Released]:\n"); printf("%d\n",saved_ext_csd[58]); printf("=============================================\n"); ext_value = saved_ext_csd[56]; printf("[Exception events control]:\n"); if (ext_value & 0x02) printf("%s\n", get_mmc_info(56, 1)); if (ext_value & 0x04) printf("%s\n", get_mmc_info(56, 2)); if (ext_value & 0x08) printf("%s\n", get_mmc_info(56, 3)); if (ext_value & 0x10) printf("%s\n", get_mmc_info(56, 4)); printf("=============================================\n"); ext_value = saved_ext_csd[56]; printf("[Exception events status]:\n"); if (ext_value & 0x01) printf("%s\n", get_mmc_info(54, 0)); if (ext_value & 0x02) printf("%s\n", get_mmc_info(54, 1)); if (ext_value & 0x04) printf("%s\n", get_mmc_info(54, 2)); if (ext_value & 0x08) printf("%s\n", get_mmc_info(54, 3)); if (ext_value & 0x10) printf("%s\n", get_mmc_info(54, 4)); printf("=============================================\n"); printf("[Extended Partitions Attribute]:\n"); printf("EXT1:%s\n",get_mmc_info(52,saved_ext_csd[52]&0x3)); printf("EXT2:%s\n",get_mmc_info(52,(saved_ext_csd[52] >> 4)&0x3)); printf("EXT3:%s\n",get_mmc_info(53,saved_ext_csd[53]&0x3)); printf("EXT4:%s\n",get_mmc_info(53,(saved_ext_csd[53] >> 4)&0x3)); printf("=============================================\n"); printf("[Context configuration]:\n"); for (i = 37; i <= 51; i++) { printf("=============================================\n"); printf("[ID#%d]:\n",i - 36 ,get_mmc_info(51,saved_ext_csd[i]&0x3)); printf("Activation and direction selection:\n%s\n", get_mmc_info(51,saved_ext_csd[i]&0x3)); printf("Large Unit context:%s\n", get_mmc_info(51,saved_ext_csd[i]&0x4)); printf("Large Unit multiplier:%d\n",(saved_ext_csd[i]>>3)&0x7); printf("Reliability mode:%s\n", get_mmc_info(51,(saved_ext_csd[i]>>6)&0x3)); printf("=============================================\n"); } printf("[Packed command status]:\n"); if (saved_ext_csd[36] & 0x01) printf("Error\n"); if (saved_ext_csd[36] & 0x02) printf("Indexed Error\n"); printf("=============================================\n"); printf("[Packed command failure index]:\n"); printf("%d\n",saved_ext_csd[35]); printf("=============================================\n"); printf("[Power Off Notification]:\n"); printf("%s\n", get_mmc_info(34,saved_ext_csd[34])); printf("=============================================\n"); printf("[Control to turn the Cache ON/OFF]:\n"); printf("CACHE_EN:%s\n", (saved_ext_csd[33])?"ON":"OFF"); /* flush_cache ext_csd[32] not readable */ /*Reserved [31:0] */ } printf("=============================================\n"); printf("[Barrier feature control]:\n"); printf("BARRIER_EN:%s\n", (saved_ext_csd[31])?"ON":"OFF"); printf("=============================================\n"); printf("[Mode config]:\n"); printf("%s\n", get_mmc_info(30, saved_ext_csd[30]&0x3)); printf("=============================================\n"); printf("[Mode operation codes]:\n"); if (saved_ext_csd[29] & 0x01) printf("FFU_INSTALL\n"); if (saved_ext_csd[29] & 0x02) printf("FFU_ABORT\n"); printf("=============================================\n"); printf("[FFU status]:\n"); if (!saved_ext_csd[26]) printf("Success\n"); if (saved_ext_csd[26] == 0x10) printf("General error\n"); if (saved_ext_csd[26] == 0x11) printf("Firmware install error\n"); if (saved_ext_csd[26] == 0x12) printf("Error in downloading firmware\n"); value = (saved_ext_csd[25] << 24) | (saved_ext_csd[24] << 16) | (saved_ext_csd[23] << 8) | saved_ext_csd[22]; printf("=============================================\n"); printf("[Preload data size]:\n"); printf("%d*%s\n", value,((saved_ext_csd[61])?"4KB":"512B")); value = (saved_ext_csd[21] << 24) | (saved_ext_csd[20] << 16) | (saved_ext_csd[19] << 8) | saved_ext_csd[18]; printf("=============================================\n"); printf("[Max preload data size]:\n"); printf("%d*%s\n", value,((saved_ext_csd[61])?"4KB":"512B")); printf("=============================================\n"); printf("[Product state awareness enablement]:\n"); ext_value = saved_ext_csd[17]; if (ext_value & 0x01) printf("Manual mode Supported\n"); if (ext_value & 0x02) printf("Auto mode Supported\n"); if (ext_value & 0x10) printf("Production State Awareness is enabled.\n"); else printf("Production State Awareness is disabled\n"); if (ext_value & 0x20) printf("Auto mode is enabled.\n"); else printf("Manual mode is enabled.\n"); printf("=============================================\n"); printf("[Secure removal tyupe]:\n"); ext_value = saved_ext_csd[16]; if (ext_value & 0x01) printf("information removed by an erase of the physical memory \n"); if (ext_value & 0x02) printf("information removed by an overwriting the addressed locations with a character followed\n" "by an erase\n"); if (ext_value & 0x04) printf("information removed by an overwriting the addressed locations with a character, its\n" "complement, then a random character\n"); if (ext_value & 0x08) printf("information removed using a vendor defined.\n"); printf("%s\n", get_mmc_info(16,(saved_ext_csd[16]>>3)&0x3)); printf("=============================================\n"); if (ext_csd_rev >= 7) { printf("[eMMC Firmware Version]:\n"); printf("%d\n",saved_ext_csd[254]); print_mmc_life(); } if (ext_csd_rev >= 8) { printf("[Command Queue Support]:\n"); printf(" 0x%02x\n",saved_ext_csd[EXT_CSD_CMDQ_SUPPORT]); printf("=============================================\n"); printf("[Command Queue Depth]:\n"); printf("%u\n",(saved_ext_csd[EXT_CSD_CMDQ_DEPTH] & 0x1f) + 1); printf("=============================================\n"); printf("[Command Enabled]:\n"); printf("%s\n",(saved_ext_csd[EXT_CSD_CMDQ_MODE_EN])?"ON":"OFF"); printf("=============================================\n"); } } void print_mmc_ext_info_help(void) { int i = 0; for (i= 0; i < sizeof(mmc_ext_cmd)/sizeof(mmc_ext_cmd[0]); i++) { printf("%s\n",mmc_ext_cmd[i]); } }