Skip to contentSkip to conversation

cross-compiling, SEND_STATUS, pretty-printing and enhanced user area

PATCH In review Ben Gardiner 2 participants 10 messages May 30, 2013 – Jun 27, 2013

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover cross-compiling, SEND_STATUS, pretty-printing and enhanced user area

This series builds on top of f74dfe23cd00894aa9f235374468e05acb793e17.

It introduces:
* some Makefile changes to make cross-compiling easier
* SEND_STATUS
* 'pretty'-printing sizes of some fields in KiB
* setting the OTP enhanced user area parameters

available also https://github.com/BenGardiner/mmc-utils/commits/features/enh-programming
if it helps.

Ben Gardiner (8):
allow environment and command-line supplied make vars extract definitions for EXT_CSD register EXT_CSD_PARTITIONING_SUPPORT extract definitions for EXT_CSD register PARTITION_SETTING_COMPLETED
and pretty-print
Support SEND_STATUS command
fix printing ENH_START_ADDR
report if card is block-addressed and effect on ENH_START_ADDR print KiB sizes for some fields
support setting the OTP enhanced user area parameters

 Makefile   |   10 +-
 mmc.c      |   10 ++
 mmc.h      |   20 ++++
 mmc_cmds.c |  307 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 mmc_cmds.h |    2 +
 5 files changed, 328 insertions(+), 21 deletions(-)

--
1.7.3.5

#1 lore raw

PATCH 1/8 allow environment and command-line supplied make vars

Most useful when cross-compiling.

---
 Makefile |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)
Makefile +6 -4
index f03f131..ae846e2 100644
@@ -1,12 +1,14 @@
-CC = gcc
+CC ?= gcc
 AM_CFLAGS = -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2
-CFLAGS = -g -O2
+CFLAGS ?= -g -O2
 objects = mmc.o mmc_cmds.o
 
-CHECKFLAGS= -Wall -Werror -Wuninitialized -Wundef
+CHECKFLAGS = -Wall -Werror -Wuninitialized -Wundef
 
 DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
 
+override CFLAGS := $(CHECKFLAGS) $(AM_CFLAGS) $(CFLAGS)
+
 INSTALL = install
 prefix ?= /usr/local
 bindir = $(prefix)/bin
@@ -26,7 +28,7 @@ all: $(progs) manpages
 ifdef C
 	$(check) $<
 endif
-	$(CC) $(CHECKFLAGS) $(AM_CFLAGS) $(DEPFLAGS) $(CFLAGS) -c $<
+	$(CC) $(CPPFLAGS) $(CFLAGS) $(DEPFLAGS) -c $<
 
 mmc: $(objects)
 	$(CC) $(CFLAGS) -o $@ $(objects) $(LDFLAGS) $(LIBS)
Signature · 1 line
1.7.3.5
#2 lore raw

PATCH 2/8 extract definitions for EXT_CSD register EXT_CSD_PARTITIONING_SUPPORT

In reply to Ben Gardiner
---
 mmc.h      |    3 +++
 mmc_cmds.c |    6 +++---
 2 files changed, 6 insertions(+), 3 deletions(-)
mmc.h +3 -0
index c863751..47ef8ea 100644
@@ -40,6 +40,7 @@
 #define EXT_CSD_WR_REL_PARAM		166
 #define EXT_CSD_BKOPS_EN		163	/* R/W */
 #define EXT_CSD_RST_N_FUNCTION		162	/* R/W */
+#define EXT_CSD_PARTITIONING_SUPPORT	160	/* RO */
 #define EXT_CSD_NATIVE_SECTOR_SIZE	63 /* R */
 #define EXT_CSD_USE_NATIVE_SECTOR	62 /* R/W */
 #define EXT_CSD_DATA_SECTOR_SIZE	61 /* R */
@@ -79,6 +80,8 @@
 #define EXT_CSD_PART_CONFIG_ACC_BOOT1	  (0x2)
 #define EXT_CSD_PART_CONFIG_ACC_USER_AREA (0x7)
 #define EXT_CSD_PART_CONFIG_ACC_ACK	  (0x40)
