cpufunc.h revision 124478
166458Sdfr/*-
266458Sdfr * Copyright (c) 1998 Doug Rabson
366458Sdfr * All rights reserved.
466458Sdfr *
566458Sdfr * Redistribution and use in source and binary forms, with or without
666458Sdfr * modification, are permitted provided that the following conditions
766458Sdfr * are met:
866458Sdfr * 1. Redistributions of source code must retain the above copyright
966458Sdfr *    notice, this list of conditions and the following disclaimer.
1066458Sdfr * 2. Redistributions in binary form must reproduce the above copyright
1166458Sdfr *    notice, this list of conditions and the following disclaimer in the
1266458Sdfr *    documentation and/or other materials provided with the distribution.
1366458Sdfr *
1466458Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1566458Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1666458Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1766458Sdfr * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1866458Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1966458Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2066458Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2166458Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2266458Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2366458Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2466458Sdfr * SUCH DAMAGE.
2566458Sdfr *
2666458Sdfr * $FreeBSD: head/sys/ia64/include/cpufunc.h 124478 2004-01-13 15:30:36Z des $
2766458Sdfr */
2866458Sdfr
2966458Sdfr#ifndef _MACHINE_CPUFUNC_H_
3066458Sdfr#define _MACHINE_CPUFUNC_H_
3166458Sdfr
3266458Sdfr#ifdef _KERNEL
3366458Sdfr
3466458Sdfr#include <sys/types.h>
3583511Sdfr#include <machine/ia64_cpu.h>
3696912Smarcel#include <machine/vmparam.h>
3766458Sdfr
3893264Sdillonstruct thread;
3988088Sjhb
4066458Sdfr#ifdef __GNUC__
4166458Sdfr
4266458Sdfrstatic __inline void
4366458Sdfrbreakpoint(void)
4466458Sdfr{
4566458Sdfr	__asm __volatile("break 0x80100"); /* XXX use linux value */
4666458Sdfr}
4766458Sdfr
48123419Speter
49124478Sdes#define	HAVE_INLINE_FFS
50123419Speter
51123419Speterstatic __inline int
52123419Speterffs(int mask)
53123419Speter{
54123419Speter	return (__builtin_ffs(mask));
55123419Speter}
56123419Speter
5766458Sdfr#endif
5866458Sdfr
59114208Smarcelextern uint64_t ia64_port_base;
60114208Smarcel#define	__MEMIO_ADDR(x)		(__volatile void*)(IA64_PHYS_TO_RR6(x))
61114208Smarcel#define	__PIO_ADDR(x)		(__volatile void*)(ia64_port_base |	\
62114208Smarcel	(((x) & 0xFFFC) << 10) | ((x) & 0xFFF))
6383511Sdfr
64114208Smarcel/*
65114208Smarcel * I/O port reads with ia32 semantics.
66114208Smarcel */
67114208Smarcelstatic __inline uint8_t
68114208Smarcelinb(unsigned int port)
6983511Sdfr{
70114208Smarcel	__volatile uint8_t *p;
71114208Smarcel	uint8_t v;
72114208Smarcel	p = __PIO_ADDR(port);
7383511Sdfr	ia64_mf();
74114208Smarcel	v = *p;
75114208Smarcel	ia64_mf_a();
76114208Smarcel	ia64_mf();
77114208Smarcel	return (v);
7866458Sdfr}
7966458Sdfr
80114208Smarcelstatic __inline uint16_t
81114208Smarcelinw(unsigned int port)
8266458Sdfr{
83114208Smarcel	__volatile uint16_t *p;
84114208Smarcel	uint16_t v;
85114208Smarcel	p = __PIO_ADDR(port);
8683511Sdfr	ia64_mf();
87114208Smarcel	v = *p;
88114208Smarcel	ia64_mf_a();
89114208Smarcel	ia64_mf();
90114208Smarcel	return (v);
9166458Sdfr}
9266458Sdfr
93114208Smarcelstatic __inline uint32_t
94114208Smarcelinl(unsigned int port)
9566458Sdfr{
96114208Smarcel	volatile uint32_t *p;
97114208Smarcel	uint32_t v;
98114208Smarcel	p = __PIO_ADDR(port);
9983511Sdfr	ia64_mf();
100114208Smarcel	v = *p;
101114208Smarcel	ia64_mf_a();
102114208Smarcel	ia64_mf();
103114208Smarcel	return (v);
10466458Sdfr}
10566458Sdfr
10666458Sdfrstatic __inline void
107114208Smarcelinsb(unsigned int port, void *addr, size_t count)
10866458Sdfr{
109114208Smarcel	uint8_t *buf = addr;
11066458Sdfr	while (count--)
111114208Smarcel		*buf++ = inb(port);
11266458Sdfr}
11366458Sdfr
11466458Sdfrstatic __inline void
115114208Smarcelinsw(unsigned int port, void *addr, size_t count)
11666458Sdfr{
117114208Smarcel	uint16_t *buf = addr;
11866458Sdfr	while (count--)
119114208Smarcel		*buf++ = inw(port);
12066458Sdfr}
12166458Sdfr
12266458Sdfrstatic __inline void
123114208Smarcelinsl(unsigned int port, void *addr, size_t count)
12466458Sdfr{
125114208Smarcel	uint32_t *buf = addr;
12666458Sdfr	while (count--)
127114208Smarcel		*buf++ = inl(port);
12866458Sdfr}
12966458Sdfr
13066458Sdfrstatic __inline void
131114208Smarceloutb(unsigned int port, uint8_t data)
13266458Sdfr{
133114208Smarcel	volatile uint8_t *p;
134114208Smarcel	p = __PIO_ADDR(port);
13583511Sdfr	ia64_mf();
13683511Sdfr	*p = data;
137114208Smarcel	ia64_mf_a();
13883511Sdfr	ia64_mf();
13966458Sdfr}
14066458Sdfr
14166458Sdfrstatic __inline void
142114208Smarceloutw(unsigned int port, uint16_t data)
14366458Sdfr{
144114208Smarcel	volatile uint16_t *p;
145114208Smarcel	p = __PIO_ADDR(port);
14683511Sdfr	ia64_mf();
14783836Sdfr	*p = data;
148114208Smarcel	ia64_mf_a();
14983836Sdfr	ia64_mf();
15066458Sdfr}
15166458Sdfr
15266458Sdfrstatic __inline void
153114208Smarceloutl(unsigned int port, uint32_t data)
15466458Sdfr{
155114208Smarcel	volatile uint32_t *p;
156114208Smarcel	p = __PIO_ADDR(port);
15783836Sdfr	ia64_mf();
15883836Sdfr	*p = data;
159114208Smarcel	ia64_mf_a();
16083836Sdfr	ia64_mf();
16166458Sdfr}
16266458Sdfr
16366458Sdfrstatic __inline void
164114208Smarceloutsb(unsigned int port, const void *addr, size_t count)
16584581Smarcel{
166114208Smarcel	const uint8_t *buf = addr;
16784581Smarcel	while (count--)
168114208Smarcel		outb(port, *buf++);
16984581Smarcel}
17084581Smarcel
17184581Smarcelstatic __inline void
172114208Smarceloutsw(unsigned int port, const void *addr, size_t count)
17384581Smarcel{
174114208Smarcel	const uint16_t *buf = addr;
17584581Smarcel	while (count--)
176114208Smarcel		outw(port, *buf++);
17784581Smarcel}
17884581Smarcel
17984581Smarcelstatic __inline void
180114208Smarceloutsl(unsigned int port, const void *addr, size_t count)
18184581Smarcel{
182114208Smarcel	const uint32_t *buf = addr;
18384581Smarcel	while (count--)
184114208Smarcel		outl(port, *buf++);
18584581Smarcel}
18684581Smarcel
18784581Smarcelstatic __inline void
18866458Sdfrdisable_intr(void)
18966458Sdfr{
190114208Smarcel	__asm __volatile ("rsm psr.i");
19166458Sdfr}
19266458Sdfr
19366458Sdfrstatic __inline void
19466458Sdfrenable_intr(void)
19566458Sdfr{
196114208Smarcel	__asm __volatile ("ssm psr.i;; srlz.d");
19766458Sdfr}
19866458Sdfr
19992870Sdfrstatic __inline register_t
20092781Sdfrintr_disable(void)
20166458Sdfr{
20292870Sdfr	register_t psr;
203114208Smarcel	__asm __volatile ("mov %0=psr;;" : "=r"(psr));
20474897Sjhb	disable_intr();
205115295Smarcel	return ((psr & IA64_PSR_I) ? 1 : 0);
20666458Sdfr}
20766458Sdfr
20866458Sdfrstatic __inline void
209115295Smarcelintr_restore(register_t ie)
21066458Sdfr{
211115295Smarcel	if (ie)
212115295Smarcel		enable_intr();
21366458Sdfr}
21466458Sdfr
21566458Sdfr#endif /* _KERNEL */
21666458Sdfr
21766458Sdfr#endif /* !_MACHINE_CPUFUNC_H_ */
218