cpufunc.h revision 92781
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 92781 2002-03-20 10:00:05Z dfr $
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>
3666458Sdfr
3788441Sdfr#define	CRITICAL_FORK	(ia64_get_psr() | IA64_PSR_I)
3888088Sjhb
3966458Sdfr#ifdef __GNUC__
4066458Sdfr
4166458Sdfrstatic __inline void
4266458Sdfrbreakpoint(void)
4366458Sdfr{
4466458Sdfr	__asm __volatile("break 0x80100"); /* XXX use linux value */
4566458Sdfr}
4666458Sdfr
4766458Sdfr#endif
4866458Sdfr
4983511Sdfrextern u_int64_t	ia64_port_base;
5083511Sdfr
5183511Sdfrstatic __inline volatile void *
5283511Sdfria64_port_address(u_int port)
5383511Sdfr{
5483511Sdfr    return (volatile void *)(ia64_port_base
5583511Sdfr			     | ((port >> 2) << 12)
5683511Sdfr			     | (port & ((1 << 12) - 1)));
5783511Sdfr}
5883511Sdfr
5983836Sdfrstatic __inline volatile void *
6084581Smarcelia64_memory_address(u_int64_t addr)
6183836Sdfr{
6284581Smarcel	return (volatile void *) IA64_PHYS_TO_RR6(addr);
6383836Sdfr}
6483836Sdfr
6566458Sdfrstatic __inline u_int8_t
6666458Sdfrinb(u_int port)
6766458Sdfr{
6883511Sdfr	volatile u_int8_t *p = ia64_port_address(port);
6983511Sdfr	u_int8_t v = *p;
7083511Sdfr	ia64_mf_a();
7183511Sdfr	ia64_mf();
7283511Sdfr	return v;
7366458Sdfr}
7466458Sdfr
7566458Sdfrstatic __inline u_int16_t
7666458Sdfrinw(u_int port)
7766458Sdfr{
7883511Sdfr	volatile u_int16_t *p = ia64_port_address(port);
7983511Sdfr	u_int16_t v = *p;
8083511Sdfr	ia64_mf_a();
8183511Sdfr	ia64_mf();
8283511Sdfr	return v;
8366458Sdfr}
8466458Sdfr
8566458Sdfrstatic __inline u_int32_t
8666458Sdfrinl(u_int port)
8766458Sdfr{
8883511Sdfr	volatile u_int32_t *p = ia64_port_address(port);
8983511Sdfr	u_int32_t v = *p;
9083511Sdfr	ia64_mf_a();
9183511Sdfr	ia64_mf();
9283511Sdfr	return v;
9366458Sdfr}
9466458Sdfr
9566458Sdfrstatic __inline void
9666458Sdfrinsb(u_int port, void *addr, size_t count)
9766458Sdfr{
9866458Sdfr	u_int8_t *p = addr;
9966458Sdfr	while (count--)
10066458Sdfr		*p++ = inb(port);
10166458Sdfr}
10266458Sdfr
10366458Sdfrstatic __inline void
10466458Sdfrinsw(u_int port, void *addr, size_t count)
10566458Sdfr{
10666458Sdfr	u_int16_t *p = addr;
10766458Sdfr	while (count--)
10866458Sdfr		*p++ = inw(port);
10966458Sdfr}
11066458Sdfr
11166458Sdfrstatic __inline void
11266458Sdfrinsl(u_int port, void *addr, size_t count)
11366458Sdfr{
11466458Sdfr	u_int32_t *p = addr;
11566458Sdfr	while (count--)
11666458Sdfr		*p++ = inl(port);
11766458Sdfr}
11866458Sdfr
11966458Sdfrstatic __inline void
12066458Sdfroutb(u_int port, u_int8_t data)
12166458Sdfr{
12283511Sdfr	volatile u_int8_t *p = ia64_port_address(port);
12383511Sdfr	*p = data;
12483511Sdfr	ia64_mf_a();
12583511Sdfr	ia64_mf();
12666458Sdfr}
12766458Sdfr
12866458Sdfrstatic __inline void
12966458Sdfroutw(u_int port, u_int16_t data)
13066458Sdfr{
13183511Sdfr	volatile u_int16_t *p = ia64_port_address(port);
13283511Sdfr	*p = data;
13383511Sdfr	ia64_mf_a();
13483511Sdfr	ia64_mf();
13566458Sdfr}
13666458Sdfr
13766458Sdfrstatic __inline void
13866458Sdfroutl(u_int port, u_int32_t data)
13966458Sdfr{
14083511Sdfr	volatile u_int32_t *p = ia64_port_address(port);
14183511Sdfr	*p = data;
14283511Sdfr	ia64_mf_a();
14383511Sdfr	ia64_mf();
14466458Sdfr}
14566458Sdfr
14666458Sdfrstatic __inline void
14766458Sdfroutsb(u_int port, const void *addr, size_t count)
14866458Sdfr{
14966458Sdfr	const u_int8_t *p = addr;
15066458Sdfr	while (count--)
15166458Sdfr		outb(port, *p++);
15266458Sdfr}
15366458Sdfr
15466458Sdfrstatic __inline void
15566458Sdfroutsw(u_int port, const void *addr, size_t count)
15666458Sdfr{
15766458Sdfr	const u_int16_t *p = addr;
15866458Sdfr	while (count--)
15966458Sdfr		outw(port, *p++);
16066458Sdfr}
16166458Sdfr
16266458Sdfrstatic __inline void
16366458Sdfroutsl(u_int port, const void *addr, size_t count)
16466458Sdfr{
16566458Sdfr	const u_int32_t *p = addr;
16666458Sdfr	while (count--)
16766458Sdfr		outl(port, *p++);
16866458Sdfr}
16966458Sdfr
17066458Sdfrstatic __inline u_int8_t
17166458Sdfrreadb(u_int addr)
17266458Sdfr{
17383836Sdfr	volatile u_int8_t *p = ia64_memory_address(addr);
17483836Sdfr	u_int8_t v = *p;
17583836Sdfr	ia64_mf_a();
17683836Sdfr	ia64_mf();
17783836Sdfr	return v;
17866458Sdfr}
17966458Sdfr
18066458Sdfrstatic __inline u_int16_t
18166458Sdfrreadw(u_int addr)
18266458Sdfr{
18383836Sdfr	volatile u_int16_t *p = ia64_memory_address(addr);
18483836Sdfr	u_int16_t v = *p;
18583836Sdfr	ia64_mf_a();
18683836Sdfr	ia64_mf();
18783836Sdfr	return v;
18866458Sdfr}
18966458Sdfr
19066458Sdfrstatic __inline u_int32_t
19166458Sdfrreadl(u_int addr)
19266458Sdfr{
19383836Sdfr	volatile u_int32_t *p = ia64_memory_address(addr);
19483836Sdfr	u_int32_t v = *p;
19583836Sdfr	ia64_mf_a();
19683836Sdfr	ia64_mf();
19783836Sdfr	return v;
19866458Sdfr}
19966458Sdfr
20066458Sdfrstatic __inline void
20166458Sdfrwriteb(u_int addr, u_int8_t data)
20266458Sdfr{
20383836Sdfr	volatile u_int8_t *p = ia64_memory_address(addr);
20483836Sdfr	*p = data;
20583836Sdfr	ia64_mf_a();
20683836Sdfr	ia64_mf();
20766458Sdfr}
20866458Sdfr
20966458Sdfrstatic __inline void
21066458Sdfrwritew(u_int addr, u_int16_t data)
21166458Sdfr{
21283836Sdfr	volatile u_int16_t *p = ia64_memory_address(addr);
21383836Sdfr	*p = data;
21483836Sdfr	ia64_mf_a();
21583836Sdfr	ia64_mf();
21666458Sdfr}
21766458Sdfr
21866458Sdfrstatic __inline void
21966458Sdfrwritel(u_int addr, u_int32_t data)
22066458Sdfr{
22183836Sdfr	volatile u_int32_t *p = ia64_memory_address(addr);
22283836Sdfr	*p = data;
22383836Sdfr	ia64_mf_a();
22483836Sdfr	ia64_mf();
22566458Sdfr}
22666458Sdfr
22766458Sdfrstatic __inline void
22884581Smarcelmemcpy_fromio(u_int8_t *addr, size_t ofs, size_t count)
22984581Smarcel{
23084581Smarcel	volatile u_int8_t *p = ia64_memory_address(ofs);
23184581Smarcel	while (count--)
23284581Smarcel		*addr++ = *p++;
23384581Smarcel}
23484581Smarcel
23584581Smarcelstatic __inline void
23684581Smarcelmemcpy_io(size_t dst, size_t src, size_t count)
23784581Smarcel{
23884581Smarcel	volatile u_int8_t *dp = ia64_memory_address(dst);
23984581Smarcel	volatile u_int8_t *sp = ia64_memory_address(src);
24084581Smarcel	while (count--)
24184581Smarcel		*dp++ = *sp++;
24284581Smarcel}
24384581Smarcel
24484581Smarcelstatic __inline void
24584581Smarcelmemcpy_toio(size_t ofs, u_int8_t *addr, size_t count)
24684581Smarcel{
24784581Smarcel	volatile u_int8_t *p = ia64_memory_address(ofs);
24884581Smarcel	while (count--)
24984581Smarcel		*p++ = *addr++;
25084581Smarcel}
25184581Smarcel
25284581Smarcelstatic __inline void
25384581Smarcelmemset_io(size_t ofs, u_int8_t value, size_t count)
25484581Smarcel{
25584581Smarcel	volatile u_int8_t *p = ia64_memory_address(ofs);
25684581Smarcel	while (count--)
25784581Smarcel		*p++ = value;
25884581Smarcel}
25984581Smarcel
26084581Smarcelstatic __inline void
26184581Smarcelmemsetw(u_int16_t *addr, int val, size_t size)
26284581Smarcel{
26384581Smarcel	while (size--)
26484581Smarcel		*addr++ = val;
26584581Smarcel}
26684581Smarcel
26784581Smarcelstatic __inline void
26884581Smarcelmemsetw_io(size_t ofs, u_int16_t value, size_t count)
26984581Smarcel{
27084581Smarcel	volatile u_int16_t *p = ia64_memory_address(ofs);
27184581Smarcel	while (count--)
27284581Smarcel		*p++ = value;
27384581Smarcel}
27484581Smarcel
27584581Smarcelstatic __inline void
27666458Sdfrdisable_intr(void)
27766458Sdfr{
27866458Sdfr	__asm __volatile ("rsm psr.i;;");
27966458Sdfr}
28066458Sdfr
28166458Sdfrstatic __inline void
28266458Sdfrenable_intr(void)
28366458Sdfr{
28466458Sdfr	__asm __volatile (";; ssm psr.i;; srlz.d");
28566458Sdfr}
28666458Sdfr
28774897Sjhbstatic __inline critical_t
28892781Sdfrintr_disable(void)
28966458Sdfr{
29074897Sjhb	critical_t psr;
29174897Sjhb
29266458Sdfr	__asm __volatile ("mov %0=psr;;" : "=r" (psr));
29374897Sjhb	disable_intr();
29474897Sjhb	return (psr);
29566458Sdfr}
29666458Sdfr
29766458Sdfrstatic __inline void
29892781Sdfrintr_enable(critical_t psr)
29966458Sdfr{
30066458Sdfr	__asm __volatile ("mov psr.l=%0;; srlz.d" :: "r" (psr));
30166458Sdfr}
30266458Sdfr
30392781Sdfrstatic __inline critical_t
30492781Sdfrcpu_critical_enter(void)
30592781Sdfr{
30692781Sdfr	return (intr_disable());
30792781Sdfr}
30892781Sdfr
30992781Sdfrstatic __inline void
31092781Sdfrcpu_critical_exit(critical_t psr)
31192781Sdfr{
31292781Sdfr	intr_enable(psr);
31392781Sdfr}
31492781Sdfr
31566458Sdfr#endif /* _KERNEL */
31666458Sdfr
31766458Sdfr#endif /* !_MACHINE_CPUFUNC_H_ */
318