+#define EXT_CSD_PARTITIONING_EN		(1<<0)
+#define EXT_CSD_ENH_ATTRIBUTE_EN	(1<<1)
 
 /* From kernel linux/mmc/core.h */
 #define MMC_RSP_PRESENT	(1 << 0)
mmc_cmds.c +3 -3
index b407f65..8cf6e89 100644
@@ -670,14 +670,14 @@ int do_read_extcsd(int nargs, char **argv)
 		printf("H/W reset function"
 			" [RST_N_FUNCTION]: 0x%02x\n", ext_csd[162]);
 		printf("HPI management [HPI_MGMT]: 0x%02x\n", ext_csd[161]);
-		reg = ext_csd[160];
+		reg = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
 		printf("Partitioning Support [PARTITIONING_SUPPORT]: 0x%02x\n",
 			reg);
-		if (reg & 0x1)
+		if (reg & EXT_CSD_PARTITIONING_EN)
 			printf(" Device support partitioning feature\n");
 		else
 			printf(" Device NOT support partitioning feature\n");
-		if (reg & 0x2)
+		if (reg & EXT_CSD_ENH_ATTRIBUTE_EN)
 			printf(" Device can have enhanced tech.\n");
 		else
 			printf(" Device cannot have enhanced tech.\n");
Signature · 1 line
1.7.3.5
#3 lore raw

PATCH 3/8 extract definitions for EXT_CSD register PARTITION_SETTING_COMPLETED and pretty-print

In reply to Ben Gardiner
---
 mmc.h      |    1 +
 mmc_cmds.c |    8 +++++++-
 2 files changed, 8 insertions(+), 1 deletions(-)
mmc.h +1 -0
index 47ef8ea..3420d7b 100644
@@ -41,6 +41,7 @@
 #define EXT_CSD_BKOPS_EN		163	/* R/W */
 #define EXT_CSD_RST_N_FUNCTION		162	/* R/W */
 #define EXT_CSD_PARTITIONING_SUPPORT	160	/* RO */
+#define EXT_CSD_PARTITION_SETTING_COMPLETED	155	/* R/W */
 #define EXT_CSD_NATIVE_SECTOR_SIZE	63 /* R */
 #define EXT_CSD_USE_NATIVE_SECTOR	62 /* R/W */
 #define EXT_CSD_DATA_SECTOR_SIZE	61 /* R */
mmc_cmds.c +7 -1
index 8cf6e89..dd7498e 100644
@@ -687,9 +687,15 @@ int do_read_extcsd(int nargs, char **argv)
 			    ext_csd[157]);
 		printf("Partitions attribute [PARTITIONS_ATTRIBUTE]: 0x%02x\n",
 			ext_csd[156]);
+		reg = ext_csd[EXT_CSD_PARTITION_SETTING_COMPLETED];
 		printf("Partitioning Setting"
 			" [PARTITION_SETTING_COMPLETED]: 0x%02x\n",
-			ext_csd[155]);
+			reg);
+		if(reg)
+			printf(" Device partition setting complete\n");
+		else
+			printf(" Device partition setting NOT complete\n");
+
 		printf("General Purpose Partition Size\n"
 			" [GP_SIZE_MULT_4]: 0x%06x\n", (ext_csd[154] << 16) |
 			(ext_csd[153] << 8) | ext_csd[152]);
Signature · 1 line
1.7.3.5
#4 lore raw

PATCH 4/8 Support SEND_STATUS command

In reply to Ben Gardiner

mmc status get </path/to/mmcblkX>

---
 mmc.c      |    5 +++++
 mmc.h      |    2 ++
 mmc_cmds.c |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 mmc_cmds.h |    1 +
 4 files changed, 55 insertions(+), 0 deletions(-)
mmc.c +5 -0
index a2de863..c22ce9e 100644
@@ -70,6 +70,11 @@ static struct Command commands[] = {
 		"Set the eMMC data sector size to 4KB by disabling emulation on\n<device>.",
 	  NULL
 	},
