Commit 638b3e8342e4b395f9e961bfac200420f29874a3

Authored by Tom Rini

Merge branch 'master' of git://git.denx.de/u-boot-mmc

Showing 19 changed files Side-by-side Diff

... ... @@ -1534,6 +1534,16 @@
1534 1534 CONFIG_SH_MMCIF_CLK
1535 1535 Define the clock frequency for MMCIF
1536 1536  
  1537 + CONFIG_GENERIC_MMC
  1538 + Enable the generic MMC driver
  1539 +
  1540 + CONFIG_SUPPORT_EMMC_BOOT
  1541 + Enable some additional features of the eMMC boot partitions.
  1542 +
  1543 + CONFIG_SUPPORT_EMMC_RPMB
  1544 + Enable the commands for reading, writing and programming the
  1545 + key for the Replay Protection Memory Block partition in eMMC.
  1546 +
1537 1547 - USB Device Firmware Update (DFU) class support:
1538 1548 CONFIG_DFU_FUNCTION
1539 1549 This enables the USB portion of the DFU USB class
board/BuR/common/common.c
... ... @@ -19,6 +19,7 @@
19 19 #include <asm/arch/clock.h>
20 20 #include <asm/arch/gpio.h>
21 21 #include <asm/arch/sys_proto.h>
  22 +#include <asm/arch/mmc_host_def.h>
22 23 #include <asm/io.h>
23 24 #include <asm/gpio.h>
24 25 #include <i2c.h>
... ... @@ -214,4 +215,10 @@
214 215 return rv;
215 216 }
216 217 #endif /* CONFIG_DRIVER_TI_CPSW */
  218 +#if defined(CONFIG_GENERIC_MMC) && !defined(CONFIG_SPL_BUILD)
  219 +int board_mmc_init(bd_t *bis)
  220 +{
  221 + return omap_mmc_init(1, 0, 0, -1, -1);
  222 +}
  223 +#endif
... ... @@ -33,15 +33,8 @@
33 33 "what you are doing!\n"
34 34 "\nReally perform this fuse programming? <y/N>\n");
35 35  
36   - if (getc() == 'y') {
37   - int c;
38   -
39   - putc('y');
40   - c = getc();
41   - putc('\n');
42   - if (c == '\r')
43   - return 1;
44   - }
  36 + if (confirm_yesno())
  37 + return 1;
45 38  
46 39 puts("Fuse programming aborted\n");
47 40 return 0;
... ... @@ -71,12 +71,6 @@
71 71 );
72 72 #else /* !CONFIG_GENERIC_MMC */
73 73  
74   -enum mmc_state {
75   - MMC_INVALID,
76   - MMC_READ,
77   - MMC_WRITE,
78   - MMC_ERASE,
79   -};
80 74 static void print_mmcinfo(struct mmc *mmc)
81 75 {
82 76 printf("Device: %s\n", mmc->cfg->name);
... ... @@ -98,7 +92,18 @@
98 92  
99 93 printf("Bus Width: %d-bit\n", mmc->bus_width);
100 94 }
101   -
  95 +static struct mmc *init_mmc_device(int dev)
  96 +{
  97 + struct mmc *mmc;
  98 + mmc = find_mmc_device(dev);
  99 + if (!mmc) {
  100 + printf("no mmc device at slot %x\n", dev);
  101 + return NULL;
  102 + }
  103 + if (mmc_init(mmc))
  104 + return NULL;
  105 + return mmc;
  106 +}
102 107 static int do_mmcinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
103 108 {
104 109 struct mmc *mmc;
105 110  
106 111  
107 112  
108 113  
109 114  
110 115  
111 116  
112 117  
113 118  
114 119  
115 120  
116 121  
117 122  
118 123  
119 124  
120 125  
121 126  
122 127  
123 128  
124 129  
125 130  
126 131  
127 132  
128 133  
129 134  
130 135  
131 136  
132 137  
133 138  
134 139  
135 140  
136 141  
137 142  
138 143  
139 144  
140 145  
141 146  
142 147  
143 148  
144 149  
145 150  
146 151  
147 152  
148 153  
149 154  
150 155  
151 156  
152 157  
153 158  
154 159  
155 160  
156 161  
157 162  
158 163  
159 164  
160 165  
161 166  
162 167  
163 168  
164 169  
... ... @@ -112,351 +117,537 @@
112 117 }
113 118 }
114 119  
115   - mmc = find_mmc_device(curr_device);
  120 + mmc = init_mmc_device(curr_device);
  121 + if (!mmc)
  122 + return CMD_RET_FAILURE;
116 123  
117   - if (mmc) {
118   - mmc_init(mmc);
  124 + print_mmcinfo(mmc);
  125 + return CMD_RET_SUCCESS;
  126 +}
