blob: fecfadaa1faf8024eb4dba7a6f70a73d8f435e23 [file] [log] [blame]
Kenneth Watersff048ea2012-12-05 14:46:30 +00001/*
2 * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 *
6 * Alternatively, this software may be distributed under the terms of the
7 * GNU General Public License ("GPL") version 2 as published by the Free
8 * Software Foundation.
9 */
10
11#include <common.h>
12#include <command.h>
Simon Glasse1410752022-07-30 15:52:15 -060013#include <mapmem.h>
Kenneth Watersff048ea2012-12-05 14:46:30 +000014#include <part.h>
15
Simon Glass09140112020-05-10 11:40:03 -060016int do_read(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
Kenneth Watersff048ea2012-12-05 14:46:30 +000017{
18 char *ep;
Simon Glass4101f682016-02-29 15:25:34 -070019 struct blk_desc *dev_desc = NULL;
Kenneth Watersff048ea2012-12-05 14:46:30 +000020 int dev;
21 int part = 0;
Simon Glass05289792020-05-10 11:39:57 -060022 struct disk_partition part_info;
Kenneth Watersff048ea2012-12-05 14:46:30 +000023 ulong offset = 0u;
24 ulong limit = 0u;
25 void *addr;
26 uint blk;
27 uint cnt;
28
29 if (argc != 6) {
30 cmd_usage(cmdtp);
31 return 1;
32 }
33
Simon Glass7e5f4602021-07-24 09:03:29 -060034 dev = (int)hextoul(argv[2], &ep);
Kenneth Watersff048ea2012-12-05 14:46:30 +000035 if (*ep) {
36 if (*ep != ':') {
37 printf("Invalid block device %s\n", argv[2]);
38 return 1;
39 }
Simon Glass7e5f4602021-07-24 09:03:29 -060040 part = (int)hextoul(++ep, NULL);
Kenneth Watersff048ea2012-12-05 14:46:30 +000041 }
42
Simon Glassdb1d9e72016-02-29 15:25:42 -070043 dev_desc = blk_get_dev(argv[1], dev);
Kenneth Watersff048ea2012-12-05 14:46:30 +000044 if (dev_desc == NULL) {
45 printf("Block device %s %d not supported\n", argv[1], dev);
46 return 1;
47 }
48
Simon Glasse1410752022-07-30 15:52:15 -060049 addr = map_sysmem(hextoul(argv[3], NULL), 0);
Simon Glass7e5f4602021-07-24 09:03:29 -060050 blk = hextoul(argv[4], NULL);
51 cnt = hextoul(argv[5], NULL);
Kenneth Watersff048ea2012-12-05 14:46:30 +000052
53 if (part != 0) {
Simon Glass3e8bd462016-02-29 15:25:48 -070054 if (part_get_info(dev_desc, part, &part_info)) {
Kenneth Watersff048ea2012-12-05 14:46:30 +000055 printf("Cannot find partition %d\n", part);
56 return 1;
57 }
58 offset = part_info.start;
59 limit = part_info.size;
60 } else {
Simon Glass4101f682016-02-29 15:25:34 -070061 /* Largest address not available in struct blk_desc. */
Kenneth Watersff048ea2012-12-05 14:46:30 +000062 limit = ~0;
63 }
64
65 if (cnt + blk > limit) {
66 printf("Read out of range\n");
67 return 1;
68 }
69
Tom Rinid03618d2017-08-14 20:58:50 -040070 if (blk_dread(dev_desc, offset + blk, cnt, addr) != cnt) {
Kenneth Watersff048ea2012-12-05 14:46:30 +000071 printf("Error reading blocks\n");
72 return 1;
73 }
74
75 return 0;
76}
77
78U_BOOT_CMD(
79 read, 6, 0, do_read,
80 "Load binary data from a partition",
81 "<interface> <dev[:part]> addr blk# cnt"
82);