+	{ do_status_get, -1,
+	  "status get", "<device>\n"
+	  "Print the response to STATUS_SEND (CMD13).",
+	  NULL
+	},
 	{ do_write_boot_en, -3,
 	  "bootpart enable", "<boot_partition> " "<send_ack> " "<device>\n"
 		"Enable the boot partition for the <device>.\nTo receive acknowledgment of boot from the card set <send_ack>\nto 1, else set it to 0.",
mmc.h +2 -0
index 3420d7b..3577f42 100644
@@ -24,6 +24,8 @@
 /* From kernel linux/mmc/mmc.h */
 #define MMC_SWITCH		6	/* ac	[31:0] See below	R1b */
 #define MMC_SEND_EXT_CSD	8	/* adtc				R1  */
+#define MMC_SEND_STATUS		13	/* ac   [31:16] RCA        R1  */
+#define R1_SWITCH_ERROR   (1 << 7)  /* sx, c */
 #define MMC_SWITCH_MODE_WRITE_BYTE	0x03	/* Set target to value */
 
 /*
mmc_cmds.c +47 -0

59 lines not on this page · raw message

mmc_cmds.h +1 -0
index e52d622..3a754bf 100644
@@ -24,3 +24,4 @@ int do_write_boot_en(int nargs, char **argv);
 int do_write_bkops_en(int nargs, char **argv);
 int do_hwreset_en(int nargs, char **argv);
 int do_hwreset_dis(int nargs, char **argv);
+int do_status_get(int nargs, char **argv);
Signature · 1 line
1.7.3.5
#5 lore raw

PATCH 5/8 fix printing ENH_START_ADDR

In reply to Ben Gardiner

The enhanced user area start field is 4 bytes long according to the eMMC 4.41 spec.

---
 mmc.h      |    4 ++++
 mmc_cmds.c |    8 ++++++--
 2 files changed, 10 insertions(+), 2 deletions(-)
mmc.h +4 -0
index 3577f42..fa46c3a 100644
@@ -44,6 +44,10 @@
 #define EXT_CSD_RST_N_FUNCTION		162	/* R/W */
 #define EXT_CSD_PARTITIONING_SUPPORT	160	/* RO */
 #define EXT_CSD_PARTITION_SETTING_COMPLETED	155	/* R/W */
+#define EXT_CSD_ENH_START_ADDR_3	139
+#define EXT_CSD_ENH_START_ADDR_2	138
+#define EXT_CSD_ENH_START_ADDR_1	137
+#define EXT_CSD_ENH_START_ADDR_0	136
 #define EXT_CSD_NATIVE_SECTOR_SIZE	63 /* R */
 #define EXT_CSD_USE_NATIVE_SECTOR	62 /* R/W */
 #define EXT_CSD_DATA_SECTOR_SIZE	61 /* R */
mmc_cmds.c +6 -2
index a2ccc1d..21d5b4f 100644
@@ -756,9 +756,13 @@ int do_read_extcsd(int nargs, char **argv)
 		printf("Enhanced User Data Area Size"
 			" [ENH_SIZE_MULT]: 0x%06x\n", (ext_csd[142] << 16) |
 			(ext_csd[141] << 8) | ext_csd[140]);
+
+		reg =	(ext_csd[EXT_CSD_ENH_START_ADDR_3] << 24) |
+			(ext_csd[EXT_CSD_ENH_START_ADDR_2] << 16) |
+			(ext_csd[EXT_CSD_ENH_START_ADDR_1] << 8) |
+			ext_csd[EXT_CSD_ENH_START_ADDR_0];
 		printf("Enhanced User Data Start Address"
-			" [ENH_START_ADDR]: 0x%06x\n", (ext_csd[139] << 16) |
-			   (ext_csd[138] << 8) | ext_csd[137]);
+			" [ENH_START_ADDR]: 0x%06x\n", reg);
 
 		/* A441]: reserved [135] */
 		printf("Bad Block Management mode"
Signature · 1 line
1.7.3.5
#6 lore raw

PATCH 6/8 report if card is block-addressed and effect on ENH_START_ADDR

In reply to Ben Gardiner
---
 mmc.h      |    4 ++++
 mmc_cmds.c |   28 +++++++++++++++++++++++++---
 2 files changed, 29 insertions(+), 3 deletions(-)
mmc.h +4 -0
index fa46c3a..bedde31 100644
@@ -35,6 +35,10 @@
 #define EXT_CSD_HPI_FEATURE		503
 #define EXT_CSD_BKOPS_SUPPORT		502	/* RO */
 #define EXT_CSD_BOOT_INFO		228	/* R/W */
+#define EXT_CSD_SEC_COUNT_3		215
+#define EXT_CSD_SEC_COUNT_2		214
+#define EXT_CSD_SEC_COUNT_1		213
+#define EXT_CSD_SEC_COUNT_0		212
 #define EXT_CSD_PART_SWITCH_TIME	199
 #define EXT_CSD_BOOT_CFG		179
 #define EXT_CSD_PART_CONFIG		179
mmc_cmds.c +25 -3
index 21d5b4f..149c904 100644
@@ -424,6 +424,21 @@ int do_status_get(int nargs, char **argv)
 	return ret;
 }
 
