1 /* $NetBSD: cpufunc.h,v 1.4 2010/07/24 09:35:36 jruoho Exp $ */
2
3 /*-
4 * Copyright (c) 1998 Doug Rabson
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $FreeBSD$
29 */
30
31 #ifndef _MACHINE_CPUFUNC_H_
32 #define _MACHINE_CPUFUNC_H_
33
34 #ifdef _KERNEL
35
36 #include <sys/types.h>
37 #include <machine/ia64_cpu.h>
38 #include <machine/vmparam.h>
39
40 struct thread;
41
42 #define IA64_FIXED_BREAK 0x84B5D
43
44 #ifdef __GNUC__
45
46 static __inline void
breakpoint(void)47 breakpoint(void)
48 {
49
50 __asm __volatile("break.m %0" :: "i"(IA64_FIXED_BREAK));
51 }
52
53 #define HAVE_INLINE_FFS
54 #define ffs(x) __builtin_ffs(x)
55
56 #endif
57
58 extern uint64_t ia64_port_base;
59 #define __MEMIO_ADDR(x) (__volatile void*)(IA64_PHYS_TO_RR6(x))
60 #define __PIO_ADDR(x) (__volatile void*)(ia64_port_base | \
61 (((x) & 0xFFFC) << 10) | ((x) & 0xFFF))
62
63 /*
64 * I/O port reads with ia32 semantics.
65 */
66 static __inline uint8_t
inb(unsigned int port)67 inb(unsigned int port)
68 {
69 __volatile uint8_t *p;
70 uint8_t v;
71 p = __PIO_ADDR(port);
72 ia64_mf();
73 v = *p;
74 ia64_mf_a();
75 ia64_mf();
76 return v;
77 }
78
79 static __inline uint16_t
inw(unsigned int port)80 inw(unsigned int port)
81 {
82 __volatile uint16_t *p;
83 uint16_t v;
84
85 p = __PIO_ADDR(port);
86 ia64_mf();
87 v = *p;
88 ia64_mf_a();
89 ia64_mf();
90 return v;
91 }
92
93 static __inline uint32_t
inl(unsigned int port)94 inl(unsigned int port)
95 {
96 volatile uint32_t *p;
97 uint32_t v;
98
99 p = __PIO_ADDR(port);
100 ia64_mf();
101 v = *p;
102 ia64_mf_a();
103 ia64_mf();
104 return v;
105 }
106
107 static __inline void
insb(unsigned int port,void * addr,size_t count)108 insb(unsigned int port, void *addr, size_t count)
109 {
110 uint8_t *buf = addr;
111
112 while (count--)
113 *buf++ = inb(port);
114 }
115
116 static __inline void
insw(unsigned int port,void * addr,size_t count)117 insw(unsigned int port, void *addr, size_t count)
118 {
119 uint16_t *buf = addr;
120
121 while (count--)
122 *buf++ = inw(port);
123 }
124
125 static __inline void
insl(unsigned int port,void * addr,size_t count)126 insl(unsigned int port, void *addr, size_t count)
127 {
128 uint32_t *buf = addr;
129
130 while (count--)
131 *buf++ = inl(port);
132 }
133
134 static __inline void
outb(unsigned int port,uint8_t data)135 outb(unsigned int port, uint8_t data)
136 {
137 volatile uint8_t *p;
138
139 p = __PIO_ADDR(port);
140 ia64_mf();
141 *p = data;
142 ia64_mf_a();
143 ia64_mf();
144 }
145
146 static __inline void
outw(unsigned int port,uint16_t data)147 outw(unsigned int port, uint16_t data)
148 {
149 volatile uint16_t *p;
150
151 p = __PIO_ADDR(port);
152 ia64_mf();
153 *p = data;
154 ia64_mf_a();
155 ia64_mf();
156 }
157
158 static __inline void
outl(unsigned int port,uint32_t data)159 outl(unsigned int port, uint32_t data)
160 {
161 volatile uint32_t *p;
162
163 p = __PIO_ADDR(port);
164 ia64_mf();
165 *p = data;
166 ia64_mf_a();
167 ia64_mf();
168 }
169
170 static __inline void
outsb(unsigned int port,const void * addr,size_t count)171 outsb(unsigned int port, const void *addr, size_t count)
172 {
173 const uint8_t *buf = addr;
174
175 while (count--)
176 outb(port, *buf++);
177 }
178
179 static __inline void
outsw(unsigned int port,const void * addr,size_t count)180 outsw(unsigned int port, const void *addr, size_t count)
181 {
182 const uint16_t *buf = addr;
183
184 while (count--)
185 outw(port, *buf++);
186 }
187
188 static __inline void
outsl(unsigned int port,const void * addr,size_t count)189 outsl(unsigned int port, const void *addr, size_t count)
190 {
191 const uint32_t *buf = addr;
192
193 while (count--)
194 outl(port, *buf++);
195 }
196
197 static __inline void
disable_intr(void)198 disable_intr(void)
199 {
200
201 __asm __volatile ("rsm psr.i");
202 }
203
204 static __inline void
enable_intr(void)205 enable_intr(void)
206 {
207
208 __asm __volatile ("ssm psr.i;; srlz.d");
209 }
210
211 static __inline register_t
intr_disable(void)212 intr_disable(void)
213 {
214 register_t psr;
215
216 __asm __volatile ("mov %0=psr;;" : "=r"(psr));
217 disable_intr();
218 return (psr & IA64_PSR_I) ? 1 : 0;
219 }
220
221 static __inline void
intr_restore(register_t ie)222 intr_restore(register_t ie)
223 {
224
225 if (ie)
226 enable_intr();
227 }
228
229 #endif /* _KERNEL */
230
231 #endif /* !_MACHINE_CPUFUNC_H_ */
232