Merge branch 'master' of git://git.denx.de/u-boot-arm
[kernel/u-boot.git] / common / cmd_portio.c
1 /*
2  * (C) Copyright 2003
3  * Marc Singer, elf@buici.com
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 /*
9  * Port I/O Functions
10  *
11  * Copied from FADS ROM, Dan Malek (dmalek@jlc.net)
12  */
13
14 #include <common.h>
15 #include <command.h>
16
17 /* Display values from last command.
18  * Memory modify remembered values are different from display memory.
19  */
20 static uint in_last_addr, in_last_size;
21 static uint out_last_addr, out_last_size, out_last_value;
22
23
24 int do_portio_out (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
25 {
26         uint addr = out_last_addr;
27         uint size = out_last_size;
28         uint value = out_last_value;
29
30         if (argc != 3)
31                 return CMD_RET_USAGE;
32
33         if ((flag & CMD_FLAG_REPEAT) == 0) {
34                 /*
35                  * New command specified.  Check for a size specification.
36                  * Defaults to long if no or incorrect specification.
37                  */
38                 size = cmd_get_data_size (argv[0], 1);
39                 addr = simple_strtoul (argv[1], NULL, 16);
40                 value = simple_strtoul (argv[2], NULL, 16);
41         }
42 #if defined (CONFIG_X86)
43
44         {
45                 unsigned short port = addr;
46
47                 switch (size) {
48                 default:
49                 case 1:
50                     {
51                         unsigned char ch = value;
52                         __asm__ volatile ("out %0, %%dx"::"a" (ch), "d" (port));
53                     }
54                         break;
55                 case 2:
56                     {
57                         unsigned short w = value;
58                         __asm__ volatile ("out %0, %%dx"::"a" (w), "d" (port));
59                     }
60                         break;
61                 case 4:
62                         __asm__ volatile ("out %0, %%dx"::"a" (value), "d" (port));
63
64                         break;
65                 }
66         }
67
68 #endif                                                  /* CONFIG_X86 */
69
70         out_last_addr = addr;
71         out_last_size = size;
72         out_last_value = value;
73
74         return 0;
75 }
76
77 U_BOOT_CMD(
78         out,    3,      1,      do_portio_out,
79         "write datum to IO port",
80         "[.b, .w, .l] port value\n    - output to IO port"
81 );
82
83 int do_portio_in (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
84 {
85         uint addr = in_last_addr;
86         uint size = in_last_size;
87
88         if (argc != 2)
89                 return CMD_RET_USAGE;
90
91         if ((flag & CMD_FLAG_REPEAT) == 0) {
92                 /*
93                  * New command specified.  Check for a size specification.
94                  * Defaults to long if no or incorrect specification.
95                  */
96                 size = cmd_get_data_size (argv[0], 1);
97                 addr = simple_strtoul (argv[1], NULL, 16);
98         }
99 #if defined (CONFIG_X86)
100
101         {
102                 unsigned short port = addr;
103
104                 switch (size) {
105                 default:
106                 case 1:
107                     {
108                         unsigned char ch;
109                         __asm__ volatile ("in %%dx, %0":"=a" (ch):"d" (port));
110
111                         printf (" %02x\n", ch);
112                     }
113                         break;
114                 case 2:
115                     {
116                         unsigned short w;
117                         __asm__ volatile ("in %%dx, %0":"=a" (w):"d" (port));
118
119                         printf (" %04x\n", w);
120                     }
121                         break;
122                 case 4:
123                     {
124                         unsigned long l;
125                         __asm__ volatile ("in %%dx, %0":"=a" (l):"d" (port));
126
127                         printf (" %08lx\n", l);
128                     }
129                         break;
130                 }
131         }
132 #endif  /* CONFIG_X86 */
133
134         in_last_addr = addr;
135         in_last_size = size;
136
137         return 0;
138 }
139
140 U_BOOT_CMD(
141         in,     2,      1,      do_portio_in,
142         "read data from an IO port",
143         "[.b, .w, .l] port\n"
144         "    - read datum from IO port"
145 );