blob: c7e964153b89a3dabca727e9707975418ea4e72a [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Vadim Bendebury9ad557b2012-12-05 14:46:42 +00002/*
3 * Copyright (c) 2012 The Chromium OS Authors.
Vadim Bendebury9ad557b2012-12-05 14:46:42 +00004 */
5
6/*
7 * IO space access commands.
8 */
9
10#include <common.h>
11#include <command.h>
12#include <asm/io.h>
13
Simon Glass9da37762019-09-25 08:56:25 -060014/* Display values from last command */
15static ulong last_addr, last_size;
16static ulong last_length = 0x40;
17static ulong base_address;
18
19#define DISP_LINE_LEN 16
20
Vadim Bendebury9ad557b2012-12-05 14:46:42 +000021/*
22 * IO Display
23 *
24 * Syntax:
25 * iod{.b, .w, .l} {addr}
26 */
Simon Glass09140112020-05-10 11:40:03 -060027int do_io_iod(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
Vadim Bendebury9ad557b2012-12-05 14:46:42 +000028{
Simon Glass9da37762019-09-25 08:56:25 -060029 ulong addr, length, bytes;
30 u8 buf[DISP_LINE_LEN];
31 int size, todo;
Vadim Bendebury9ad557b2012-12-05 14:46:42 +000032
Simon Glass9da37762019-09-25 08:56:25 -060033 /*
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)
Vadim Bendebury9ad557b2012-12-05 14:46:42 +000042 return CMD_RET_USAGE;
43
Simon Glass9da37762019-09-25 08:56:25 -060044 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;
Vadim Bendebury9ad557b2012-12-05 14:46:42 +000052
Simon Glass9da37762019-09-25 08:56:25 -060053 /* Address is specified since argc > 1 */
54 addr = simple_strtoul(argv[1], NULL, 16);
55 addr += base_address;
Vadim Bendebury9ad557b2012-12-05 14:46:42 +000056
Simon Glass9da37762019-09-25 08:56:25 -060057 /*
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 }
Vadim Bendebury9ad557b2012-12-05 14:46:42 +000064
Simon Glass9da37762019-09-25 08:56:25 -060065 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;
Vadim Bendebury9ad557b2012-12-05 14:46:42 +000089
90 return 0;
91}
92
Simon Glass09140112020-05-10 11:40:03 -060093int do_io_iow(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
Vadim Bendebury9ad557b2012-12-05 14:46:42 +000094{
Tom Rini9398b8c2017-05-10 15:20:13 -040095 ulong addr, val;
96 int size;
Vadim Bendebury9ad557b2012-12-05 14:46:42 +000097
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/**************************************************/
Simon Glass9da37762019-09-25 08:56:25 -0600119U_BOOT_CMD(iod, 3, 1, do_io_iod,
Bin Mengd6418192014-10-20 16:14:53 +0800120 "IO space display", "[.b, .w, .l] address");
Vadim Bendebury9ad557b2012-12-05 14:46:42 +0000121
122U_BOOT_CMD(iow, 3, 0, do_io_iow,
Bin Mengd6418192014-10-20 16:14:53 +0800123 "IO space modify",
124 "[.b, .w, .l] address value");