cpufunc.h revision 127253
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 127253 2004-03-21 01:41:29Z marcel $
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#define	IA64_FIXED_BREAK	0x84B5D
41
42#ifdef __GNUC__
43
44static __inline void
45breakpoint(void)
46{
47	__asm __volatile("break.m %0" :: "i"(IA64_FIXED_BREAK));
48}
49
50#define	HAVE_INLINE_FFS
51
52static __inline int
53ffs(int mask)
54{
55	return (__builtin_ffs(mask));
56}
57
58#endif
59
60extern uint64_t ia64_port_base;
61#define	__MEMIO_ADDR(x)		(__volatile void*)(IA64_PHYS_TO_RR6(x))
62#define	__PIO_ADDR(x)		(__volatile void*)(ia64_port_base |	\
63	(((x) & 0xFFFC) << 10) | ((x) & 0xFFF))
64
65/*
66 * I/O port reads with ia32 semantics.
67 */
68static __inline uint8_t
69inb(unsigned int port)
70{
71	__volatile uint8_t *p;
72	uint8_t v;
73	p = __PIO_ADDR(port);
74	ia64_mf();
75	v = *p;
76	ia64_mf_a();
77	ia64_mf();
78	return (v);
79}
80
81static __inline uint16_t
82inw(unsigned int port)
83{
84	__volatile uint16_t *p;
85	uint16_t v;
86	p = __PIO_ADDR(port);
87	ia64_mf();
88	v = *p;
89	ia64_mf_a();
90	ia64_mf();
91	return (v);
92}
93
94static __inline uint32_t
95inl(unsigned int port)
96{
97	volatile uint32_t *p;
98	uint32_t v;
99	p = __PIO_ADDR(port);
100	ia64_mf();
101	v = *p;
102	ia64_mf_a();
103	ia64_mf();
104	return (v);
105}
106
107static __inline void
108insb(unsigned int port, void *addr, size_t count)
109{
110	uint8_t *buf = addr;
111	while (count--)
112		*buf++ = inb(port);
113}
114
115static __inline void
116insw(unsigned int port, void *addr, size_t count)
117{
118	uint16_t *buf = addr;
119	while (count--)
120		*buf++ = inw(port);
121}
122
123static __inline void
124insl(unsigned int port, void *addr, size_t count)
125{
126	uint32_t *buf = addr;
127	while (count--)
128		*buf++ = inl(port);
129}
130
131static __inline void
132outb(unsigned int port, uint8_t data)
133{
134	volatile uint8_t *p;
135	p = __PIO_ADDR(port);
136	ia64_mf();
137	*p = data;
138	ia64_mf_a();
139	ia64_mf();
140}
141
142static __inline void
143outw(unsigned int port, uint16_t data)
144{
145	volatile uint16_t *p;
146	p = __PIO_ADDR(port);
147	ia64_mf();
148	*p = data;
149	ia64_mf_a();
150	ia64_mf();
151}
152
153static __inline void
154outl(unsigned int port, uint32_t data)
155{
156	volatile uint32_t *p;
157	p = __PIO_ADDR(port);
158	ia64_mf();
159	*p = data;
160	ia64_mf_a();
161	ia64_mf();
162}
163
164static __inline void
165outsb(unsigned int port, const void *addr, size_t count)
166{
167	const uint8_t *buf = addr;
168	while (count--)
169		outb(port, *buf++);
170}
171
172static __inline void
173outsw(unsigned int port, const void *addr, size_t count)
174{
175	const uint16_t *buf = addr;
176	while (count--)
177		outw(port, *buf++);
178}
179
180static __inline void
181outsl(unsigned int port, const void *addr, size_t count)
182{
183	const uint32_t *buf = addr;
184	while (count--)
185		outl(port, *buf++);
186}
187
188static __inline void
189disable_intr(void)
190{
191	__asm __volatile ("rsm psr.i");
192}
193
194static __inline void
195enable_intr(void)
196{
197	__asm __volatile ("ssm psr.i;; srlz.d");
198}
199
200static __inline register_t
201intr_disable(void)
202{
203	register_t psr;
204	__asm __volatile ("mov %0=psr;;" : "=r"(psr));
205	disable_intr();
206	return ((psr & IA64_PSR_I) ? 1 : 0);
207}
208
209static __inline void
210intr_restore(register_t ie)
211{
212	if (ie)
213		enable_intr();
214}
215
216#endif /* _KERNEL */
217
218#endif /* !_MACHINE_CPUFUNC_H_ */
219