+unsigned int get_sector_count(__u8 *ext_csd)
+{
+	return (ext_csd[EXT_CSD_SEC_COUNT_3] << 24) |
+	(ext_csd[EXT_CSD_SEC_COUNT_2] << 16) |
+	(ext_csd[EXT_CSD_SEC_COUNT_1] << 8)  |
+	ext_csd[EXT_CSD_SEC_COUNT_0];
+}
+
+int is_blockaddresed(__u8 *ext_csd)
+{
+	unsigned int sectors = get_sector_count(ext_csd);
+
+	return (sectors > (2u * 1024 * 1024 * 1024) / 512);
+}
+
 int do_read_extcsd(int nargs, char **argv)
 {
 	__u8 ext_csd[512], ext_csd_rev, reg;
@@ -591,9 +606,14 @@ int do_read_extcsd(int nargs, char **argv)
 	/* A441/A43: reserved [218] */
 	printf("Sleep/awake timeout [S_A_TIMEOUT: 0x%02x]\n", ext_csd[217]);
 	/* A441/A43: reserved [216] */
-	printf("Sector Count [SEC_COUNT: 0x%08x]\n", (ext_csd[215] << 24) |
-		      (ext_csd[214] << 16) | (ext_csd[213] << 8)  |
-		      ext_csd[212]);
+
+	unsigned int sectors =	get_sector_count(ext_csd);
+	printf("Sector Count [SEC_COUNT: 0x%08x]\n", sectors);
+	if (is_blockaddresed(ext_csd))
+		printf(" Device is block-addressed\n");
+	else
+		printf(" Device is NOT block-addressed\n");
+
 	/* A441/A43: reserved [211] */
 	printf("Minimum Write Performance for 8bit:\n");
 	printf(" [MIN_PERF_W_8_52: 0x%02x]\n", ext_csd[210]);
@@ -763,6 +783,8 @@ int do_read_extcsd(int nargs, char **argv)
 			ext_csd[EXT_CSD_ENH_START_ADDR_0];
 		printf("Enhanced User Data Start Address"
 			" [ENH_START_ADDR]: 0x%06x\n", reg);
+		printf(" i.e. %lu bytes offset\n", (is_blockaddresed(ext_csd) ?
+				1l : 512l) * reg);
 
 		/* A441]: reserved [135] */
 		printf("Bad Block Management mode"
Signature · 1 line
1.7.3.5
#7 lore raw

PATCH 7/8 print KiB sizes for some fields

In reply to Ben Gardiner
---
 mmc.h      |    3 +++
 mmc_cmds.c |   40 ++++++++++++++++++++++++++++++++++------
 2 files changed, 37 insertions(+), 6 deletions(-)
mmc.h +3 -0
index bedde31..5385e0e 100644
@@ -48,6 +48,9 @@
 #define EXT_CSD_RST_N_FUNCTION		162	/* R/W */
 #define EXT_CSD_PARTITIONING_SUPPORT	160	/* RO */
 #define EXT_CSD_PARTITION_SETTING_COMPLETED	155	/* R/W */
+#define EXT_CSD_ENH_SIZE_MULT_2		142
+#define EXT_CSD_ENH_SIZE_MULT_1		141
+#define EXT_CSD_ENH_SIZE_MULT_0		140
 #define EXT_CSD_ENH_START_ADDR_3	139
 #define EXT_CSD_ENH_START_ADDR_2	138
 #define EXT_CSD_ENH_START_ADDR_1	137
mmc_cmds.c +34 -6
index 149c904..37bb211 100644
@@ -439,6 +439,16 @@ int is_blockaddresed(__u8 *ext_csd)
 	return (sectors > (2u * 1024 * 1024 * 1024) / 512);
 }
 
+unsigned int get_hc_wp_grp_size(__u8 *ext_csd)
+{
+	return ext_csd[221];
+}
+
+unsigned int get_hc_erase_grp_size(__u8 *ext_csd)
+{
+	return ext_csd[224];
+}
+
 int do_read_extcsd(int nargs, char **argv)
 {
 	__u8 ext_csd[512], ext_csd_rev, reg;
@@ -593,14 +603,22 @@ int do_read_extcsd(int nargs, char **argv)
 	/* A441/A43: reserved [227] */
 	printf("Boot partition size [BOOT_SIZE_MULTI: 0x%02x]\n", ext_csd[226]);
 	printf("Access size [ACC_SIZE: 0x%02x]\n", ext_csd[225]);
+
+	reg = get_hc_erase_grp_size(ext_csd);
 	printf("High-capacity erase unit size [HC_ERASE_GRP_SIZE: 0x%02x]\n",
-		ext_csd[224]);
+		reg);
+	printf(" i.e. %u KiB\n", 512 * reg);
+
 	printf("High-capacity erase timeout [ERASE_TIMEOUT_MULT: 0x%02x]\n",
 		ext_csd[223]);
 	printf("Reliable write sector count [REL_WR_SEC_C: 0x%02x]\n",
 		ext_csd[222]);
+
+	reg = get_hc_wp_grp_size(ext_csd);
 	printf("High-capacity W protect group size [HC_WP_GRP_SIZE: 0x%02x]\n",
-		ext_csd[221]);
+		reg);
+	printf(" i.e. %lu KiB\n", 512l * get_hc_erase_grp_size(ext_csd) * reg);
+
 	printf("Sleep current (VCC) [S_C_VCC: 0x%02x]\n", ext_csd[220]);
 	printf("Sleep current (VCCQ) [S_C_VCCQ: 0x%02x]\n", ext_csd[219]);
 	/* A441/A43: reserved [218] */
