1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#ifndef	_SYS_IVINTR_H
27#define	_SYS_IVINTR_H
28
29#include <sys/intreg.h>
30#include <sys/param.h>
31
32#ifdef	__cplusplus
33extern "C" {
34#endif
35
36/* Software interrupt and other bit flags */
37#define	IV_SOFTINT_PEND	0x1	/* Software interrupt is pending */
38#define	IV_SOFTINT_MT	0x2	/* Multi target software interrupt */
39#define	IV_CACHE_ALLOC	0x4	/* Allocated using kmem_cache_alloc() */
40
41/*
42 * Reserve some interrupt vector data structures for the hardware and software
43 * interrupts.
44 *
45 * NOTE: Need two single target software interrupts per cpu for cyclics.
46 *       Need one single target software interrupt per cpu for tick accounting.
47 */
48#define	MAX_RSVD_IV	((NCPU * 3) + 256) /* HW and Single target SW intrs */
49#define	MAX_RSVD_IVX	32		/* Multi target software intrs */
50
51#define	IVSIZE	roundup(((MAXIVNUM * sizeof (intr_vec_t *)) + \
52			(MAX_RSVD_IV * sizeof (intr_vec_t)) + \
53			(MAX_RSVD_IVX * sizeof (intr_vecx_t))), PAGESIZE)
54
55#ifndef _ASM
56
57typedef	uint_t (*intrfunc)(caddr_t, caddr_t);
58typedef	uint_t (*softintrfunc)(caddr_t, caddr_t);
59typedef	struct intr_vec intr_vec_t;
60typedef	struct intr_vecx intr_vecx_t;
61
62extern uint_t ignore_invalid_vecintr;
63
64/* Software interrupt type */
65typedef enum softint_type {
66	SOFTINT_ST 	= (ushort_t)0,	/* Single target */
67	SOFTINT_MT	= (ushort_t)1	/* Multi target */
68} softint_type_t;
69
70/*
71 * Interrupt Vector Structure.
72 *
73 * Interrupt vector structure is allocated either from the reserved pool or
74 * dynamically using kmem cache method. For the hardware interrupts, one per
75 * vector with unique pil basis, i.e, interrupts sharing the same ino and the
76 * same pil do share the same structure.
77 *
78 * Used by Hardware and Single target Software interrupts.
79 */
80struct intr_vec {
81	ushort_t	iv_inum;	/* MDB: interrupt mondo number */
82	ushort_t	iv_pil;		/* Interrupt priority level */
83	ushort_t	iv_flags;	/* SW interrupt and other bit flags */
84	uint8_t		iv_pad[10];	/* Align on cache line boundary */
85
86	intrfunc	iv_handler;	/* ISR */
87	caddr_t		iv_arg1;	/* ISR arg1 */
88	caddr_t		iv_arg2;	/* ISR arg2 */
89	caddr_t		iv_payload_buf;	/* Sun4v: mondo payload, epkt */
90
91	intr_vec_t	*iv_vec_next;	/* Per vector list */
92	intr_vec_t	*iv_pil_next;	/* Per PIL list */
93};
94
95/*
96 * Extended version of Interrupt Vector Structure.
97 *
98 * Used by Multi target Software interrupts.
99 */
100struct intr_vecx {
101	intr_vec_t	iv_vec;		/* CPU0 uses iv_pil_next */
102	intr_vec_t	*iv_pil_xnext[NCPU -1]; /* For CPU1 through N-1 */
103};
104
105#define	IV_GET_PIL_NEXT(iv_p, cpu_id) \
106	(((iv_p->iv_flags & IV_SOFTINT_MT) && (cpu_id != 0)) ? \
107	((intr_vecx_t *)iv_p)->iv_pil_xnext[cpu_id - 1] : iv_p->iv_pil_next)
108#define	IV_SET_PIL_NEXT(iv_p, cpu_id, next) \
109	(((iv_p->iv_flags & IV_SOFTINT_MT) && (cpu_id != 0)) ? \
110	(((intr_vecx_t *)iv_p)->iv_pil_xnext[cpu_id - 1] = next) : \
111	(iv_p->iv_pil_next = next))
112
113extern  uint64_t intr_vec_table[];
114
115extern	void init_ivintr(void);
116extern	void fini_ivintr(void);
117
118extern	int add_ivintr(uint_t inum, uint_t pil, intrfunc intr_handler,
119	caddr_t intr_arg1, caddr_t intr_arg2, caddr_t intr_payload);
120extern	int rem_ivintr(uint_t inum, uint_t pil);
121
122extern	uint64_t add_softintr(uint_t pil, softintrfunc intr_handler,
123	caddr_t intr_arg1, softint_type_t type);
124extern	int rem_softintr(uint64_t softint_id);
125extern	int update_softint_arg2(uint64_t softint_id, caddr_t intr_arg2);
126extern	int update_softint_pri(uint64_t softint_id, uint_t pil);
127
128#endif	/* !_ASM */
129
130#ifdef	__cplusplus
131}
132#endif
133
134#endif	/* _SYS_IVINTR_H */
135