common: fix missing function pointer relocation in fixup_cmdtable()
[platform/kernel/u-boot.git] / common / cmd_portio.c
1 /*
2  * (C) Copyright 2003
3  * Marc Singer, elf@buici.com
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 /*
25  * Port I/O Functions
26  *
27  * Copied from FADS ROM, Dan Malek (dmalek@jlc.net)
28  */
29
30 #include <common.h>
31 #include <command.h>
32
33 /* Display values from last command.
34  * Memory modify remembered values are different from display memory.
35  */
36 static uint in_last_addr, in_last_size;
37 static uint out_last_addr, out_last_size, out_last_value;
38
39
40 int do_portio_out (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
41 {
42         uint addr = out_last_addr;
43         uint size = out_last_size;
44         uint value = out_last_value;
45
46         if (argc != 3)
47                 return cmd_usage(cmdtp);
48
49         if ((flag & CMD_FLAG_REPEAT) == 0) {
50                 /*
51                  * New command specified.  Check for a size specification.
52                  * Defaults to long if no or incorrect specification.
53                  */
54                 size = cmd_get_data_size (argv[0], 1);
55                 addr = simple_strtoul (argv[1], NULL, 16);
56                 value = simple_strtoul (argv[2], NULL, 16);
57         }
58 #if defined (CONFIG_X86)
59
60         {
61                 unsigned short port = addr;
62
63                 switch (size) {
64                 default:
65                 case 1:
66                     {
67                         unsigned char ch = value;
68                         __asm__ volatile ("out %0, %%dx"::"a" (ch), "d" (port));
69                     }
70                         break;
71                 case 2:
72                     {
73                         unsigned short w = value;
74                         __asm__ volatile ("out %0, %%dx"::"a" (w), "d" (port));
75                     }
76                         break;
77                 case 4:
78                         __asm__ volatile ("out %0, %%dx"::"a" (value), "d" (port));
79
80                         break;
81                 }
82         }
83
84 #endif                                                  /* CONFIG_X86 */
85
86         out_last_addr = addr;
87         out_last_size = size;
88         out_last_value = value;
89
90         return 0;
91 }
92
93 U_BOOT_CMD(
94         out,    3,      1,      do_portio_out,
95         "write datum to IO port",
96         "[.b, .w, .l] port value\n    - output to IO port"
97 );
98
99 int do_portio_in (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
100 {
101         uint addr = in_last_addr;
102         uint size = in_last_size;
103
104         if (argc != 2)
105                 return cmd_usage(cmdtp);
106
107         if ((flag & CMD_FLAG_REPEAT) == 0) {
108                 /*
109                  * New command specified.  Check for a size specification.
110                  * Defaults to long if no or incorrect specification.
111                  */
112                 size = cmd_get_data_size (argv[0], 1);
113                 addr = simple_strtoul (argv[1], NULL, 16);
114         }
115 #if defined (CONFIG_X86)
116
117         {
118                 unsigned short port = addr;
119
120                 switch (size) {
121                 default:
122                 case 1:
123                     {
124                         unsigned char ch;
125                         __asm__ volatile ("in %%dx, %0":"=a" (ch):"d" (port));
126
127                         printf (" %02x\n", ch);
128                     }
129                         break;
130                 case 2:
131                     {
132                         unsigned short w;
133                         __asm__ volatile ("in %%dx, %0":"=a" (w):"d" (port));
134
135                         printf (" %04x\n", w);
136                     }
137                         break;
138                 case 4:
139                     {
140                         unsigned long l;
141                         __asm__ volatile ("in %%dx, %0":"=a" (l):"d" (port));
142
143                         printf (" %08lx\n", l);
144                     }
145                         break;
146                 }
147         }
148 #endif  /* CONFIG_X86 */
149
150         in_last_addr = addr;
151         in_last_size = size;
152
153         return 0;
154 }
155
156 U_BOOT_CMD(
157         in,     2,      1,      do_portio_in,
158         "read data from an IO port",
159         "[.b, .w, .l] port\n"
160         "    - read datum from IO port"
161 );