@@ -749,9 +767,14 @@ int do_read_extcsd(int nargs, char **argv)
 		else
 			printf(" Device cannot have enhanced tech.\n");
 
+		reg = (ext_csd[159] << 16) | (ext_csd[158] << 8) |
+			ext_csd[157];
 		printf("Max Enhanced Area Size [MAX_ENH_SIZE_MULT]: 0x%06x\n",
-			   (ext_csd[159] << 16) | (ext_csd[158] << 8) |
-			    ext_csd[157]);
+			   reg);
+		unsigned int wp_sz = get_hc_wp_grp_size(ext_csd);
+		unsigned int erase_sz = get_hc_erase_grp_size(ext_csd);
+		printf(" i.e. %lu KiB\n", 512l * reg * wp_sz * erase_sz);
+
 		printf("Partitions attribute [PARTITIONS_ATTRIBUTE]: 0x%02x\n",
 			ext_csd[156]);
 		reg = ext_csd[EXT_CSD_PARTITION_SETTING_COMPLETED];
@@ -773,9 +796,14 @@ int do_read_extcsd(int nargs, char **argv)
 		printf(" [GP_SIZE_MULT_1]: 0x%06x\n", (ext_csd[145] << 16) |
 			   (ext_csd[144] << 8) | ext_csd[143]);
 
+		reg =	(ext_csd[EXT_CSD_ENH_SIZE_MULT_2] << 16) |
+			(ext_csd[EXT_CSD_ENH_SIZE_MULT_1] << 8) |
+			ext_csd[EXT_CSD_ENH_SIZE_MULT_0];
 		printf("Enhanced User Data Area Size"
-			" [ENH_SIZE_MULT]: 0x%06x\n", (ext_csd[142] << 16) |
-			(ext_csd[141] << 8) | ext_csd[140]);
+			" [ENH_SIZE_MULT]: 0x%06x\n", reg);
+		printf(" i.e. %lu KiB\n", 512l * reg *
+		       get_hc_erase_grp_size(ext_csd) *
+		       get_hc_wp_grp_size(ext_csd));
 
 		reg =	(ext_csd[EXT_CSD_ENH_START_ADDR_3] << 24) |
 			(ext_csd[EXT_CSD_ENH_START_ADDR_2] << 16) |
