| 1 | /* 	$NetBSD: footbridge_intr.h,v 1.22 2021/08/13 11:40:43 skrll Exp $	*/ |
| 2 | |
| 3 | /* |
| 4 | * Copyright (c) 2001, 2002 Wasabi Systems, Inc. |
| 5 | * All rights reserved. |
| 6 | * |
| 7 | * Written by Jason R. Thorpe for Wasabi Systems, Inc. |
| 8 | * |
| 9 | * Redistribution and use in source and binary forms, with or without |
| 10 | * modification, are permitted provided that the following conditions |
| 11 | * are met: |
| 12 | * 1. Redistributions of source code must retain the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer. |
| 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 15 | * notice, this list of conditions and the following disclaimer in the |
| 16 | * documentation and/or other materials provided with the distribution. |
| 17 | * 3. All advertising materials mentioning features or use of this software |
| 18 | * must display the following acknowledgement: |
| 19 | *	This product includes software developed for the NetBSD Project by |
| 20 | *	Wasabi Systems, Inc. |
| 21 | * 4. The name of Wasabi Systems, Inc. may not be used to endorse |
| 22 | * or promote products derived from this software without specific prior |
| 23 | * written permission. |
| 24 | * |
| 25 | * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND |
| 26 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
| 27 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 28 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC |
| 29 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 30 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 31 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 32 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 33 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 34 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 35 | * POSSIBILITY OF SUCH DAMAGE. |
| 36 | */ |
| 37 | |
| 38 | #ifndef _FOOTBRIDGE_INTR_H_ |
| 39 | #define _FOOTBRIDGE_INTR_H_ |
| 40 | |
| 41 | #ifndef _LOCORE |
| 42 | typedef uint8_t ipl_t; |
| 43 | typedef struct { |
| 44 | 	ipl_t _ipl; |
| 45 | } ipl_cookie_t; |
| 46 | |
| 47 | #include <arm/mutex.h> |
| 48 | #endif |
| 49 | #include <arm/cpu.h> |
| 50 | #include <arm/armreg.h> |
| 51 | |
| 52 | #define IPL_NONE	0	/* nothing */ |
| 53 | #define IPL_SOFTCLOCK	1	/* clock soft interrupts */ |
| 54 | #define IPL_SOFTBIO	2	/* block i/o */ |
| 55 | #define IPL_SOFTNET	3	/* network software interrupts */ |
| 56 | #define IPL_SOFTSERIAL	4	/* serial software interrupts */ |
| 57 | #define IPL_VM		5	/* memory allocation */ |
| 58 | #define IPL_SCHED	6	/* clock */ |
| 59 | #define IPL_HIGH	7	/* everything */ |
| 60 | |
| 61 | #define NIPL		8 |
| 62 | |
| 63 | #define	IST_UNUSABLE	-1	/* interrupt cannot be used */ |
| 64 | #define	IST_NONE	0	/* none (dummy) */ |
| 65 | #define	IST_PULSE	1	/* pulsed */ |
| 66 | #define	IST_EDGE	2	/* edge-triggered */ |
| 67 | #define	IST_LEVEL	3	/* level-triggered */ |
| 68 | |
| 69 | #define	ARM_IRQ_HANDLER	_C_LABEL(footbridge_intr_dispatch) |
| 70 | |
| 71 | #ifndef _LOCORE |
| 72 | #include <arm/cpufunc.h> |
| 73 | |
| 74 | #include <arm/footbridge/dc21285mem.h> |
| 75 | #include <arm/footbridge/dc21285reg.h> |
| 76 | |
| 77 | #define INT_SWMASK							\ |
| 78 | 	((1U << IRQ_SOFTINT) | (1U << IRQ_RESERVED0) |			\ |
| 79 | 	 (1U << IRQ_RESERVED1) | (1U << IRQ_RESERVED2)) |
| 80 | #define ICU_INT_HWMASK	(0xffffffff & ~(INT_SWMASK | (1U << IRQ_RESERVED3))) |
| 81 | |
| 82 | /* only call this with interrupts off */ |
| 83 | static inline void __attribute__((__unused__)) |
| 84 | footbridge_set_intrmask(void) |
| 85 | { |
| 86 | 	extern volatile uint32_t intr_enabled; |
| 87 | 	volatile uint32_t * const dc21285_armcsr_vbase = |
| 88 | 	 (volatile uint32_t *)(DC21285_ARMCSR_VBASE); |
| 89 | |
| 90 | 	/* fetch once so we write the same number to both registers */ |
| 91 | 	uint32_t tmp = intr_enabled & ICU_INT_HWMASK; |
| 92 | |
| 93 | 	dc21285_armcsr_vbase[IRQ_ENABLE_SET>>2] = tmp; |
| 94 | 	dc21285_armcsr_vbase[IRQ_ENABLE_CLEAR>>2] = ~tmp; |
| 95 | } |
| 96 | |
| 97 | static inline void __attribute__((__unused__)) |
| 98 | footbridge_splx(int ipl) |
| 99 | { |
| 100 | 	extern int footbridge_imask[]; |
| 101 | 	extern volatile uint32_t intr_enabled; |
| 102 | 	extern volatile int footbridge_ipending; |
| 103 | 	int oldirqstate, hwpend; |
| 104 | |
| 105 | 	/* Don't let the compiler re-order this code with preceding code */ |
| 106 | 	__insn_barrier(); |
| 107 | |
| 108 | 	set_curcpl(ipl); |
| 109 | |
| 110 | 	hwpend = footbridge_ipending & ICU_INT_HWMASK & ~footbridge_imask[ipl]; |
| 111 | 	if (hwpend != 0) { |
| 112 | 		oldirqstate = disable_interrupts(I32_bit); |
| 113 | 		intr_enabled |= hwpend; |
| 114 | 		footbridge_set_intrmask(); |
| 115 | 		restore_interrupts(oldirqstate); |
| 116 | 	} |
| 117 | |
| 118 | #ifdef __HAVE_FAST_SOFTINTS |
| 119 | 	cpu_dosoftints(); |
| 120 | #endif |
| 121 | } |
| 122 | |
| 123 | static inline int __attribute__((__unused__)) |
| 124 | footbridge_splraise(int ipl) |
| 125 | { |
| 126 | 	int	old; |
| 127 | |
| 128 | 	old = curcpl(); |
| 129 | 	set_curcpl(ipl); |
| 130 | |
| 131 | 	/* Don't let the compiler re-order this code with subsequent code */ |
| 132 | 	__insn_barrier(); |
| 133 | |
| 134 | 	return (old); |
| 135 | } |
| 136 | |
| 137 | static inline int __attribute__((__unused__)) |
| 138 | footbridge_spllower(int ipl) |
| 139 | { |
| 140 | 	int old = curcpl(); |
| 141 | |
| 142 | 	footbridge_splx(ipl); |
| 143 | 	return(old); |
| 144 | } |
| 145 | |
| 146 | /* should only be defined in footbridge_intr.c */ |
| 147 | #if !defined(ARM_SPL_NOINLINE) |
| 148 | |
| 149 | #define splx(newspl)		footbridge_splx(newspl) |
| 150 | #define	_spllower(ipl)		footbridge_spllower(ipl) |
| 151 | #define	_splraise(ipl)		footbridge_splraise(ipl) |
| 152 | |
| 153 | #else |
| 154 | |
| 155 | int	_splraise(int); |
| 156 | int	_spllower(int); |
| 157 | void	splx(int); |
| 158 | |
| 159 | #endif /* ! ARM_SPL_NOINLINE */ |
| 160 | |
| 161 | #include <sys/evcnt.h> |
| 162 | #include <sys/queue.h> |
| 163 | #include <machine/irqhandler.h> |
| 164 | |
| 165 | #define	splsoft()	_splraise(IPL_SOFT) |
| 166 | |
| 167 | #define	spl0()		(void)_spllower(IPL_NONE) |
| 168 | #define	spllowersoftclock() (void)_spllower(IPL_SOFTCLOCK) |
| 169 | |
| 170 | |
| 171 | static inline ipl_cookie_t |
| 172 | makeiplcookie(ipl_t ipl) |
| 173 | { |
| 174 | |
| 175 | 	return (ipl_cookie_t){._ipl = ipl}; |
| 176 | } |
| 177 | |
| 178 | static inline int |
| 179 | splraiseipl(ipl_cookie_t icookie) |
| 180 | { |
| 181 | |
| 182 | 	return _splraise(icookie._ipl); |
| 183 | } |
| 184 | |
| 185 | #include <sys/spl.h> |
| 186 | |
| 187 | /* footbridge has 32 interrupt lines */ |
| 188 | #define	NIRQ		32 |
| 189 | |
| 190 | struct intrhand { |
| 191 | 	TAILQ_ENTRY(intrhand) ih_list;	/* link on intrq list */ |
| 192 | 	int (*ih_func)(void *);		/* handler */ |
| 193 | 	void *ih_arg;			/* arg for handler */ |
| 194 | 	int ih_ipl;			/* IPL_* */ |
| 195 | 	int ih_irq;			/* IRQ number */ |
| 196 | }; |
| 197 | |
| 198 | #define	IRQNAMESIZE	sizeof("footbridge irq 31") |
| 199 | |
| 200 | struct intrq { |
| 201 | 	TAILQ_HEAD(, intrhand) iq_list;	/* handler list */ |
| 202 | 	struct evcnt iq_ev;		/* event counter */ |
| 203 | 	int iq_mask;			/* IRQs to mask while handling */ |
| 204 | 	int iq_levels;			/* IPL_*'s this IRQ has */ |
| 205 | 	int iq_ist;			/* share type */ |
| 206 | 	int iq_ipl;			/* max ipl */ |
| 207 | 	char iq_name[IRQNAMESIZE];	/* interrupt name */ |
| 208 | }; |
| 209 | |
| 210 | #endif /* _LOCORE */ |
| 211 | |
| 212 | #endif	/* _FOOTBRIDGE_INTR_H */ |