1 #ifndef _ASM_IO_H
2 #define _ASM_IO_H
3 
4 #include "asm/types.h"
5 #include "asi.h"
6 
7 #define NO_QEMU_PROTOS
8 #include "arch/common/fw_cfg.h"
9 
10 extern unsigned long va_shift; // Set in entry.S
11 // Defined in ldscript
12 extern char _start, _data, _stack, _estack, _fcstack, _efcstack, _end, _iomem;
13 
14 // XXX check use and merge
15 #define phys_to_virt(phys) ((void *) ((unsigned long) (phys)))
16 #define virt_to_phys(virt) ((unsigned long) (virt))
17 
18 #ifndef BOOTSTRAP
19 
20 extern unsigned long isa_io_base;
21 
22 /*
23  * The insw/outsw/insl/outsl macros don't do byte-swapping.
24  * They are only used in practice for transferring buffers which
25  * are arrays of bytes, and byte-swapping is not appropriate in
26  * that case.  - paulus
27  */
28 #define insw(port, buf, ns)	_insw_ns((uint16_t *)((port)+isa_io_base), (buf), (ns))
29 #define outsw(port, buf, ns)	_outsw_ns((uint16_t *)((port)+isa_io_base), (buf), (ns))
30 
31 #define inb(port)		in_8((uint8_t *)((port)+isa_io_base))
32 #define outb(val, port)		out_8((uint8_t *)((port)+isa_io_base), (val))
33 #define inw(port)		in_le16((uint16_t *)((port)+isa_io_base))
34 #define outw(val, port)		out_le16((uint16_t *)((port)+isa_io_base), (val))
35 #define inl(port)		in_le32((uint32_t *)((port)+isa_io_base))
36 #define outl(val, port)		out_le32((uint32_t *)((port)+isa_io_base), (val))
37 
38 /*
39  * 8, 16 and 32 bit, big and little endian I/O operations, with barrier.
40  */
in_8(volatile unsigned char * addr)41 static inline int in_8(volatile unsigned char *addr)
42 {
43     int ret;
44 
45     __asm__ __volatile__("lduba [%1] %2, %0\n\t"
46                          : "=r"(ret)
47                          : "r"(addr), "i" (ASI_PHYS_BYPASS_EC_E)
48                          : "memory");
49 
50     return ret;
51 }
52 
out_8(volatile unsigned char * addr,int val)53 static inline void out_8(volatile unsigned char *addr, int val)
54 {
55     __asm__ __volatile__("stba %0, [%1] %2\n\t"
56                          :
57                          : "r"(val), "r"(addr), "i" (ASI_PHYS_BYPASS_EC_E)
58                          : "memory");
59 }
60 
in_be16(volatile unsigned short * addr)61 static inline int in_be16(volatile unsigned short *addr)
62 {
63     int ret;
64 
65     __asm__ __volatile__("lduha [%1] %2, %0\n\t"
66                          : "=r"(ret)
67                          : "r"(addr), "i" (ASI_PHYS_BYPASS_EC_E)
68                          : "memory");
69 
70     return ret;
71 }
72 
in_le16(volatile unsigned short * addr)73 static inline int in_le16(volatile unsigned short *addr)
74 {
75     int ret;
76 
77     __asm__ __volatile__("lduha [%1] %2, %0\n\t"
78                          : "=r"(ret)
79                          : "r"(addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
80                          : "memory");
81 
82     return ret;
83 }
84 
out_be16(volatile unsigned short * addr,int val)85 static inline void out_be16(volatile unsigned short *addr, int val)
86 {
87 
88     __asm__ __volatile__("stha %0, [%1] %2\n\t"
89                          :
90                          : "r"(val), "r"(addr), "i" (ASI_PHYS_BYPASS_EC_E)
91                          : "memory");
92 }
93 
out_le16(volatile unsigned short * addr,int val)94 static inline void out_le16(volatile unsigned short *addr, int val)
95 {
96     __asm__ __volatile__("stha %0, [%1] %2\n\t"
97                          :
98                          : "r"(val), "r"(addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
99                          : "memory");
100 }
101 
in_be32(volatile unsigned * addr)102 static inline unsigned in_be32(volatile unsigned *addr)
103 {
104     unsigned ret;
105 
106     __asm__ __volatile__("lduwa [%1] %2, %0\n\t"
107                          : "=r"(ret)
108                          : "r"(addr), "i" (ASI_PHYS_BYPASS_EC_E)
109                          : "memory");
110 
111     return ret;
112 }
113 
in_le32(volatile unsigned * addr)114 static inline unsigned in_le32(volatile unsigned *addr)
115 {
116     unsigned ret;
117 
118     __asm__ __volatile__("lduwa [%1] %2, %0\n\t"
119                          : "=r"(ret)
120                          : "r"(addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
121                          : "memory");
122     return ret;
123 }
124 
out_be32(volatile unsigned * addr,int val)125 static inline void out_be32(volatile unsigned *addr, int val)
126 {
127     __asm__ __volatile__("stwa %0, [%1] %2\n\t"
128                          :
129                          : "r"(val), "r"(addr), "i" (ASI_PHYS_BYPASS_EC_E)
130                          : "memory");
131 }
132 
out_le32(volatile unsigned * addr,int val)133 static inline void out_le32(volatile unsigned *addr, int val)
134 {
135     __asm__ __volatile__("stwa %0, [%1] %2\n\t"
136                          :
137                          : "r"(val), "r"(addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
138                          : "memory");
139 }
140 
_insw_ns(volatile uint16_t * port,void * buf,int ns)141 static inline void _insw_ns(volatile uint16_t * port, void *buf, int ns)
142 {
143 	uint16_t *b = (uint16_t *) buf;
144 
145 	while (ns > 0) {
146 		*b++ = in_be16(port);
147 		ns--;
148 	}
149 }
150 
_outsw_ns(volatile uint16_t * port,const void * buf,int ns)151 static inline void _outsw_ns(volatile uint16_t * port, const void *buf,
152 			     int ns)
153 {
154 	uint16_t *b = (uint16_t *) buf;
155 
156 	while (ns > 0) {
157 		out_be16(port, *b++);
158 		ns--;
159 	}
160 }
161 
_insw(volatile uint16_t * port,void * buf,int ns)162 static inline void _insw(volatile uint16_t * port, void *buf, int ns)
163 {
164 	uint16_t *b = (uint16_t *) buf;
165 
166 	while (ns > 0) {
167 		*b++ = in_le16(port);
168 		ns--;
169 	}
170 }
171 
_outsw(volatile uint16_t * port,const void * buf,int ns)172 static inline void _outsw(volatile uint16_t * port, const void *buf,
173 			  int ns)
174 {
175 	uint16_t *b = (uint16_t *) buf;
176 
177 	while (ns > 0) {
178 		out_le16(port, *b++);
179 		ns--;
180 	}
181 }
182 #else /* BOOTSTRAP */
183 #ifdef FCOMPILER
184 #define inb(reg) ((u8)0xff)
185 #define inw(reg) ((u16)0xffff)
186 #define inl(reg) ((u32)0xffffffff)
187 #define outb(reg, val) do{} while(0)
188 #define outw(reg, val) do{} while(0)
189 #define outl(reg, val) do{} while(0)
190 #else
191 extern u8 inb(u32 reg);
192 extern u16 inw(u32 reg);
193 extern u32 inl(u32 reg);
194 extern void insw(u32 reg, void *addr, unsigned long count);
195 extern void outb(u32 reg, u8 val);
196 extern void outw(u32 reg, u16 val);
197 extern void outl(u32 reg, u32 val);
198 extern void outsw(u32 reg, const void *addr, unsigned long count);
199 #endif
200 #endif
201 
202 #if defined(CONFIG_QEMU)
203 #define FW_CFG_ARCH_WIDTH        (FW_CFG_ARCH_LOCAL + 0x00)
204 #define FW_CFG_ARCH_HEIGHT       (FW_CFG_ARCH_LOCAL + 0x01)
205 #define FW_CFG_ARCH_DEPTH        (FW_CFG_ARCH_LOCAL + 0x02)
206 #endif
207 
208 #endif /* _ASM_IO_H */
209