Signature · 1 line
1.7.3.5
#8 lore raw

PATCH 8/8 support setting the OTP enhanced user area parameters

In reply to Ben Gardiner
---
 mmc.c      |    5 ++
 mmc.h      |    3 +
 mmc_cmds.c |  170 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 mmc_cmds.h |    1 +
 4 files changed, 177 insertions(+), 2 deletions(-)
mmc.c +5 -0
index c22ce9e..30e3ce0 100644
@@ -70,6 +70,11 @@ static struct Command commands[] = {
 		"Set the eMMC data sector size to 4KB by disabling emulation on\n<device>.",
 	  NULL
 	},
+	{ do_enh_area_set, -4,
+	  "enh_area set", "<-y|-n> " "<start KiB> " "<length KiB> " "<device>\n"
+		"Enable the enhanced user area for the <device>. Dry-run only unless -y is passed.",
+	  NULL
+	},
 	{ do_status_get, -1,
 	  "status get", "<device>\n"
 	  "Print the response to STATUS_SEND (CMD13).",
mmc.h +3 -0
index 5385e0e..f16bd89 100644
@@ -42,11 +42,13 @@
 #define EXT_CSD_PART_SWITCH_TIME	199
 #define EXT_CSD_BOOT_CFG		179
 #define EXT_CSD_PART_CONFIG		179
+#define EXT_CSD_ERASE_GROUP_DEF		175
 #define EXT_CSD_BOOT_WP			173
 #define EXT_CSD_WR_REL_PARAM		166
 #define EXT_CSD_BKOPS_EN		163	/* R/W */
 #define EXT_CSD_RST_N_FUNCTION		162	/* R/W */
 #define EXT_CSD_PARTITIONING_SUPPORT	160	/* RO */
+#define EXT_CSD_PARTITIONS_ATTRIBUTE	156	/* R/W */
 #define EXT_CSD_PARTITION_SETTING_COMPLETED	155	/* R/W */
 #define EXT_CSD_ENH_SIZE_MULT_2		142
 #define EXT_CSD_ENH_SIZE_MULT_1		141
@@ -96,6 +98,7 @@
 #define EXT_CSD_PART_CONFIG_ACC_ACK	  (0x40)
 #define EXT_CSD_PARTITIONING_EN		(1<<0)
 #define EXT_CSD_ENH_ATTRIBUTE_EN	(1<<1)
+#define EXT_CSD_ENH_USR		(1<<0)
 
 /* From kernel linux/mmc/core.h */
 #define MMC_RSP_PRESENT	(1 << 0)
mmc_cmds.c +168 -2

188 lines not on this page · raw message

mmc_cmds.h +1 -0
index 3a754bf..bb1a9ca 100644
@@ -25,3 +25,4 @@ int do_write_bkops_en(int nargs, char **argv);
 int do_hwreset_en(int nargs, char **argv);
 int do_hwreset_dis(int nargs, char **argv);
 int do_status_get(int nargs, char **argv);
+int do_enh_area_set(int nargs, char **argv);
Signature · 1 line
1.7.3.5
#9 lore raw
In reply to Ben Gardiner

Hi Ben,

Quoted 7 lines · Ben Gardiner

This series builds on top of f74dfe23cd00894aa9f235374468e05acb793e17.

It introduces:
* some Makefile changes to make cross-compiling easier
* SEND_STATUS
* 'pretty'-printing sizes of some fields in KiB
* setting the OTP enhanced user area parameters

Thanks for doing this! I've pushed the whole patchset to mmc-utils, after adding an extra warning about the OTP fuse in the usage message.

- Chris.

Signature · 2 lines
Chris Ball   <[email protected]>   <http://printf.net/>
One Laptop Per Child