119 127  
120   - print_mmcinfo(mmc);
121   - return 0;
122   - } else {
123   - printf("no mmc device at slot %x\n", curr_device);
  128 +#ifdef CONFIG_SUPPORT_EMMC_RPMB
  129 +static int confirm_key_prog(void)
  130 +{
  131 + puts("Warning: Programming authentication key can be done only once !\n"
  132 + " Use this command only if you are sure of what you are doing,\n"
  133 + "Really perform the key programming? <y/N> ");
  134 + if (confirm_yesno())
124 135 return 1;
  136 +
  137 + puts("Authentication key programming aborted\n");
  138 + return 0;
  139 +}
  140 +static int do_mmcrpmb_key(cmd_tbl_t *cmdtp, int flag,
  141 + int argc, char * const argv[])
  142 +{
  143 + void *key_addr;
  144 + struct mmc *mmc = find_mmc_device(curr_device);
  145 +
  146 + if (argc != 2)
  147 + return CMD_RET_USAGE;
  148 +
  149 + key_addr = (void *)simple_strtoul(argv[1], NULL, 16);
  150 + if (!confirm_key_prog())
  151 + return CMD_RET_FAILURE;
  152 + if (mmc_rpmb_set_key(mmc, key_addr)) {
  153 + printf("ERROR - Key already programmed ?\n");
  154 + return CMD_RET_FAILURE;
125 155 }
  156 + return CMD_RET_SUCCESS;
126 157 }
  158 +static int do_mmcrpmb_read(cmd_tbl_t *cmdtp, int flag,
  159 + int argc, char * const argv[])
  160 +{
  161 + u16 blk, cnt;
  162 + void *addr;
  163 + int n;
  164 + void *key_addr = NULL;
  165 + struct mmc *mmc = find_mmc_device(curr_device);
127 166  
128   -U_BOOT_CMD(
129   - mmcinfo, 1, 0, do_mmcinfo,
130   - "display MMC info",
131   - "- display info of the current MMC device"
132   -);
  167 + if (argc < 4)
  168 + return CMD_RET_USAGE;
133 169  
134   -static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  170 + addr = (void *)simple_strtoul(argv[1], NULL, 16);
  171 + blk = simple_strtoul(argv[2], NULL, 16);
  172 + cnt = simple_strtoul(argv[3], NULL, 16);
  173 +
  174 + if (argc == 5)
  175 + key_addr = (void *)simple_strtoul(argv[4], NULL, 16);
  176 +
  177 + printf("\nMMC RPMB read: dev # %d, block # %d, count %d ... ",
  178 + curr_device, blk, cnt);
  179 + n = mmc_rpmb_read(mmc, addr, blk, cnt, key_addr);
  180 +
  181 + printf("%d RPMB blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR");
  182 + if (n != cnt)
  183 + return CMD_RET_FAILURE;
  184 + return CMD_RET_SUCCESS;
  185 +}
  186 +static int do_mmcrpmb_write(cmd_tbl_t *cmdtp, int flag,
  187 + int argc, char * const argv[])
135 188 {
136   - enum mmc_state state;
  189 + u16 blk, cnt;
  190 + void *addr;
  191 + int n;
  192 + void *key_addr;
  193 + struct mmc *mmc = find_mmc_device(curr_device);
137 194  
138   - if (argc < 2)
  195 + if (argc != 5)
139 196 return CMD_RET_USAGE;
140 197  
141   - if (curr_device < 0) {
142   - if (get_mmc_num() > 0)
143   - curr_device = 0;
144   - else {
145   - puts("No MMC device available\n");
146   - return 1;
147   - }
  198 + addr = (void *)simple_strtoul(argv[1], NULL, 16);
  199 + blk = simple_strtoul(argv[2], NULL, 16);
  200 + cnt = simple_strtoul(argv[3], NULL, 16);
  201 + key_addr = (void *)simple_strtoul(argv[4], NULL, 16);
  202 +
  203 + printf("\nMMC RPMB write: dev # %d, block # %d, count %d ... ",
  204 + curr_device, blk, cnt);
  205 + n = mmc_rpmb_write(mmc, addr, blk, cnt, key_addr);
  206 +
  207 + printf("%d RPMB blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR");
  208 + if (n != cnt)
  209 + return CMD_RET_FAILURE;
  210 + return CMD_RET_SUCCESS;
  211 +}
  212 +static int do_mmcrpmb_counter(cmd_tbl_t *cmdtp, int flag,
  213 + int argc, char * const argv[])
  214 +{
  215 + unsigned long counter;
  216 + struct mmc *mmc = find_mmc_device(curr_device);
  217 +
  218 + if (mmc_rpmb_get_counter(mmc, &counter))
  219 + return CMD_RET_FAILURE;
  220 + printf("RPMB Write counter= %lx\n", counter);
  221 + return CMD_RET_SUCCESS;
  222 +}
  223 +
  224 +static cmd_tbl_t cmd_rpmb[] = {
  225 + U_BOOT_CMD_MKENT(key, 2, 0, do_mmcrpmb_key, "", ""),
  226 + U_BOOT_CMD_MKENT(read, 5, 1, do_mmcrpmb_read, "", ""),
  227 + U_BOOT_CMD_MKENT(write, 5, 0, do_mmcrpmb_write, "", ""),
  228 + U_BOOT_CMD_MKENT(counter, 1, 1, do_mmcrpmb_counter, "", ""),
  229 +};
  230 +
  231 +static int do_mmcrpmb(cmd_tbl_t *cmdtp, int flag,
  232 + int argc, char * const argv[])
  233 +{
  234 + cmd_tbl_t *cp;
  235 + struct mmc *mmc;
  236 + char original_part;
  237 + int ret;
  238 +
  239 + cp = find_cmd_tbl(argv[1], cmd_rpmb, ARRAY_SIZE(cmd_rpmb));
  240 +
  241 + /* Drop the rpmb subcommand */
  242 + argc--;
  243 + argv++;
  244 +
  245 + if (cp == NULL || argc > cp->maxargs)
  246 + return CMD_RET_USAGE;
  247 + if (flag == CMD_FLAG_REPEAT && !cp->repeatable)
  248 + return CMD_RET_SUCCESS;
  249 +
  250 + mmc = init_mmc_device(curr_device);
  251 + if (!mmc)
  252 + return CMD_RET_FAILURE;
  253 +
  254 + if (!(mmc->version & MMC_VERSION_MMC)) {
  255 + printf("It is not a EMMC device\n");
  256 + return CMD_RET_FAILURE;
148 257 }
  258 + if (mmc->version < MMC_VERSION_4_41) {
  259 + printf("RPMB not supported before version 4.41\n");
  260 + return CMD_RET_FAILURE;
  261 + }
  262 + /* Switch to the RPMB partition */
  263 + original_part = mmc->part_num;
  264 + if (mmc->part_num != MMC_PART_RPMB) {
  265 + if (mmc_switch_part(curr_device, MMC_PART_RPMB) != 0)
  266 + return CMD_RET_FAILURE;
  267 + mmc->part_num = MMC_PART_RPMB;
  268 + }
  269 + ret = cp->cmd(cmdtp, flag, argc, argv);
149 270  
150   - if (strcmp(argv[1], "rescan") == 0) {
151   - struct mmc *mmc;
  271 + /* Return to original partition */
  272 + if (mmc->part_num != original_part) {
  273 + if (mmc_switch_part(curr_device, original_part) != 0)
  274 + return CMD_RET_FAILURE;
  275 + mmc->part_num = original_part;
  276 + }
  277 + return ret;
  278 +}
  279 +#endif
152 280  
153   - if (argc != 2)
154   - return CMD_RET_USAGE;
  281 +static int do_mmc_read(cmd_tbl_t *cmdtp, int flag,
  282 + int argc, char * const argv[])
  283 +{
  284 + struct mmc *mmc;
  285 + u32 blk, cnt, n;
  286 + void *addr;
155 287  
156   - mmc = find_mmc_device(curr_device);
157   - if (!mmc) {
158   - printf("no mmc device at slot %x\n", curr_device);
159   - return 1;
160   - }
  288 + if (argc != 4)
  289 + return CMD_RET_USAGE;
161 290  
162   - mmc->has_init = 0;
  291 + addr = (void *)simple_strtoul(argv[1], NULL, 16);
  292 + blk = simple_strtoul(argv[2], NULL, 16);
  293 + cnt = simple_strtoul(argv[3], NULL, 16);
163 294  
164   - if (mmc_init(mmc))
165   - return 1;
166   - else
167   - return 0;
168   - } else if (strcmp(argv[1], "part") == 0) {
169   - block_dev_desc_t *mmc_dev;
170   - struct mmc *mmc;
  295 + mmc = init_mmc_device(curr_device);
  296 + if (!mmc)
  297 + return CMD_RET_FAILURE;
171 298  
172   - if (argc != 2)
173   - return CMD_RET_USAGE;
  299 + printf("\nMMC read: dev # %d, block # %d, count %d ... ",
  300 + curr_device, blk, cnt);
174 301  
175   - mmc = find_mmc_device(curr_device);
176   - if (!mmc) {
177   - printf("no mmc device at slot %x\n", curr_device);
178   - return 1;
179   - }
180   - mmc_init(mmc);
181   - mmc_dev = mmc_get_dev(curr_device);
182   - if (mmc_dev != NULL &&
183   - mmc_dev->type != DEV_TYPE_UNKNOWN) {
184   - print_part(mmc_dev);
185   - return 0;
186   - }
  302 + n = mmc->block_dev.block_read(curr_device, blk, cnt, addr);
  303 + /* flush cache after read */
  304 + flush_cache((ulong)addr, cnt * 512); /* FIXME */
  305 + printf("%d blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR");
187 306  
188   - puts("get mmc type error!\n");
189   - return 1;
190   - } else if (strcmp(argv[1], "list") == 0) {
191   - if (argc != 2)
192   - return CMD_RET_USAGE;
193   - print_mmc_devices('\n');
194   - return 0;
195   - } else if (strcmp(argv[1], "dev") == 0) {
196   - int dev, part = -1;
197   - struct mmc *mmc;
  307 + return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
  308 +}
  309 +static int do_mmc_write(cmd_tbl_t *cmdtp, int flag,
  310 + int argc, char * const argv[])
  311 +{
  312 + struct mmc *mmc;
  313 + u32 blk, cnt, n;
  314 + void *addr;
198 315  
199   - if (argc == 2)
200   - dev = curr_device;
201   - else if (argc == 3)
202   - dev = simple_strtoul(argv[2], NULL, 10);
203   - else if (argc == 4) {
204   - dev = (int)simple_strtoul(argv[2], NULL, 10);
205   - part = (int)simple_strtoul(argv[3], NULL, 10);
206   - if (part > PART_ACCESS_MASK) {
207   - printf("#part_num shouldn't be larger"
208   - " than %d\n", PART_ACCESS_MASK);
209   - return 1;
210   - }
211   - } else
212   - return CMD_RET_USAGE;
  316 + if (argc != 4)
  317 + return CMD_RET_USAGE;
213 318  
214   - mmc = find_mmc_device(dev);
215   - if (!mmc) {
216   - printf("no mmc device at slot %x\n", dev);
217   - return 1;
218   - }
  319 + addr = (void *)simple_strtoul(argv[1], NULL, 16);
  320 + blk = simple_strtoul(argv[2], NULL, 16);
  321 + cnt = simple_strtoul(argv[3], NULL, 16);
219 322  
220   - mmc_init(mmc);
221   - if (part != -1) {
222   - int ret;
223   - if (mmc->part_config == MMCPART_NOAVAILABLE) {
224   - printf("Card doesn't support part_switch\n");
225   - return 1;
226   - }
  323 + mmc = init_mmc_device(curr_device);
  324 + if (!mmc)
  325 + return CMD_RET_FAILURE;
227 326  
228   - if (part != mmc->part_num) {
229   - ret = mmc_switch_part(dev, part);
230   - if (!ret)
231   - mmc->part_num = part;
  327 + printf("\nMMC write: dev # %d, block # %d, count %d ... ",
  328 + curr_device, blk, cnt);
232 329  
233   - printf("switch to partitions #%d, %s\n",
234   - part, (!ret) ? "OK" : "ERROR");
235   - }
236   - }
237   - curr_device = dev;
238   - if (mmc->part_config == MMCPART_NOAVAILABLE)
239   - printf("mmc%d is current device\n", curr_device);
240   - else
241   - printf("mmc%d(part %d) is current device\n",
242   - curr_device, mmc->part_num);
  330 + if (mmc_getwp(mmc) == 1) {
  331 + printf("Error: card is write protected!\n");
  332 + return CMD_RET_FAILURE;
  333 + }
  334 + n = mmc->block_dev.block_write(curr_device, blk, cnt, addr);
  335 + printf("%d blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR");
243 336  
244   - return 0;
245   -#ifdef CONFIG_SUPPORT_EMMC_BOOT
246   - } else if (strcmp(argv[1], "partconf") == 0) {
247   - int dev;
248   - struct mmc *mmc;
249   - u8 ack, part_num, access;
  337 + return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
  338 +}
  339 +static int do_mmc_erase(cmd_tbl_t *cmdtp, int flag,
  340 + int argc, char * const argv[])
  341 +{
  342 + struct mmc *mmc;
  343 + u32 blk, cnt, n;
250 344  
251   - if (argc == 6) {
252   - dev = simple_strtoul(argv[2], NULL, 10);
253   - ack = simple_strtoul(argv[3], NULL, 10);
254   - part_num = simple_strtoul(argv[4], NULL, 10);
255   - access = simple_strtoul(argv[5], NULL, 10);
256   - } else {
257   - return CMD_RET_USAGE;
258   - }
  345 + if (argc != 3)
  346 + return CMD_RET_USAGE;
259 347  
260   - mmc = find_mmc_device(dev);
261   - if (!mmc) {
262   - printf("no mmc device at slot %x\n", dev);
263   - return 1;
264   - }
  348 + blk = simple_strtoul(argv[1], NULL, 16);
  349 + cnt = simple_strtoul(argv[2], NULL, 16);
265 350  
266   - if (IS_SD(mmc)) {
267   - puts("PARTITION_CONFIG only exists on eMMC\n");
268   - return 1;
269   - }
  351 + mmc = init_mmc_device(curr_device);
  352 + if (!mmc)
  353 + return CMD_RET_FAILURE;
270 354  
271   - /* acknowledge to be sent during boot operation */
272   - return mmc_set_part_conf(mmc, ack, part_num, access);
273   - } else if (strcmp(argv[1], "bootbus") == 0) {
274   - int dev;
275   - struct mmc *mmc;
276   - u8 width, reset, mode;
  355 + printf("\nMMC erase: dev # %d, block # %d, count %d ... ",
  356 + curr_device, blk, cnt);
277 357  
278   - if (argc == 6) {
279   - dev = simple_strtoul(argv[2], NULL, 10);
280   - width = simple_strtoul(argv[3], NULL, 10);
281   - reset = simple_strtoul(argv[4], NULL, 10);
282   - mode = simple_strtoul(argv[5], NULL, 10);
283   - } else {
284   - return CMD_RET_USAGE;
285   - }
  358 + if (mmc_getwp(mmc) == 1) {
  359 + printf("Error: card is write protected!\n");
  360 + return CMD_RET_FAILURE;
  361 + }
  362 + n = mmc->block_dev.block_erase(curr_device, blk, cnt);
  363 + printf("%d blocks erased: %s\n", n, (n == cnt) ? "OK" : "ERROR");
286 364  
287   - mmc = find_mmc_device(dev);
288   - if (!mmc) {
289   - printf("no mmc device at slot %x\n", dev);
290   - return 1;
291   - }
  365 + return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
  366 +}
  367 +static int do_mmc_rescan(cmd_tbl_t *cmdtp, int flag,
  368 + int argc, char * const argv[])
  369 +{
  370 + struct mmc *mmc;
292 371  
293   - if (IS_SD(mmc)) {
294   - puts("BOOT_BUS_WIDTH only exists on eMMC\n");
295   - return 1;
296   - }
  372 + mmc = find_mmc_device(curr_device);
  373 + if (!mmc) {
  374 + printf("no mmc device at slot %x\n", curr_device);
  375 + return CMD_RET_FAILURE;
  376 + }
297 377  
298   - /* acknowledge to be sent during boot operation */
299   - return mmc_set_boot_bus_width(mmc, width, reset, mode);
300   - } else if (strcmp(argv[1], "bootpart-resize") == 0) {
301   - int dev;
302   - struct mmc *mmc;
303   - u32 bootsize, rpmbsize;
  378 + mmc->has_init = 0;
304 379  
305   - if (argc == 5) {
306   - dev = simple_strtoul(argv[2], NULL, 10);
307   - bootsize = simple_strtoul(argv[3], NULL, 10);
308   - rpmbsize = simple_strtoul(argv[4], NULL, 10);
309   - } else {
310   - return CMD_RET_USAGE;
311   - }
  380 + if (mmc_init(mmc))
  381 + return CMD_RET_FAILURE;
  382 + return CMD_RET_SUCCESS;
  383 +}
  384 +static int do_mmc_part(cmd_tbl_t *cmdtp, int flag,
  385 + int argc, char * const argv[])
  386 +{
  387 + block_dev_desc_t *mmc_dev;
  388 + struct mmc *mmc;
312 389  
313   - mmc = find_mmc_device(dev);
314   - if (!mmc) {
315   - printf("no mmc device at slot %x\n", dev);
316   - return 1;
317   - }
  390 + mmc = init_mmc_device(curr_device);
  391 + if (!mmc)
  392 + return CMD_RET_FAILURE;
318 393  
319   - if (IS_SD(mmc)) {
320   - printf("It is not a EMMC device\n");
321   - return 1;
322   - }
  394 + mmc_dev = mmc_get_dev(curr_device);
  395 + if (mmc_dev != NULL && mmc_dev->type != DEV_TYPE_UNKNOWN) {
  396 + print_part(mmc_dev);
  397 + return CMD_RET_SUCCESS;
  398 + }
323 399  
324   - if (0 == mmc_boot_partition_size_change(mmc,
325   - bootsize, rpmbsize)) {
326   - printf("EMMC boot partition Size %d MB\n", bootsize);
327   - printf("EMMC RPMB partition Size %d MB\n", rpmbsize);
328   - return 0;
329   - } else {
330   - printf("EMMC boot partition Size change Failed.\n");
331   - return 1;
332   - }
333   - } else if (strcmp(argv[1], "rst-function") == 0) {
334   - /*
335   - * Set the RST_n_ENABLE bit of RST_n_FUNCTION
336   - * The only valid values are 0x0, 0x1 and 0x2 and writing
337   - * a value of 0x1 or 0x2 sets the value permanently.
338   - */
339   - int dev;
340   - struct mmc *mmc;
341   - u8 enable;
  400 + puts("get mmc type error!\n");
  401 + return CMD_RET_FAILURE;
  402 +}
  403 +static int do_mmc_dev(cmd_tbl_t *cmdtp, int flag,
  404 + int argc, char * const argv[])
  405 +{
  406 + int dev, part = -1, ret;
  407 + struct mmc *mmc;
342 408  
343   - if (argc == 4) {
344   - dev = simple_strtoul(argv[2], NULL, 10);
345   - enable = simple_strtoul(argv[3], NULL, 10);
346   - } else {
347   - return CMD_RET_USAGE;
  409 + if (argc == 1) {
  410 + dev = curr_device;
  411 + } else if (argc == 2) {
  412 + dev = simple_strtoul(argv[1], NULL, 10);
  413 + } else if (argc == 3) {
  414 + dev = (int)simple_strtoul(argv[1], NULL, 10);
  415 + part = (int)simple_strtoul(argv[2], NULL, 10);
  416 + if (part > PART_ACCESS_MASK) {
  417 + printf("#part_num shouldn't be larger than %d\n",
  418 + PART_ACCESS_MASK);
  419 + return CMD_RET_FAILURE;
348 420 }
  421 + } else {
  422 + return CMD_RET_USAGE;
  423 + }
349 424  
350   - if (enable > 2 || enable < 0) {
351   - puts("Invalid RST_n_ENABLE value\n");
352   - return CMD_RET_USAGE;
353   - }
  425 + mmc = init_mmc_device(dev);
  426 + if (!mmc)
  427 + return CMD_RET_FAILURE;
354 428  
355   - mmc = find_mmc_device(dev);
356   - if (!mmc) {
357   - printf("no mmc device at slot %x\n", dev);
  429 + if (part != -1) {
  430 + ret = mmc_select_hwpart(dev, part);
  431 + printf("switch to partitions #%d, %s\n",
  432 + part, (!ret) ? "OK" : "ERROR");
  433 + if (ret)
358 434 return 1;
359   - }
  435 + }
  436 + curr_device = dev;
  437 + if (mmc->part_config == MMCPART_NOAVAILABLE)
  438 + printf("mmc%d is current device\n", curr_device);
  439 + else
  440 + printf("mmc%d(part %d) is current device\n",
  441 + curr_device, mmc->part_num);
360 442  
361   - if (IS_SD(mmc)) {
362   - puts("RST_n_FUNCTION only exists on eMMC\n");
363   - return 1;
364   - }
  443 + return CMD_RET_SUCCESS;
  444 +}
  445 +static int do_mmc_list(cmd_tbl_t *cmdtp, int flag,
  446 + int argc, char * const argv[])
  447 +{
  448 + print_mmc_devices('\n');
  449 + return CMD_RET_SUCCESS;
  450 +}
  451 +#ifdef CONFIG_SUPPORT_EMMC_BOOT
  452 +static int do_mmc_bootbus(cmd_tbl_t *cmdtp, int flag,
  453 + int argc, char * const argv[])
  454 +{
  455 + int dev;
  456 + struct mmc *mmc;
  457 + u8 width, reset, mode;
365 458  
366   - return mmc_set_rst_n_function(mmc, enable);
367   -#endif /* CONFIG_SUPPORT_EMMC_BOOT */
  459 + if (argc != 5)
  460 + return CMD_RET_USAGE;
  461 + dev = simple_strtoul(argv[1], NULL, 10);
  462 + width = simple_strtoul(argv[2], NULL, 10);
  463 + reset = simple_strtoul(argv[3], NULL, 10);
  464 + mode = simple_strtoul(argv[4], NULL, 10);
  465 +
  466 + mmc = init_mmc_device(dev);
  467 + if (!mmc)
  468 + return CMD_RET_FAILURE;
  469 +
  470 + if (IS_SD(mmc)) {
  471 + puts("BOOT_BUS_WIDTH only exists on eMMC\n");
  472 + return CMD_RET_FAILURE;
368 473 }
369 474  
370   - else if (argc == 3 && strcmp(argv[1], "setdsr") == 0) {
371   - struct mmc *mmc = find_mmc_device(curr_device);
372   - u32 val = simple_strtoul(argv[2], NULL, 16);
373   - int ret;
  475 + /* acknowledge to be sent during boot operation */
  476 + return mmc_set_boot_bus_width(mmc, width, reset, mode);
  477 +}
  478 +static int do_mmc_boot_resize(cmd_tbl_t *cmdtp, int flag,
  479 + int argc, char * const argv[])
  480 +{
  481 + int dev;
  482 + struct mmc *mmc;
  483 + u32 bootsize, rpmbsize;
374 484  
375   - if (!mmc) {
376   - printf("no mmc device at slot %x\n", curr_device);
377   - return 1;
378   - }
379   - ret = mmc_set_dsr(mmc, val);
380   - printf("set dsr %s\n", (!ret) ? "OK, force rescan" : "ERROR");
381   - if (!ret) {
382   - mmc->has_init = 0;
383   - if (mmc_init(mmc))
384   - return 1;
385   - else
386   - return 0;
387   - }
388   - return ret;
  485 + if (argc != 4)
  486 + return CMD_RET_USAGE;
  487 + dev = simple_strtoul(argv[1], NULL, 10);
  488 + bootsize = simple_strtoul(argv[2], NULL, 10);
  489 + rpmbsize = simple_strtoul(argv[3], NULL, 10);
  490 +
  491 + mmc = init_mmc_device(dev);
  492 + if (!mmc)
  493 + return CMD_RET_FAILURE;
  494 +
  495 + if (IS_SD(mmc)) {
  496 + printf("It is not a EMMC device\n");
  497 + return CMD_RET_FAILURE;
389 498 }
390 499  
391   - state = MMC_INVALID;
392   - if (argc == 5 && strcmp(argv[1], "read") == 0)
393   - state = MMC_READ;
394   - else if (argc == 5 && strcmp(argv[1], "write") == 0)
395   - state = MMC_WRITE;
396   - else if (argc == 4 && strcmp(argv[1], "erase") == 0)
397   - state = MMC_ERASE;
  500 + if (mmc_boot_partition_size_change(mmc, bootsize, rpmbsize)) {
  501 + printf("EMMC boot partition Size change Failed.\n");
  502 + return CMD_RET_FAILURE;
  503 + }
398 504  
399   - if (state != MMC_INVALID) {
400   - struct mmc *mmc = find_mmc_device(curr_device);
401   - int idx = 2;
402   - u32 blk, cnt, n;
403   - void *addr;
  505 + printf("EMMC boot partition Size %d MB\n", bootsize);
  506 + printf("EMMC RPMB partition Size %d MB\n", rpmbsize);
  507 + return CMD_RET_SUCCESS;
  508 +}
  509 +static int do_mmc_partconf(cmd_tbl_t *cmdtp, int flag,
  510 + int argc, char * const argv[])
  511 +{
  512 + int dev;
  513 + struct mmc *mmc;
  514 + u8 ack, part_num, access;
404 515  
405   - if (state != MMC_ERASE) {
406   - addr = (void *)simple_strtoul(argv[idx], NULL, 16);
407   - ++idx;
408   - } else
409   - addr = NULL;
410   - blk = simple_strtoul(argv[idx], NULL, 16);
411   - cnt = simple_strtoul(argv[idx + 1], NULL, 16);
  516 + if (argc != 5)
  517 + return CMD_RET_USAGE;
412 518  
413   - if (!mmc) {
414   - printf("no mmc device at slot %x\n", curr_device);
415   - return 1;
416   - }
  519 + dev = simple_strtoul(argv[1], NULL, 10);
  520 + ack = simple_strtoul(argv[2], NULL, 10);
  521 + part_num = simple_strtoul(argv[3], NULL, 10);
  522 + access = simple_strtoul(argv[4], NULL, 10);
417 523  
418   - printf("\nMMC %s: dev # %d, block # %d, count %d ... ",
419   - argv[1], curr_device, blk, cnt);
  524 + mmc = init_mmc_device(dev);
  525 + if (!mmc)
  526 + return CMD_RET_FAILURE;
420 527  
421   - mmc_init(mmc);
  528 + if (IS_SD(mmc)) {
  529 + puts("PARTITION_CONFIG only exists on eMMC\n");
  530 + return CMD_RET_FAILURE;
  531 + }
422 532  
423   - if ((state == MMC_WRITE || state == MMC_ERASE)) {
424   - if (mmc_getwp(mmc) == 1) {
425   - printf("Error: card is write protected!\n");
426   - return 1;
427   - }
428   - }
  533 + /* acknowledge to be sent during boot operation */
  534 + return mmc_set_part_conf(mmc, ack, part_num, access);
  535 +}
  536 +static int do_mmc_rst_func(cmd_tbl_t *cmdtp, int flag,
  537 + int argc, char * const argv[])
  538 +{
  539 + int dev;
  540 + struct mmc *mmc;
  541 + u8 enable;
429 542  
430   - switch (state) {
431   - case MMC_READ:
432   - n = mmc->block_dev.block_read(curr_device, blk,
433   - cnt, addr);
434   - /* flush cache after read */
435   - flush_cache((ulong)addr, cnt * 512); /* FIXME */
436   - break;
437   - case MMC_WRITE:
438   - n = mmc->block_dev.block_write(curr_device, blk,
439   - cnt, addr);
440   - break;
441   - case MMC_ERASE:
442   - n = mmc->block_dev.block_erase(curr_device, blk, cnt);
443   - break;
444   - default:
445   - BUG();
446   - }
  543 + /*
  544 + * Set the RST_n_ENABLE bit of RST_n_FUNCTION
  545 + * The only valid values are 0x0, 0x1 and 0x2 and writing
  546 + * a value of 0x1 or 0x2 sets the value permanently.
  547 + */
  548 + if (argc != 3)
  549 + return CMD_RET_USAGE;
447 550  
448   - printf("%d blocks %s: %s\n",
449   - n, argv[1], (n == cnt) ? "OK" : "ERROR");
450   - return (n == cnt) ? 0 : 1;
  551 + dev = simple_strtoul(argv[1], NULL, 10);
  552 + enable = simple_strtoul(argv[2], NULL, 10);
  553 +
  554 + if (enable > 2 || enable < 0) {
  555 + puts("Invalid RST_n_ENABLE value\n");
  556 + return CMD_RET_USAGE;
451 557 }
452 558  
453   - return CMD_RET_USAGE;
  559 + mmc = init_mmc_device(dev);
  560 + if (!mmc)
  561 + return CMD_RET_FAILURE;
  562 +
  563 + if (IS_SD(mmc)) {
  564 + puts("RST_n_FUNCTION only exists on eMMC\n");
  565 + return CMD_RET_FAILURE;
  566 + }
  567 +
  568 + return mmc_set_rst_n_function(mmc, enable);
454 569 }
  570 +#endif
  571 +static int do_mmc_setdsr(cmd_tbl_t *cmdtp, int flag,
  572 + int argc, char * const argv[])
  573 +{
  574 + struct mmc *mmc;
  575 + u32 val;
  576 + int ret;
455 577  
  578 + if (argc != 2)
  579 + return CMD_RET_USAGE;
  580 + val = simple_strtoul(argv[2], NULL, 16);
  581 +
  582 + mmc = find_mmc_device(curr_device);
  583 + if (!mmc) {
  584 + printf("no mmc device at slot %x\n", curr_device);
  585 + return CMD_RET_FAILURE;
  586 + }
  587 + ret = mmc_set_dsr(mmc, val);
  588 + printf("set dsr %s\n", (!ret) ? "OK, force rescan" : "ERROR");
  589 + if (!ret) {
  590 + mmc->has_init = 0;
  591 + if (mmc_init(mmc))
  592 + return CMD_RET_FAILURE;
  593 + else
  594 + return CMD_RET_SUCCESS;
  595 + }
  596 + return ret;
  597 +}
  598 +
  599 +static cmd_tbl_t cmd_mmc[] = {
  600 + U_BOOT_CMD_MKENT(info, 1, 0, do_mmcinfo, "", ""),
  601 + U_BOOT_CMD_MKENT(read, 4, 1, do_mmc_read, "", ""),
  602 + U_BOOT_CMD_MKENT(write, 4, 0, do_mmc_write, "", ""),
  603 + U_BOOT_CMD_MKENT(erase, 3, 0, do_mmc_erase, "", ""),
  604 + U_BOOT_CMD_MKENT(rescan, 1, 1, do_mmc_rescan, "", ""),
  605 + U_BOOT_CMD_MKENT(part, 1, 1, do_mmc_part, "", ""),
  606 + U_BOOT_CMD_MKENT(dev, 3, 0, do_mmc_dev, "", ""),
  607 + U_BOOT_CMD_MKENT(list, 1, 1, do_mmc_list, "", ""),
  608 +#ifdef CONFIG_SUPPORT_EMMC_BOOT
  609 + U_BOOT_CMD_MKENT(bootbus, 5, 0, do_mmc_bootbus, "", ""),
  610 + U_BOOT_CMD_MKENT(bootpart-resize, 3, 0, do_mmc_boot_resize, "", ""),
  611 + U_BOOT_CMD_MKENT(partconf, 5, 0, do_mmc_partconf, "", ""),
  612 + U_BOOT_CMD_MKENT(rst-function, 3, 0, do_mmc_rst_func, "", ""),
  613 +#endif
  614 +#ifdef CONFIG_SUPPORT_EMMC_RPMB
  615 + U_BOOT_CMD_MKENT(rpmb, CONFIG_SYS_MAXARGS, 1, do_mmcrpmb, "", ""),
  616 +#endif
  617 + U_BOOT_CMD_MKENT(setdsr, 2, 0, do_mmc_setdsr, "", ""),
  618 +};
  619 +
  620 +static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  621 +{
  622 + cmd_tbl_t *cp;
  623 +
  624 + cp = find_cmd_tbl(argv[1], cmd_mmc, ARRAY_SIZE(cmd_mmc));
  625 +
  626 + /* Drop the mmc command */
  627 + argc--;
  628 + argv++;
  629 +
  630 + if (cp == NULL || argc > cp->maxargs)
  631 + return CMD_RET_USAGE;
  632 + if (flag == CMD_FLAG_REPEAT && !cp->repeatable)
  633 + return CMD_RET_SUCCESS;
  634 +
  635 + if (curr_device < 0) {
  636 + if (get_mmc_num() > 0) {
  637 + curr_device = 0;
  638 + } else {
  639 + puts("No MMC device available\n");
  640 + return CMD_RET_FAILURE;
  641 + }
  642 + }
  643 + return cp->cmd(cmdtp, flag, argc, argv);
  644 +}
  645 +
456 646 U_BOOT_CMD(
457   - mmc, 6, 1, do_mmcops,
  647 + mmc, 7, 1, do_mmcops,
458 648 "MMC sub system",
459   - "read addr blk# cnt\n"
  649 + "info - display info of the current MMC device\n"
  650 + "mmc read addr blk# cnt\n"
460 651 "mmc write addr blk# cnt\n"
461 652 "mmc erase blk# cnt\n"
462 653 "mmc rescan\n"
463 654  
... ... @@ -474,7 +665,21 @@
474 665 " - Change the RST_n_FUNCTION field of the specified device\n"
475 666 " WARNING: This is a write-once field and 0 / 1 / 2 are the only valid values.\n"
476 667 #endif
477   - "mmc setdsr - set DSR register value\n"
  668 +#ifdef CONFIG_SUPPORT_EMMC_RPMB
  669 + "mmc rpmb read addr blk# cnt [address of auth-key] - block size is 256 bytes\n"
  670 + "mmc rpmb write addr blk# cnt <address of auth-key> - block size is 256 bytes\n"
  671 + "mmc rpmb key <address of auth-key> - program the RPMB authentication key.\n"
  672 + "mmc rpmb counter - read the value of the write counter\n"
  673 +#endif
  674 + "mmc setdsr <value> - set DSR register value\n"
478 675 );
  676 +
  677 +/* Old command kept for compatibility. Same as 'mmc info' */
  678 +U_BOOT_CMD(
  679 + mmcinfo, 1, 0, do_mmcinfo,
  680 + "display MMC info",
  681 + "- display info of the current MMC device"
  682 +);
  683 +
479 684 #endif /* !CONFIG_GENERIC_MMC */
... ... @@ -605,22 +605,16 @@
605 605 opts.spread = spread;
606 606  
607 607 if (scrub) {
608   - if (!scrub_yes)
609   - puts(scrub_warn);
610   -
611   - if (scrub_yes)
  608 + if (scrub_yes) {
612 609 opts.scrub = 1;
613   - else if (getc() == 'y') {
614   - puts("y");
615   - if (getc() == '\r')
  610 + } else {
  611 + puts(scrub_warn);
  612 + if (confirm_yesno()) {
616 613 opts.scrub = 1;
617   - else {
  614 + } else {
618 615 puts("scrub aborted\n");
619 616 return 1;
620 617 }
621   - } else {
622   - puts("scrub aborted\n");
623   - return 1;
624 618 }
625 619 }
626 620 ret = nand_erase_opts(nand, &opts);
... ... @@ -158,21 +158,9 @@
158 158 lowup(half + count - 1), page + (half + count - 1) / 2,
159 159 half + count
160 160 );
161   -
162   - i = 0;
163   - while (1) {
164   - if (tstc()) {
165   - const char exp_ans[] = "YES\r";
166   - char c;
167   - putc(c = getc());
168   - if (exp_ans[i++] != c) {
169   - printf(" Aborting\n");
170   - return 1;
171   - } else if (!exp_ans[i]) {
172   - puts("\n");
173   - break;
174   - }
175   - }
  161 + if (!confirm_yesno()) {
  162 + printf(" Aborting\n");
  163 + return 1;
176 164 }
177 165 }
178 166  
... ... @@ -82,7 +82,7 @@
82 82 U_BOOT_CMD(
83 83 part, 5, 1, do_part,
84 84 "disk partition related commands",
85   - "uuid <interface> <dev>:<part>\n"
  85 + "part uuid <interface> <dev>:<part>\n"
86 86 " - print partition UUID\n"
87 87 "part uuid <interface> <dev>:<part> <varname>\n"
88 88 " - set environment variable to partition UUID\n"
... ... @@ -537,7 +537,33 @@
537 537 }
538 538 return 0;
539 539 }
  540 +/* Reads user's confirmation.
  541 + Returns 1 if user's input is "y", "Y", "yes" or "YES"
  542 +*/
  543 +int confirm_yesno(void)
  544 +{
  545 + int i;
  546 + char str_input[5];
540 547  
  548 + /* Flush input */
  549 + while (tstc())
  550 + getc();
  551 + i = 0;
  552 + while (i < sizeof(str_input)) {
  553 + str_input[i] = getc();
  554 + putc(str_input[i]);
  555 + if (str_input[i] == '\r')
  556 + break;
  557 + i++;
  558 + }
  559 + putc('\n');
  560 + if (strncmp(str_input, "y\r", 2) == 0 ||
  561 + strncmp(str_input, "Y\r", 2) == 0 ||
  562 + strncmp(str_input, "yes\r", 4) == 0 ||
  563 + strncmp(str_input, "YES\r", 4) == 0)
  564 + return 1;
  565 + return 0;
  566 +}
541 567 /* pass 1 to disable ctrlc() checking, 0 to enable.
542 568 * returns previous state
543 569 */
... ... @@ -22,6 +22,7 @@
22 22 struct block_drvr {
23 23 char *name;
24 24 block_dev_desc_t* (*get_dev)(int dev);
  25 + int (*select_hwpart)(int dev_num, int hwpart);
25 26 };
26 27  
27 28 static const struct block_drvr block_drvr[] = {
... ... @@ -38,7 +39,11 @@
38 39 { .name = "usb", .get_dev = usb_stor_get_dev, },
39 40 #endif
40 41 #if defined(CONFIG_MMC)
41   - { .name = "mmc", .get_dev = mmc_get_dev, },
  42 + {
  43 + .name = "mmc",
  44 + .get_dev = mmc_get_dev,
  45 + .select_hwpart = mmc_select_hwpart,
  46 + },
42 47 #endif
43 48 #if defined(CONFIG_SYSTEMACE)
44 49 { .name = "ace", .get_dev = systemace_get_dev, },
45 50  
46 51  
... ... @@ -52,11 +57,13 @@
52 57 DECLARE_GLOBAL_DATA_PTR;
53 58  
54 59 #ifdef HAVE_BLOCK_DEVICE
55   -block_dev_desc_t *get_dev(const char *ifname, int dev)
  60 +block_dev_desc_t *get_dev_hwpart(const char *ifname, int dev, int hwpart)
56 61 {
57 62 const struct block_drvr *drvr = block_drvr;
58 63 block_dev_desc_t* (*reloc_get_dev)(int dev);
  64 + int (*select_hwpart)(int dev_num, int hwpart);
59 65 char *name;
  66 + int ret;
60 67  
61 68 if (!ifname)
62 69 return NULL;
63 70  
64 71  
65 72  
66 73  
... ... @@ -68,17 +75,41 @@
68 75 while (drvr->name) {
69 76 name = drvr->name;
70 77 reloc_get_dev = drvr->get_dev;
  78 + select_hwpart = drvr->select_hwpart;
71 79 #ifdef CONFIG_NEEDS_MANUAL_RELOC
72 80 name += gd->reloc_off;
73 81 reloc_get_dev += gd->reloc_off;
  82 + if (select_hwpart)
  83 + select_hwpart += gd->reloc_off;
74 84 #endif
75   - if (strncmp(ifname, name, strlen(name)) == 0)
76   - return reloc_get_dev(dev);
  85 + if (strncmp(ifname, name, strlen(name)) == 0) {
  86 + block_dev_desc_t *dev_desc = reloc_get_dev(dev);
  87 + if (!dev_desc)
  88 + return NULL;
  89 + if (hwpart == -1)
  90 + return dev_desc;
  91 + if (!select_hwpart)
  92 + return NULL;
  93 + ret = select_hwpart(dev_desc->dev, hwpart);
  94 + if (ret < 0)
  95 + return NULL;
  96 + return dev_desc;
  97 + }
77 98 drvr++;
78 99 }
79 100 return NULL;
80 101 }
  102 +
  103 +block_dev_desc_t *get_dev(const char *ifname, int dev)
  104 +{
  105 + return get_dev_hwpart(ifname, dev, -1);
  106 +}
81 107 #else
  108 +block_dev_desc_t *get_dev_hwpart(const char *ifname, int dev, int hwpart)
  109 +{
  110 + return NULL;
  111 +}
  112 +
82 113 block_dev_desc_t *get_dev(const char *ifname, int dev)
83 114 {
84 115 return NULL;
85 116  
86 117  
87 118  
88 119  
89 120  
90 121  
... ... @@ -413,25 +444,52 @@
413 444 return -1;
414 445 }
415 446  
416   -int get_device(const char *ifname, const char *dev_str,
  447 +int get_device(const char *ifname, const char *dev_hwpart_str,
417 448 block_dev_desc_t **dev_desc)
418 449 {
419 450 char *ep;
420   - int dev;
  451 + char *dup_str = NULL;
  452 + const char *dev_str, *hwpart_str;
  453 + int dev, hwpart;
421 454  
  455 + hwpart_str = strchr(dev_hwpart_str, '.');
  456 + if (hwpart_str) {
  457 + dup_str = strdup(dev_hwpart_str);
  458 + dup_str[hwpart_str - dev_hwpart_str] = 0;
  459 + dev_str = dup_str;
  460 + hwpart_str++;
  461 + } else {
  462 + dev_str = dev_hwpart_str;
  463 + hwpart = -1;
  464 + }
  465 +
422 466 dev = simple_strtoul(dev_str, &ep, 16);
423 467 if (*ep) {
424 468 printf("** Bad device specification %s %s **\n",
425 469 ifname, dev_str);
426   - return -1;
  470 + dev = -1;
  471 + goto cleanup;
427 472 }
428 473  
429   - *dev_desc = get_dev(ifname, dev);
  474 + if (hwpart_str) {
  475 + hwpart = simple_strtoul(hwpart_str, &ep, 16);
  476 + if (*ep) {
  477 + printf("** Bad HW partition specification %s %s **\n",
  478 + ifname, hwpart_str);
  479 + dev = -1;
  480 + goto cleanup;
  481 + }
  482 + }
  483 +
  484 + *dev_desc = get_dev_hwpart(ifname, dev, hwpart);
430 485 if (!(*dev_desc) || ((*dev_desc)->type == DEV_TYPE_UNKNOWN)) {
431   - printf("** Bad device %s %s **\n", ifname, dev_str);
432   - return -1;
  486 + printf("** Bad device %s %s **\n", ifname, dev_hwpart_str);
  487 + dev = -1;
  488 + goto cleanup;
433 489 }
434 490  
  491 +cleanup:
  492 + free(dup_str);
435 493 return dev;
436 494 }
437 495  
drivers/mmc/Makefile
... ... @@ -30,6 +30,7 @@
30 30 obj-$(CONFIG_EXYNOS_DWMMC) += exynos_dw_mmc.o
31 31 obj-$(CONFIG_ZYNQ_SDHCI) += zynq_sdhci.o
32 32 obj-$(CONFIG_SOCFPGA_DWMMC) += socfpga_dw_mmc.o
  33 +obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o
33 34 ifdef CONFIG_SPL_BUILD
34 35 obj-$(CONFIG_SPL_MMC_BOOT) += fsl_esdhc_spl.o
35 36 else
drivers/mmc/fsl_esdhc.c
... ... @@ -174,7 +174,7 @@
174 174 int timeout;
175 175 struct fsl_esdhc_cfg *cfg = mmc->priv;
176 176 struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
177   -#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
  177 +
178 178 uint wml_value;
179 179  
180 180 wml_value = data->blocksize/4;
181 181  
182 182  
183 183  
... ... @@ -184,12 +184,15 @@
184 184 wml_value = WML_RD_WML_MAX_VAL;
185 185  
186 186 esdhc_clrsetbits32(&regs->wml, WML_RD_WML_MASK, wml_value);
  187 +#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
187 188 esdhc_write32(&regs->dsaddr, (u32)data->dest);
  189 +#endif
188 190 } else {
  191 +#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
189 192 flush_dcache_range((ulong)data->src,
190 193 (ulong)data->src+data->blocks
191 194 *data->blocksize);
192   -
  195 +#endif
193 196 if (wml_value > WML_WR_WML_MAX)
194 197 wml_value = WML_WR_WML_MAX_VAL;
195 198 if ((esdhc_read32(&regs->prsstat) & PRSSTAT_WPSPL) == 0) {
196 199  
197 200  
... ... @@ -199,19 +202,10 @@
199 202  
200 203 esdhc_clrsetbits32(&regs->wml, WML_WR_WML_MASK,
201 204 wml_value << 16);
  205 +#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
202 206 esdhc_write32(&regs->dsaddr, (u32)data->src);
  207 +#endif
203 208 }
204   -#else /* CONFIG_SYS_FSL_ESDHC_USE_PIO */
205   - if (!(data->flags & MMC_DATA_READ)) {
206   - if ((esdhc_read32(&regs->prsstat) & PRSSTAT_WPSPL) == 0) {
207   - printf("\nThe SD card is locked. "
208   - "Can not write to a locked card.\n\n");
209   - return TIMEOUT;
210   - }
211   - esdhc_write32(&regs->dsaddr, (u32)data->src);
212   - } else
213   - esdhc_write32(&regs->dsaddr, (u32)data->dest);
214   -#endif /* CONFIG_SYS_FSL_ESDHC_USE_PIO */
215 209  
216 210 esdhc_write32(&regs->blkattr, data->blocks << 16 | data->blocksize);
217 211  
218 212  
... ... @@ -388,9 +382,10 @@
388 382 goto out;
389 383 }
390 384 } while ((irqstat & DATA_COMPLETE) != DATA_COMPLETE);
391   -#endif
  385 +
392 386 if (data->flags & MMC_DATA_READ)
393 387 check_and_invalidate_dcache_range(cmd, data);
  388 +#endif
394 389 }
395 390  
396 391 out:
... ... @@ -150,6 +150,8 @@
150 150 #endif
151 151 return TIMEOUT;
152 152 }
  153 + if (cmd.response[0] & MMC_STATUS_SWITCH_ERROR)
  154 + return SWITCH_ERR;
153 155  
154 156 return 0;
155 157 }
... ... @@ -501,7 +503,7 @@
501 503 err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
502 504  
503 505 if (err)
504   - return err;
  506 + return err == SWITCH_ERR ? 0 : err;
505 507  
506 508 /* Now check to see that it worked */
507 509 err = mmc_send_ext_csd(mmc, ext_csd);
... ... @@ -550,6 +552,32 @@
550 552 return 0;
551 553 }
552 554  
  555 +int mmc_select_hwpart(int dev_num, int hwpart)
  556 +{
  557 + struct mmc *mmc = find_mmc_device(dev_num);
  558 + int ret;
  559 +
  560 + if (!mmc)
  561 + return -1;
  562 +
  563 + if (mmc->part_num == hwpart)
  564 + return 0;
  565 +
  566 + if (mmc->part_config == MMCPART_NOAVAILABLE) {
  567 + printf("Card doesn't support part_switch\n");
  568 + return -1;
  569 + }
  570 +
  571 + ret = mmc_switch_part(dev_num, hwpart);
  572 + if (ret)
  573 + return -1;
  574 +
  575 + mmc->part_num = hwpart;
  576 +
  577 + return 0;
  578 +}
  579 +
  580 +
553 581 int mmc_switch_part(int dev_num, unsigned int part_num)
554 582 {
555 583 struct mmc *mmc = find_mmc_device(dev_num);
556 584  
... ... @@ -1310,10 +1338,13 @@
1310 1338 int mmc_init(struct mmc *mmc)
1311 1339 {
1312 1340 int err = IN_PROGRESS;
1313   - unsigned start = get_timer(0);
  1341 + unsigned start;
1314 1342  
1315 1343 if (mmc->has_init)
1316 1344 return 0;
  1345 +
  1346 + start = get_timer(0);
  1347 +
1317 1348 if (!mmc->init_in_progress)
1318 1349 err = mmc_start_init(mmc);
1319 1350  
  1 +/*
  2 + * Copyright 2014, Staubli Faverges
  3 + * Pierre Aubert
  4 + *
  5 + * eMMC- Replay Protected Memory Block
  6 + * According to JEDEC Standard No. 84-A441
  7 + *
  8 + * SPDX-License-Identifier: GPL-2.0+
  9 + */
  10 +
  11 +#include <config.h>
  12 +#include <common.h>
  13 +#include <mmc.h>
  14 +#include <sha256.h>
  15 +#include "mmc_private.h"
  16 +
  17 +/* Request codes */
  18 +#define RPMB_REQ_KEY 1
  19 +#define RPMB_REQ_WCOUNTER 2
  20 +#define RPMB_REQ_WRITE_DATA 3
  21 +#define RPMB_REQ_READ_DATA 4
  22 +#define RPMB_REQ_STATUS 5
  23 +
  24 +/* Response code */
  25 +#define RPMB_RESP_KEY 0x0100
  26 +#define RPMB_RESP_WCOUNTER 0x0200
  27 +#define RPMB_RESP_WRITE_DATA 0x0300
  28 +#define RPMB_RESP_READ_DATA 0x0400
  29 +
  30 +/* Error codes */
  31 +#define RPMB_OK 0
  32 +#define RPMB_ERR_GENERAL 1
  33 +#define RPMB_ERR_AUTH 2
  34 +#define RPMB_ERR_COUNTER 3
  35 +#define RPMB_ERR_ADDRESS 4
  36 +#define RPMB_ERR_WRITE 5
  37 +#define RPMB_ERR_READ 6
  38 +#define RPMB_ERR_KEY 7
  39 +#define RPMB_ERR_CNT_EXPIRED 0x80
  40 +#define RPMB_ERR_MSK 0x7
  41 +
  42 +/* Sizes of RPMB data frame */
  43 +#define RPMB_SZ_STUFF 196
  44 +#define RPMB_SZ_MAC 32
  45 +#define RPMB_SZ_DATA 256
  46 +#define RPMB_SZ_NONCE 16
  47 +
  48 +#define SHA256_BLOCK_SIZE 64
  49 +
  50 +/* Error messages */
  51 +static const char * const rpmb_err_msg[] = {
  52 + "",
  53 + "General failure",
  54 + "Authentication failure",
  55 + "Counter failure",
  56 + "Address failure",
  57 + "Write failure",
  58 + "Read failure",
  59 + "Authentication key not yet programmed",
  60 +};
  61 +
  62 +
  63 +/* Structure of RPMB data frame. */
  64 +struct s_rpmb {
  65 + unsigned char stuff[RPMB_SZ_STUFF];
  66 + unsigned char mac[RPMB_SZ_MAC];
  67 + unsigned char data[RPMB_SZ_DATA];
  68 + unsigned char nonce[RPMB_SZ_NONCE];
  69 + unsigned long write_counter;
  70 + unsigned short address;
  71 + unsigned short block_count;
  72 + unsigned short result;
  73 + unsigned short request;
  74 +};
  75 +
  76 +static int mmc_set_blockcount(struct mmc *mmc, unsigned int blockcount,
  77 + bool is_rel_write)
  78 +{
  79 + struct mmc_cmd cmd = {0};
  80 +
  81 + cmd.cmdidx = MMC_CMD_SET_BLOCK_COUNT;
  82 + cmd.cmdarg = blockcount & 0x0000FFFF;
  83 + if (is_rel_write)
  84 + cmd.cmdarg |= 1 << 31;
  85 + cmd.resp_type = MMC_RSP_R1;
  86 +
  87 + return mmc_send_cmd(mmc, &cmd, NULL);
  88 +}
  89 +static int mmc_rpmb_request(struct mmc *mmc, const struct s_rpmb *s,
  90 + unsigned int count, bool is_rel_write)
  91 +{
  92 + struct mmc_cmd cmd = {0};
  93 + struct mmc_data data;
  94 + int ret;
  95 +
  96 + ret = mmc_set_blockcount(mmc, count, is_rel_write);
  97 + if (ret) {
  98 +#ifdef CONFIG_MMC_RPMB_TRACE
  99 + printf("%s:mmc_set_blockcount-> %d\n", __func__, ret);
  100 +#endif
  101 + return 1;
  102 + }
  103 +
  104 + cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
  105 + cmd.cmdarg = 0;
  106 + cmd.resp_type = MMC_RSP_R1b;
  107 +
  108 + data.src = (const char *)s;
  109 + data.blocks = 1;
  110 + data.blocksize = MMC_MAX_BLOCK_LEN;
  111 + data.flags = MMC_DATA_WRITE;
  112 +
  113 + ret = mmc_send_cmd(mmc, &cmd, &data);
  114 + if (ret) {
  115 +#ifdef CONFIG_MMC_RPMB_TRACE
  116 + printf("%s:mmc_send_cmd-> %d\n", __func__, ret);
  117 +#endif
  118 + return 1;
  119 + }
  120 + return 0;
  121 +}
  122 +static int mmc_rpmb_response(struct mmc *mmc, struct s_rpmb *s,
  123 + unsigned short expected)
  124 +{
  125 + struct mmc_cmd cmd = {0};
  126 + struct mmc_data data;
  127 + int ret;
  128 +
  129 + ret = mmc_set_blockcount(mmc, 1, false);
  130 + if (ret) {
  131 +#ifdef CONFIG_MMC_RPMB_TRACE
  132 + printf("%s:mmc_set_blockcount-> %d\n", __func__, ret);
  133 +#endif
  134 + return -1;
  135 + }
  136 + cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
  137 + cmd.cmdarg = 0;
  138 + cmd.resp_type = MMC_RSP_R1;
  139 +
  140 + data.dest = (char *)s;
  141 + data.blocks = 1;
  142 + data.blocksize = MMC_MAX_BLOCK_LEN;
  143 + data.flags = MMC_DATA_READ;
  144 +
  145 + ret = mmc_send_cmd(mmc, &cmd, &data);
  146 + if (ret) {
  147 +#ifdef CONFIG_MMC_RPMB_TRACE
  148 + printf("%s:mmc_send_cmd-> %d\n", __func__, ret);
  149 +#endif
  150 + return -1;
  151 + }
  152 + /* Check the response and the status */
  153 + if (be16_to_cpu(s->request) != expected) {
  154 +#ifdef CONFIG_MMC_RPMB_TRACE
  155 + printf("%s:response= %x\n", __func__,
  156 + be16_to_cpu(s->request));
  157 +#endif
  158 + return -1;
  159 + }
  160 + ret = be16_to_cpu(s->result);
  161 + if (ret) {
  162 + printf("%s %s\n", rpmb_err_msg[ret & RPMB_ERR_MSK],
  163 + (ret & RPMB_ERR_CNT_EXPIRED) ?
  164 + "Write counter has expired" : "");
  165 + }
  166 +
  167 + /* Return the status of the command */
  168 + return ret;
  169 +}
  170 +static int mmc_rpmb_status(struct mmc *mmc, unsigned short expected)
  171 +{
  172 + ALLOC_CACHE_ALIGN_BUFFER(struct s_rpmb, rpmb_frame, 1);
  173 +
  174 + memset(rpmb_frame, 0, sizeof(struct s_rpmb));
  175 + rpmb_frame->request = cpu_to_be16(RPMB_REQ_STATUS);
  176 + if (mmc_rpmb_request(mmc, rpmb_frame, 1, false))
  177 + return -1;
  178 +
  179 + /* Read the result */
  180 + return mmc_rpmb_response(mmc, rpmb_frame, expected);
  181 +}
  182 +static void rpmb_hmac(unsigned char *key, unsigned char *buff, int len,
  183 + unsigned char *output)
  184 +{
  185 + sha256_context ctx;
  186 + int i;
  187 + unsigned char k_ipad[SHA256_BLOCK_SIZE];
  188 + unsigned char k_opad[SHA256_BLOCK_SIZE];
  189 +
  190 + sha256_starts(&ctx);
  191 +
  192 + /* According to RFC 4634, the HMAC transform looks like:
  193 + SHA(K XOR opad, SHA(K XOR ipad, text))
  194 +
  195 + where K is an n byte key.
  196 + ipad is the byte 0x36 repeated blocksize times
  197 + opad is the byte 0x5c repeated blocksize times
  198 + and text is the data being protected.
  199 + */
  200 +
  201 + for (i = 0; i < RPMB_SZ_MAC; i++) {
  202 + k_ipad[i] = key[i] ^ 0x36;
  203 + k_opad[i] = key[i] ^ 0x5c;
  204 + }
  205 + /* remaining pad bytes are '\0' XOR'd with ipad and opad values */
  206 + for ( ; i < SHA256_BLOCK_SIZE; i++) {
  207 + k_ipad[i] = 0x36;
  208 + k_opad[i] = 0x5c;
  209 + }
  210 + sha256_update(&ctx, k_ipad, SHA256_BLOCK_SIZE);
  211 + sha256_update(&ctx, buff, len);
  212 + sha256_finish(&ctx, output);
  213 +
  214 + /* Init context for second pass */
  215 + sha256_starts(&ctx);
  216 +
  217 + /* start with outer pad */
  218 + sha256_update(&ctx, k_opad, SHA256_BLOCK_SIZE);
  219 +
  220 + /* then results of 1st hash */
  221 + sha256_update(&ctx, output, RPMB_SZ_MAC);
  222 +
  223 + /* finish up 2nd pass */
  224 + sha256_finish(&ctx, output);
  225 +}
  226 +int mmc_rpmb_get_counter(struct mmc *mmc, unsigned long *pcounter)
  227 +{
  228 + int ret;
  229 + ALLOC_CACHE_ALIGN_BUFFER(struct s_rpmb, rpmb_frame, 1);
  230 +
  231 + /* Fill the request */
  232 + memset(rpmb_frame, 0, sizeof(struct s_rpmb));
  233 + rpmb_frame->request = cpu_to_be16(RPMB_REQ_WCOUNTER);
  234 + if (mmc_rpmb_request(mmc, rpmb_frame, 1, false))
  235 + return -1;
  236 +
  237 + /* Read the result */
  238 + ret = mmc_rpmb_response(mmc, rpmb_frame, RPMB_RESP_WCOUNTER);
  239 + if (ret)
  240 + return ret;
  241 +
  242 + *pcounter = be32_to_cpu(rpmb_frame->write_counter);
  243 + return 0;
  244 +}
  245 +int mmc_rpmb_set_key(struct mmc *mmc, void *key)
  246 +{
  247 + ALLOC_CACHE_ALIGN_BUFFER(struct s_rpmb, rpmb_frame, 1);
  248 + /* Fill the request */
  249 + memset(rpmb_frame, 0, sizeof(struct s_rpmb));
  250 + rpmb_frame->request = cpu_to_be16(RPMB_REQ_KEY);
  251 + memcpy(rpmb_frame->mac, key, RPMB_SZ_MAC);
  252 +
  253 + if (mmc_rpmb_request(mmc, rpmb_frame, 1, true))
  254 + return -1;
  255 +
  256 + /* read the operation status */
  257 + return mmc_rpmb_status(mmc, RPMB_RESP_KEY);
  258 +}
  259 +int mmc_rpmb_read(struct mmc *mmc, void *addr, unsigned short blk,
  260 + unsigned short cnt, unsigned char *key)
  261 +{
  262 + ALLOC_CACHE_ALIGN_BUFFER(struct s_rpmb, rpmb_frame, 1);
  263 + int i;
  264 +
  265 + for (i = 0; i < cnt; i++) {
  266 + /* Fill the request */
  267 + memset(rpmb_frame, 0, sizeof(struct s_rpmb));
  268 + rpmb_frame->address = cpu_to_be16(blk + i);
  269 + rpmb_frame->request = cpu_to_be16(RPMB_REQ_READ_DATA);
  270 + if (mmc_rpmb_request(mmc, rpmb_frame, 1, false))
  271 + break;
  272 +
  273 + /* Read the result */
  274 + if (mmc_rpmb_response(mmc, rpmb_frame, RPMB_RESP_READ_DATA))
  275 + break;
  276 +
  277 + /* Check the HMAC if key is provided */
  278 + if (key) {
  279 + unsigned char ret_hmac[RPMB_SZ_MAC];
  280 +
  281 + rpmb_hmac(key, rpmb_frame->data, 284, ret_hmac);
  282 + if (memcmp(ret_hmac, rpmb_frame->mac, RPMB_SZ_MAC)) {
  283 + printf("MAC error on block #%d\n", i);
  284 + break;
  285 + }
  286 + }
  287 + /* Copy data */
  288 + memcpy(addr + i * RPMB_SZ_DATA, rpmb_frame->data, RPMB_SZ_DATA);
  289 + }
  290 + return i;
  291 +}
  292 +int mmc_rpmb_write(struct mmc *mmc, void *addr, unsigned short blk,
  293 + unsigned short cnt, unsigned char *key)
  294 +{
  295 + ALLOC_CACHE_ALIGN_BUFFER(struct s_rpmb, rpmb_frame, 1);
  296 + unsigned long wcount;
  297 + int i;
  298 +
  299 + for (i = 0; i < cnt; i++) {
  300 + if (mmc_rpmb_get_counter(mmc, &wcount)) {
  301 + printf("Cannot read RPMB write counter\n");
  302 + break;
  303 + }
  304 +
  305 + /* Fill the request */
  306 + memset(rpmb_frame, 0, sizeof(struct s_rpmb));
  307 + memcpy(rpmb_frame->data, addr + i * RPMB_SZ_DATA, RPMB_SZ_DATA);
  308 + rpmb_frame->address = cpu_to_be16(blk + i);
  309 + rpmb_frame->block_count = cpu_to_be16(1);
  310 + rpmb_frame->write_counter = cpu_to_be32(wcount);
  311 + rpmb_frame->request = cpu_to_be16(RPMB_REQ_WRITE_DATA);
  312 + /* Computes HMAC */
  313 + rpmb_hmac(key, rpmb_frame->data, 284, rpmb_frame->mac);
  314 +
  315 + if (mmc_rpmb_request(mmc, rpmb_frame, 1, true))
  316 + break;
  317 +
  318 + /* Get status */
  319 + if (mmc_rpmb_status(mmc, RPMB_RESP_WRITE_DATA))
  320 + break;
  321 + }
  322 + return i;
  323 +}
... ... @@ -836,7 +836,7 @@
836 836 int had_ctrlc (void); /* have we had a Control-C since last clear? */
837 837 void clear_ctrlc (void); /* clear the Control-C condition */
838 838 int disable_ctrlc (int); /* 1 to disable, 0 to enable Control-C detect */
839   -
  839 +int confirm_yesno(void); /* 1 if input is "y", "Y", "yes" or "YES" */
840 840 /*
841 841 * STDIO based functions (can always be used)
842 842 */
include/configs/kwb.h
... ... @@ -109,7 +109,7 @@
109 109  
110 110 #undef CONFIG_ENV_IS_NOWHERE
111 111 #define CONFIG_ENV_IS_IN_MMC
112   -#define CONFIG_SYS_MMC_ENV_DEV 1
  112 +#define CONFIG_SYS_MMC_ENV_DEV 0
113 113 #define CONFIG_SYS_MMC_ENV_PART 2
114 114 #define CONFIG_ENV_OFFSET 0x40000 /* TODO: Adresse definieren */
115 115 #define CONFIG_ENV_OFFSET_REDUND (CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
include/configs/tseries.h
... ... @@ -237,7 +237,7 @@
237 237 #elif defined(CONFIG_EMMC_BOOT)
238 238 #undef CONFIG_ENV_IS_NOWHERE
239 239 #define CONFIG_ENV_IS_IN_MMC
240   -#define CONFIG_SYS_MMC_ENV_DEV 1
  240 +#define CONFIG_SYS_MMC_ENV_DEV 0
241 241 #define CONFIG_SYS_MMC_ENV_PART 2
242 242 #define CONFIG_ENV_OFFSET 0x40000 /* TODO: Adresse definieren */
243 243 #define CONFIG_ENV_OFFSET_REDUND (CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
... ... @@ -54,6 +54,7 @@
54 54 #define COMM_ERR -18 /* Communications Error */
55 55 #define TIMEOUT -19
56 56 #define IN_PROGRESS -20 /* operation is in progress */
  57 +#define SWITCH_ERR -21 /* Card reports failure to switch mode */
57 58  
58 59 #define MMC_CMD_GO_IDLE_STATE 0
59 60 #define MMC_CMD_SEND_OP_COND 1
... ... @@ -70,6 +71,7 @@
70 71 #define MMC_CMD_SET_BLOCKLEN 16
71 72 #define MMC_CMD_READ_SINGLE_BLOCK 17
72 73 #define MMC_CMD_READ_MULTIPLE_BLOCK 18
  74 +#define MMC_CMD_SET_BLOCK_COUNT 23
73 75 #define MMC_CMD_WRITE_SINGLE_BLOCK 24
74 76 #define MMC_CMD_WRITE_MULTIPLE_BLOCK 25
75 77 #define MMC_CMD_ERASE_GROUP_START 35
... ... @@ -109,6 +111,7 @@
109 111 #define SECURE_ERASE 0x80000000
110 112  
111 113 #define MMC_STATUS_MASK (~0x0206BF7F)
  114 +#define MMC_STATUS_SWITCH_ERROR (1 << 7)
112 115 #define MMC_STATUS_RDY_FOR_DATA (1 << 8)
113 116 #define MMC_STATUS_CURR_STATE (0xf << 9)
114 117 #define MMC_STATUS_ERROR (1 << 19)
... ... @@ -225,6 +228,7 @@
225 228 * boot partitions (2), general purpose partitions (4) in MMC v4.4.
226 229 */
227 230 #define MMC_NUM_BOOT_PARTITION 2
  231 +#define MMC_PART_RPMB 3 /* RPMB partition number */
228 232  
229 233 struct mmc_cid {
230 234 unsigned long psn;
... ... @@ -336,7 +340,13 @@
336 340 int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode);
337 341 /* Function to modify the RST_n_FUNCTION field of EXT_CSD */
338 342 int mmc_set_rst_n_function(struct mmc *mmc, u8 enable);
339   -
  343 +/* Functions to read / write the RPMB partition */
  344 +int mmc_rpmb_set_key(struct mmc *mmc, void *key);
  345 +int mmc_rpmb_get_counter(struct mmc *mmc, unsigned long *counter);
  346 +int mmc_rpmb_read(struct mmc *mmc, void *addr, unsigned short blk,
  347 + unsigned short cnt, unsigned char *key);
  348 +int mmc_rpmb_write(struct mmc *mmc, void *addr, unsigned short blk,
  349 + unsigned short cnt, unsigned char *key);
340 350 /**
341 351 * Start device initialization and return immediately; it does not block on
342 352 * polling OCR (operation condition register) status. Then you should call
... ... @@ -103,6 +103,7 @@
103 103 block_dev_desc_t* scsi_get_dev(int dev);
104 104 block_dev_desc_t* usb_stor_get_dev(int dev);
105 105 block_dev_desc_t* mmc_get_dev(int dev);
  106 +int mmc_select_hwpart(int dev_num, int hwpart);
106 107 block_dev_desc_t* systemace_get_dev(int dev);
107 108 block_dev_desc_t* mg_disk_get_dev(int dev);
108 109 block_dev_desc_t *host_get_dev(int dev);
... ... @@ -126,6 +127,7 @@
126 127 static inline block_dev_desc_t* scsi_get_dev(int dev) { return NULL; }
127 128 static inline block_dev_desc_t* usb_stor_get_dev(int dev) { return NULL; }
128 129 static inline block_dev_desc_t* mmc_get_dev(int dev) { return NULL; }
  130 +static inline int mmc_select_hwpart(int dev_num, int hwpart) { return -1; }
129 131 static inline block_dev_desc_t* systemace_get_dev(int dev) { return NULL; }
130 132 static inline block_dev_desc_t* mg_disk_get_dev(int dev) { return NULL; }
131 133 static inline block_dev_desc_t *host_get_dev(int dev) { return NULL; }
... ... @@ -35,6 +35,7 @@
35 35 obj-$(CONFIG_PHYSMEM) += physmem.o
36 36 obj-y += qsort.o
37 37 obj-$(CONFIG_SHA1) += sha1.o
  38 +obj-$(CONFIG_SUPPORT_EMMC_RPMB) += sha256.o
38 39 obj-$(CONFIG_SHA256) += sha256.o
39 40 obj-y += strmhz.o
40 41 obj-$(CONFIG_TPM) += tpm.o