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