1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (c) 2012 The Chromium OS Authors.
4 */
5
6 /*
7 * IO space access commands.
8 */
9
10 #include <common.h>
11 #include <command.h>
12 #include <asm/io.h>
13
14 /* Display values from last command */
15 static ulong last_addr, last_size;
16 static ulong last_length = 0x40;
17 static ulong base_address;
18
19 #define DISP_LINE_LEN 16
20
21 /*
22 * IO Display
23 *
24 * Syntax:
25 * iod{.b, .w, .l} {addr}
26 */
do_io_iod(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])27 int do_io_iod(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
28 {
29 ulong addr, length, bytes;
30 u8 buf[DISP_LINE_LEN];
31 int size, todo;
32
33 /*
34 * We use the last specified parameters, unless new ones are
35 * entered.
36 */
37 addr = last_addr;
38 size = last_size;
39 length = last_length;
40
41 if (argc < 2)
42 return CMD_RET_USAGE;
43
44 if ((flag & CMD_FLAG_REPEAT) == 0) {
45 /*
46 * New command specified. Check for a size specification.
47 * Defaults to long if no or incorrect specification.
48 */
49 size = cmd_get_data_size(argv[0], 4);
50 if (size < 0)
51 return 1;
52
53 /* Address is specified since argc > 1 */
54 addr = simple_strtoul(argv[1], NULL, 16);
55 addr += base_address;
56
57 /*
58 * If another parameter, it is the length to display.
59 * Length is the number of objects, not number of bytes.
60 */
61 if (argc > 2)
62 length = simple_strtoul(argv[2], NULL, 16);
63 }
64
65 bytes = size * length;
66
67 /* Print the lines */
68 for (; bytes > 0; addr += todo) {
69 u8 *ptr = buf;
70 int i;
71
72 todo = min(bytes, (ulong)DISP_LINE_LEN);
73 for (i = 0; i < todo; i += size, ptr += size) {
74 if (size == 4)
75 *(u32 *)ptr = inl(addr + i);
76 else if (size == 2)
77 *(u16 *)ptr = inw(addr + i);
78 else
79 *ptr = inb(addr + i);
80 }
81 print_buffer(addr, buf, size, todo / size,
82 DISP_LINE_LEN / size);
83 bytes -= todo;
84 }
85
86 last_addr = addr;
87 last_length = length;
88 last_size = size;
89
90 return 0;
91 }
92
do_io_iow(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])93 int do_io_iow(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
94 {
95 ulong addr, val;
96 int size;
97
98 if (argc != 3)
99 return CMD_RET_USAGE;
100
101 size = cmd_get_data_size(argv[0], 4);
102 if (size < 0)
103 return 1;
104
105 addr = simple_strtoul(argv[1], NULL, 16);
106 val = simple_strtoul(argv[2], NULL, 16);
107
108 if (size == 4)
109 outl((u32) val, addr);
110 else if (size == 2)
111 outw((u16) val, addr);
112 else
113 outb((u8) val, addr);
114
115 return 0;
116 }
117
118 /**************************************************/
119 U_BOOT_CMD(iod, 3, 1, do_io_iod,
120 "IO space display", "[.b, .w, .l] address");
121
122 U_BOOT_CMD(iow, 3, 0, do_io_iow,
123 "IO space modify",
124 "[.b, .w, .l] address value");
125