]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - common/cmd_portio.c
* Patch by Marc Singer, 29 May 2003:
[karo-tx-uboot.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 #include <cmd_portio.h>
33
34 #if (CONFIG_COMMANDS & CFG_CMD_PORTIO)
35
36 extern int cmd_get_data_size (char *arg, int default_size);
37
38 /* Display values from last command.
39  * Memory modify remembered values are different from display memory.
40  */
41 static uint in_last_addr, in_last_size;
42 static uint out_last_addr, out_last_size, out_last_value;
43
44
45 int do_portio_out (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
46 {
47         uint addr = out_last_addr;
48         uint size = out_last_size;
49         uint value = out_last_value;
50
51         if (argc != 3) {
52                 printf ("Usage:\n%s\n", cmdtp->usage);
53                 return 1;
54         }
55
56         if ((flag & CMD_FLAG_REPEAT) == 0) {
57                 /* New command specified.  Check for a size specification.
58                  * Defaults to long if no or incorrect specification.
59                  */
60                 size = cmd_get_data_size (argv[0], 1);
61                 addr = simple_strtoul (argv[1], NULL, 16);
62                 value = simple_strtoul (argv[2], NULL, 16);
63         }
64 #if defined (CONFIG_X86)
65
66         {
67                 unsigned short port = addr;
68
69                 switch (size) {
70                 default:
71                 case 1:
72                     {
73                         unsigned char ch = value;
74                         __asm__ volatile ("out %0, %%dx"::"a" (ch), "d" (port));
75                     }
76                         break;
77                 case 2:
78                     {
79                         unsigned short w = value;
80                         __asm__ volatile ("out %0, %%dx"::"a" (w), "d" (port));
81                     }
82                         break;
83                 case 4:
84                         __asm__ volatile ("out %0, %%dx"::"a" (value), "d" (port));
85
86                         break;
87                 }
88         }
89
90 #endif                                                  /* CONFIG_X86 */
91
92         out_last_addr = addr;
93         out_last_size = size;
94         out_last_value = value;
95
96         return 0;
97 }
98
99 int do_portio_in (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
100 {
101         uint addr = in_last_addr;
102         uint size = in_last_size;
103
104         if (argc != 2) {
105                 printf ("Usage:\n%s\n", cmdtp->usage);
106                 return 1;
107         }
108
109         if ((flag & CMD_FLAG_REPEAT) == 0) {
110                 /* New command specified.  Check for a size specification.
111                  * Defaults to long if no or incorrect specification.
112                  */
113                 size = cmd_get_data_size (argv[0], 1);
114                 addr = simple_strtoul (argv[1], NULL, 16);
115         }
116 #if defined (CONFIG_X86)
117
118         {
119                 unsigned short port = addr;
120
121                 switch (size) {
122                 default:
123                 case 1:
124                     {
125                         unsigned char ch;
126                         __asm__ volatile ("in %%dx, %0":"=a" (ch):"d" (port));
127
128                         printf (" %02x\n", ch);
129                     }
130                         break;
131                 case 2:
132                     {
133                         unsigned short w;
134                         __asm__ volatile ("in %%dx, %0":"=a" (w):"d" (port));
135
136                         printf (" %04x\n", w);
137                     }
138                         break;
139                 case 4:
140                     {
141                         unsigned long l;
142                         __asm__ volatile ("in %%dx, %0":"=a" (l):"d" (port));
143
144                         printf (" %08lx\n", l);
145                     }
146                         break;
147                 }
148         }
149 #endif  /* CONFIG_X86 */
150
151         in_last_addr = addr;
152         in_last_size = size;
153
154         return 0;
155 }
156
157 #endif  /* CFG_CMD_PORTIO */