1135669Scognet/*	$NetBSD: i80321_intr.h,v 1.5 2004/01/12 10:25:06 scw Exp $	*/
2135669Scognet
3139735Simp/*-
4135669Scognet * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
5135669Scognet * All rights reserved.
6135669Scognet *
7135669Scognet * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8135669Scognet *
9135669Scognet * Redistribution and use in source and binary forms, with or without
10135669Scognet * modification, are permitted provided that the following conditions
11135669Scognet * are met:
12135669Scognet * 1. Redistributions of source code must retain the above copyright
13135669Scognet *    notice, this list of conditions and the following disclaimer.
14135669Scognet * 2. Redistributions in binary form must reproduce the above copyright
15135669Scognet *    notice, this list of conditions and the following disclaimer in the
16135669Scognet *    documentation and/or other materials provided with the distribution.
17135669Scognet * 3. All advertising materials mentioning features or use of this software
18135669Scognet *    must display the following acknowledgement:
19135669Scognet *	This product includes software developed for the NetBSD Project by
20135669Scognet *	Wasabi Systems, Inc.
21135669Scognet * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22135669Scognet *    or promote products derived from this software without specific prior
23135669Scognet *    written permission.
24135669Scognet *
25135669Scognet * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26135669Scognet * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27135669Scognet * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28135669Scognet * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29135669Scognet * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30135669Scognet * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31135669Scognet * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32135669Scognet * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33135669Scognet * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34135669Scognet * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35135669Scognet * POSSIBILITY OF SUCH DAMAGE.
36236987Simp *
37135669Scognet * $FreeBSD$
38135669Scognet *
39135669Scognet */
40135669Scognet
41135669Scognet#ifndef _I80321_INTR_H_
42135669Scognet#define _I80321_INTR_H_
43135669Scognet
44135669Scognet#define	ARM_IRQ_HANDLER	_C_LABEL(i80321_intr_dispatch)
45135669Scognet
46135669Scognet#ifndef _LOCORE
47135669Scognet
48135669Scognet#include <machine/armreg.h>
49135669Scognet#include <machine/cpufunc.h>
50135669Scognet
51135669Scognet#include <arm/xscale/i80321/i80321reg.h>
52135669Scognet
53135669Scognetvoid i80321_do_pending(void);
54135669Scognet
55135669Scognetextern __volatile uint32_t intr_enabled;
56135669Scognetextern uint32_t intr_steer;
57135669Scognet
58135669Scognetstatic __inline void __attribute__((__unused__))
59135669Scogneti80321_set_intrmask(void)
60135669Scognet{
61135669Scognet
62135669Scognet	__asm __volatile("mcr p6, 0, %0, c0, c0, 0"
63135669Scognet		:
64135669Scognet		: "r" (intr_enabled & ICU_INT_HWMASK));
65135669Scognet}
66135669Scognet
67135669Scognetstatic __inline void
68135669Scogneti80321_set_intrsteer(void)
69135669Scognet{
70135669Scognet
71135669Scognet	__asm __volatile("mcr p6, 0, %0, c4, c0, 0"
72135669Scognet	    :
73135669Scognet	    : "r" (intr_steer & ICU_INT_HWMASK));
74135669Scognet}
75135669Scognet
76161592Scognet#if defined ( CPU_XSCALE_80219 )
77161592Scognet#define INT_SWMASK														\
78161592Scognet	((1U << ICU_INT_bit26) |											\
79161592Scognet	 (1U << ICU_INT_bit25) |											\
80161592Scognet	 (1U << ICU_INT_bit23) |											\
81161592Scognet	 (1U << ICU_INT_bit22) |											\
82161592Scognet	 (1U << ICU_INT_bit7)  |											\
83161592Scognet	 (1U << ICU_INT_bit6)  |											\
84161592Scognet	 (1U << ICU_INT_bit5)  |											\
85161592Scognet	 (1U << ICU_INT_bit4))
86161592Scognet#else
87135669Scognet#define INT_SWMASK                                                      \
88135669Scognet        ((1U << ICU_INT_bit26) | (1U << ICU_INT_bit22) |                \
89135669Scognet         (1U << ICU_INT_bit5)  | (1U << ICU_INT_bit4))
90161592Scognet#endif
91135669Scognet
92135669Scognet#if 0
93135669Scognetstatic __inline void __attribute__((__unused__))
94135669Scogneti80321_splx(int new)
95135669Scognet{
96135669Scognet	extern __volatile uint32_t intr_enabled;
97135669Scognet	extern __volatile int current_spl_level;
98135669Scognet	extern __volatile int i80321_ipending;
99135669Scognet	extern void i80321_do_pending(void);
100135669Scognet	int oldirqstate, hwpend;
101135669Scognet
102135669Scognet	/* Don't let the compiler re-order this code with preceding code */
103135669Scognet	__insn_barrier();
104135669Scognet
105135669Scognet	current_spl_level = new;
106135669Scognet
107135669Scognet	hwpend = (i80321_ipending & ICU_INT_HWMASK) & ~new;
108135669Scognet	if (hwpend != 0) {
109278613Sian		oldirqstate = disable_interrupts(PSR_I);
110135669Scognet		intr_enabled |= hwpend;
111135669Scognet		i80321_set_intrmask();
112135669Scognet		restore_interrupts(oldirqstate);
113135669Scognet	}
114135669Scognet
115135669Scognet	if ((i80321_ipending & INT_SWMASK) & ~new)
116135669Scognet		i80321_do_pending();
117135669Scognet}
118135669Scognet
119135669Scognetstatic __inline int __attribute__((__unused__))
120135669Scogneti80321_splraise(int ipl)
121135669Scognet{
122135669Scognet	extern __volatile int current_spl_level;
123135669Scognet	extern int i80321_imask[];
124135669Scognet	int	old;
125135669Scognet
126135669Scognet	old = current_spl_level;
127135669Scognet	current_spl_level |= i80321_imask[ipl];
128135669Scognet
129135669Scognet	/* Don't let the compiler re-order this code with subsequent code */
130135669Scognet	__insn_barrier();
131135669Scognet
132135669Scognet	return (old);
133135669Scognet}
134135669Scognet
135135669Scognetstatic __inline int __attribute__((__unused__))
136135669Scogneti80321_spllower(int ipl)
137135669Scognet{
138135669Scognet	extern __volatile int current_spl_level;
139135669Scognet	extern int i80321_imask[];
140135669Scognet	int old = current_spl_level;
141135669Scognet
142135669Scognet	i80321_splx(i80321_imask[ipl]);
143135669Scognet	return(old);
144135669Scognet}
145135669Scognet
146135669Scognet#endif
147135669Scognet#if !defined(EVBARM_SPL_NOINLINE)
148135669Scognet
149135669Scognet#define splx(new)		i80321_splx(new)
150135669Scognet#define	_spllower(ipl)		i80321_spllower(ipl)
151135669Scognet#define	_splraise(ipl)		i80321_splraise(ipl)
152135669Scognetvoid	_setsoftintr(int);
153135669Scognet
154135669Scognet#else
155135669Scognet
156135669Scognetint	_splraise(int);
157135669Scognetint	_spllower(int);
158135669Scognetvoid	splx(int);
159135669Scognetvoid	_setsoftintr(int);
160135669Scognet
161135669Scognet#endif /* ! EVBARM_SPL_NOINLINE */
162135669Scognet
163135669Scognet#endif /* _LOCORE */
164135669Scognet
165135669Scognet#endif /* _I80321_INTR_H_ */
166