Merge https://source.denx.de/u-boot/custodians/u-boot-spi
[platform/kernel/u-boot.git] / cmd / io.c
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  */
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 = hextoul(argv[1], NULL);
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 = hextoul(argv[2], NULL);
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
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 = hextoul(argv[1], NULL);
106         val = hextoul(argv[2], NULL);
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");