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