1/*	$NetBSD: cpufunc.h,v 1.3 2009/07/20 04:41:37 kiyohara 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
40struct thread;
41
42#define	IA64_FIXED_BREAK	0x84B5D
43
44#ifdef __GNUC__
45
46static __inline void
47breakpoint(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
58extern 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 */
66static __inline uint8_t
67inb(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
79static __inline uint16_t
80inw(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
93static __inline uint32_t
94inl(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
107static __inline void
108insb(unsigned int port, void *addr, size_t count)
109{
110	uint8_t *buf = addr;
111
112	while (count--)
113		*buf++ = inb(port);
114}
115
116static __inline void
117insw(unsigned int port, void *addr, size_t count)
118{
119	uint16_t *buf = addr;
120
121	while (count--)
122		*buf++ = inw(port);
123}
124
125static __inline void
126insl(unsigned int port, void *addr, size_t count)
127{
128	uint32_t *buf = addr;
129
130	while (count--)
131		*buf++ = inl(port);
132}
133
134static __inline void
135outb(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
146static __inline void
147outw(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
158static __inline void
159outl(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
170static __inline void
171outsb(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
179static __inline void
180outsw(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
188static __inline void
189outsl(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
197static __inline void
198disable_intr(void)
199{
200
201	__asm __volatile ("rsm psr.i");
202}
203
204static __inline void
205enable_intr(void)
206{
207
208	__asm __volatile ("ssm psr.i;; srlz.d");
209}
210
211static __inline register_t
212intr_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
221static __inline void
222intr_restore(register_t ie)
223{
224
225	if (ie)
226		enable_intr();
227}
228
229#endif /* _KERNEL */
230
231#endif /* !_MACHINE_CPUFUNC_H_ */
232