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