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 
do_portio_out(cmd_tbl_t * cmdtp,int flag,int argc,char * argv[])40 int do_portio_out (cmd_tbl_t * cmdtp, int flag, int argc, char *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 		cmd_usage(cmdtp);
48 		return 1;
49 	}
50 
51 	if ((flag & CMD_FLAG_REPEAT) == 0) {
52 		/* New command specified.  Check for a size specification.
53 		 * Defaults to long if no or incorrect specification.
54 		 */
55 		size = cmd_get_data_size (argv[0], 1);
56 		addr = simple_strtoul (argv[1], NULL, 16);
57 		value = simple_strtoul (argv[2], NULL, 16);
58 	}
59 #if defined (CONFIG_X86)
60 
61 	{
62 		unsigned short port = addr;
63 
64 		switch (size) {
65 		default:
66 		case 1:
67 		    {
68 			unsigned char ch = value;
69 			__asm__ volatile ("out %0, %%dx"::"a" (ch), "d" (port));
70 		    }
71 			break;
72 		case 2:
73 		    {
74 			unsigned short w = value;
75 			__asm__ volatile ("out %0, %%dx"::"a" (w), "d" (port));
76 		    }
77 			break;
78 		case 4:
79 			__asm__ volatile ("out %0, %%dx"::"a" (value), "d" (port));
80 
81 			break;
82 		}
83 	}
84 
85 #endif							/* CONFIG_X86 */
86 
87 	out_last_addr = addr;
88 	out_last_size = size;
89 	out_last_value = value;
90 
91 	return 0;
92 }
93 
94 U_BOOT_CMD(
95 	out,	3,	1,	do_portio_out,
96 	"write datum to IO port",
97 	"[.b, .w, .l] port value\n    - output to IO port"
98 );
99 
do_portio_in(cmd_tbl_t * cmdtp,int flag,int argc,char * argv[])100 int do_portio_in (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
101 {
102 	uint addr = in_last_addr;
103 	uint size = in_last_size;
104 
105 	if (argc != 2) {
106 		cmd_usage(cmdtp);
107 		return 1;
108 	}
109 
110 	if ((flag & CMD_FLAG_REPEAT) == 0) {
111 		/* New command specified.  Check for a size specification.
112 		 * Defaults to long if no or incorrect specification.
113 		 */
114 		size = cmd_get_data_size (argv[0], 1);
115 		addr = simple_strtoul (argv[1], NULL, 16);
116 	}
117 #if defined (CONFIG_X86)
118 
119 	{
120 		unsigned short port = addr;
121 
122 		switch (size) {
123 		default:
124 		case 1:
125 		    {
126 			unsigned char ch;
127 			__asm__ volatile ("in %%dx, %0":"=a" (ch):"d" (port));
128 
129 			printf (" %02x\n", ch);
130 		    }
131 			break;
132 		case 2:
133 		    {
134 			unsigned short w;
135 			__asm__ volatile ("in %%dx, %0":"=a" (w):"d" (port));
136 
137 			printf (" %04x\n", w);
138 		    }
139 			break;
140 		case 4:
141 		    {
142 			unsigned long l;
143 			__asm__ volatile ("in %%dx, %0":"=a" (l):"d" (port));
144 
145 			printf (" %08lx\n", l);
146 		    }
147 			break;
148 		}
149 	}
150 #endif	/* CONFIG_X86 */
151 
152 	in_last_addr = addr;
153 	in_last_size = size;
154 
155 	return 0;
156 }
157 
158 U_BOOT_CMD(
159 	in,	2,	1,	do_portio_in,
160 	"read data from an IO port",
161 	"[.b, .w, .l] port\n"
162 	"    - read datum from IO port"
163 );
164