cpufunc.h revision 127253
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 127253 2004-03-21 01:41:29Z marcel $
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
40127253Smarcel#define	IA64_FIXED_BREAK	0x84B5D
41127253Smarcel
4266458Sdfr#ifdef __GNUC__
4366458Sdfr
4466458Sdfrstatic __inline void
4566458Sdfrbreakpoint(void)
4666458Sdfr{
47127253Smarcel	__asm __volatile("break.m %0" :: "i"(IA64_FIXED_BREAK));
4866458Sdfr}
4966458Sdfr
50124478Sdes#define	HAVE_INLINE_FFS
51123419Speter
52123419Speterstatic __inline int
53123419Speterffs(int mask)
54123419Speter{
55123419Speter	return (__builtin_ffs(mask));
56123419Speter}
57123419Speter
5866458Sdfr#endif
5966458Sdfr
60114208Smarcelextern uint64_t ia64_port_base;
61114208Smarcel#define	__MEMIO_ADDR(x)		(__volatile void*)(IA64_PHYS_TO_RR6(x))
62114208Smarcel#define	__PIO_ADDR(x)		(__volatile void*)(ia64_port_base |	\
63114208Smarcel	(((x) & 0xFFFC) << 10) | ((x) & 0xFFF))
6483511Sdfr
65114208Smarcel/*
66114208Smarcel * I/O port reads with ia32 semantics.
67114208Smarcel */
68114208Smarcelstatic __inline uint8_t
69114208Smarcelinb(unsigned int port)
7083511Sdfr{
71114208Smarcel	__volatile uint8_t *p;
72114208Smarcel	uint8_t v;
73114208Smarcel	p = __PIO_ADDR(port);
7483511Sdfr	ia64_mf();
75114208Smarcel	v = *p;
76114208Smarcel	ia64_mf_a();
77114208Smarcel	ia64_mf();
78114208Smarcel	return (v);
7966458Sdfr}
8066458Sdfr
81114208Smarcelstatic __inline uint16_t
82114208Smarcelinw(unsigned int port)
8366458Sdfr{
84114208Smarcel	__volatile uint16_t *p;
85114208Smarcel	uint16_t v;
86114208Smarcel	p = __PIO_ADDR(port);
8783511Sdfr	ia64_mf();
88114208Smarcel	v = *p;
89114208Smarcel	ia64_mf_a();
90114208Smarcel	ia64_mf();
91114208Smarcel	return (v);
9266458Sdfr}
9366458Sdfr
94114208Smarcelstatic __inline uint32_t
95114208Smarcelinl(unsigned int port)
9666458Sdfr{
97114208Smarcel	volatile uint32_t *p;
98114208Smarcel	uint32_t v;
99114208Smarcel	p = __PIO_ADDR(port);
10083511Sdfr	ia64_mf();
101114208Smarcel	v = *p;
102114208Smarcel	ia64_mf_a();
103114208Smarcel	ia64_mf();
104114208Smarcel	return (v);
10566458Sdfr}
10666458Sdfr
10766458Sdfrstatic __inline void
108114208Smarcelinsb(unsigned int port, void *addr, size_t count)
10966458Sdfr{
110114208Smarcel	uint8_t *buf = addr;
11166458Sdfr	while (count--)
112114208Smarcel		*buf++ = inb(port);
11366458Sdfr}
11466458Sdfr
11566458Sdfrstatic __inline void
116114208Smarcelinsw(unsigned int port, void *addr, size_t count)
11766458Sdfr{
118114208Smarcel	uint16_t *buf = addr;
11966458Sdfr	while (count--)
120114208Smarcel		*buf++ = inw(port);
12166458Sdfr}
12266458Sdfr
12366458Sdfrstatic __inline void
124114208Smarcelinsl(unsigned int port, void *addr, size_t count)
12566458Sdfr{
126114208Smarcel	uint32_t *buf = addr;
12766458Sdfr	while (count--)
128114208Smarcel		*buf++ = inl(port);
12966458Sdfr}
13066458Sdfr
13166458Sdfrstatic __inline void
132114208Smarceloutb(unsigned int port, uint8_t data)
13366458Sdfr{
134114208Smarcel	volatile uint8_t *p;
135114208Smarcel	p = __PIO_ADDR(port);
13683511Sdfr	ia64_mf();
13783511Sdfr	*p = data;
138114208Smarcel	ia64_mf_a();
13983511Sdfr	ia64_mf();
14066458Sdfr}
14166458Sdfr
14266458Sdfrstatic __inline void
143114208Smarceloutw(unsigned int port, uint16_t data)
14466458Sdfr{
145114208Smarcel	volatile uint16_t *p;
146114208Smarcel	p = __PIO_ADDR(port);
14783511Sdfr	ia64_mf();
14883836Sdfr	*p = data;
149114208Smarcel	ia64_mf_a();
15083836Sdfr	ia64_mf();
15166458Sdfr}
15266458Sdfr
15366458Sdfrstatic __inline void
154114208Smarceloutl(unsigned int port, uint32_t data)
15566458Sdfr{
156114208Smarcel	volatile uint32_t *p;
157114208Smarcel	p = __PIO_ADDR(port);
15883836Sdfr	ia64_mf();
15983836Sdfr	*p = data;
160114208Smarcel	ia64_mf_a();
16183836Sdfr	ia64_mf();
16266458Sdfr}
16366458Sdfr
16466458Sdfrstatic __inline void
165114208Smarceloutsb(unsigned int port, const void *addr, size_t count)
16684581Smarcel{
167114208Smarcel	const uint8_t *buf = addr;
16884581Smarcel	while (count--)
169114208Smarcel		outb(port, *buf++);
17084581Smarcel}
17184581Smarcel
17284581Smarcelstatic __inline void
173114208Smarceloutsw(unsigned int port, const void *addr, size_t count)
17484581Smarcel{
175114208Smarcel	const uint16_t *buf = addr;
17684581Smarcel	while (count--)
177114208Smarcel		outw(port, *buf++);
17884581Smarcel}
17984581Smarcel
18084581Smarcelstatic __inline void
181114208Smarceloutsl(unsigned int port, const void *addr, size_t count)
18284581Smarcel{
183114208Smarcel	const uint32_t *buf = addr;
18484581Smarcel	while (count--)
185114208Smarcel		outl(port, *buf++);
18684581Smarcel}
18784581Smarcel
18884581Smarcelstatic __inline void
18966458Sdfrdisable_intr(void)
19066458Sdfr{
191114208Smarcel	__asm __volatile ("rsm psr.i");
19266458Sdfr}
19366458Sdfr
19466458Sdfrstatic __inline void
19566458Sdfrenable_intr(void)
19666458Sdfr{
197114208Smarcel	__asm __volatile ("ssm psr.i;; srlz.d");
19866458Sdfr}
19966458Sdfr
20092870Sdfrstatic __inline register_t
20192781Sdfrintr_disable(void)
20266458Sdfr{
20392870Sdfr	register_t psr;
204114208Smarcel	__asm __volatile ("mov %0=psr;;" : "=r"(psr));
20574897Sjhb	disable_intr();
206115295Smarcel	return ((psr & IA64_PSR_I) ? 1 : 0);
20766458Sdfr}
20866458Sdfr
20966458Sdfrstatic __inline void
210115295Smarcelintr_restore(register_t ie)
21166458Sdfr{
212115295Smarcel	if (ie)
213115295Smarcel		enable_intr();
21466458Sdfr}
21566458Sdfr
21666458Sdfr#endif /* _KERNEL */
21766458Sdfr
21866458Sdfr#endif /* !_MACHINE_CPUFUNC_H_ */
219