1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
|
/* $Id: intr.h,v 1.1 2002/02/28 17:31:25 marcelo Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
*/
#ifndef _ASM_IA64_SN_SN1_INTR_H
#define _ASM_IA64_SN_SN1_INTR_H
/* Subnode wildcard */
#define SUBNODE_ANY (-1)
/* Number of interrupt levels associated with each interrupt register. */
#define N_INTPEND_BITS 64
#define INT_PEND0_BASELVL 0
#define INT_PEND1_BASELVL 64
#define N_INTPENDJUNK_BITS 8
#define INTPENDJUNK_CLRBIT 0x80
#include <asm/sn/intr_public.h>
#include <asm/sn/driver.h>
#include <asm/sn/xtalk/xtalk.h>
#include <asm/sn/hack.h>
#ifndef __ASSEMBLY__
#define II_NAMELEN 24
/*
* Dispatch table entry - contains information needed to call an interrupt
* routine.
*/
typedef struct intr_vector_s {
intr_func_t iv_func; /* Interrupt handler function */
intr_func_t iv_prefunc; /* Interrupt handler prologue func */
void *iv_arg; /* Argument to pass to handler */
cpuid_t iv_mustruncpu; /* Where we must run. */
} intr_vector_t;
/* Interrupt information table. */
typedef struct intr_info_s {
xtalk_intr_setfunc_t ii_setfunc; /* Function to set the interrupt
* destination and level register.
* It returns 0 (success) or an
* error code.
*/
void *ii_cookie; /* arg passed to setfunc */
devfs_handle_t ii_owner_dev; /* device that owns this intr */
char ii_name[II_NAMELEN]; /* Name of this intr. */
int ii_flags; /* informational flags */
} intr_info_t;
#define THD_CREATED 0x00000001 /*
* We've created a thread for this
* interrupt.
*/
/*
* Bits for ii_flags:
*/
#define II_UNRESERVE 0
#define II_RESERVE 1 /* Interrupt reserved. */
#define II_INUSE 2 /* Interrupt connected */
#define II_ERRORINT 4 /* INterrupt is an error condition */
#define II_THREADED 8 /* Interrupt handler is threaded. */
/*
* Interrupt level wildcard
*/
#define INTRCONNECT_ANYBIT (-1)
/*
* This structure holds information needed both to call and to maintain
* interrupts. The two are in separate arrays for the locality benefits.
* Since there's only one set of vectors per hub chip (but more than one
* CPU, the lock to change the vector tables must be here rather than in
* the PDA.
*/
typedef struct intr_vecblk_s {
intr_vector_t vectors[N_INTPEND_BITS]; /* information needed to
call an intr routine. */
intr_info_t info[N_INTPEND_BITS]; /* information needed only
to maintain interrupts. */
spinlock_t vector_lock; /* Lock for this and the
masks in the PDA. */
splfunc_t vector_spl; /* vector_lock req'd spl */
int vector_state; /* Initialized to zero.
Set to INTR_INITED
by hubintr_init.
*/
int vector_count; /* Number of vectors
* reserved.
*/
int cpu_count[CPUS_PER_SUBNODE]; /* How many interrupts are
* connected to each CPU
*/
int ithreads_enabled; /* Are interrupt threads
* initialized on this node.
* and block?
*/
} intr_vecblk_t;
/* Possible values for vector_state: */
#define VECTOR_UNINITED 0
#define VECTOR_INITED 1
#define VECTOR_SET 2
#define hub_intrvect0 private.p_intmasks.dispatch0->vectors
#define hub_intrvect1 private.p_intmasks.dispatch1->vectors
#define hub_intrinfo0 private.p_intmasks.dispatch0->info
#define hub_intrinfo1 private.p_intmasks.dispatch1->info
/*
* Macros to manipulate the interrupt register on the calling hub chip.
*/
#define LOCAL_HUB_SEND_INTR(_level) LOCAL_HUB_S(PI_INT_PEND_MOD, \
(0x100|(_level)))
#define REMOTE_HUB_PI_SEND_INTR(_hub, _sn, _level) \
REMOTE_HUB_PI_S((_hub), _sn, PI_INT_PEND_MOD, (0x100|(_level)))
#define REMOTE_CPU_SEND_INTR(_cpuid, _level) \
REMOTE_HUB_PI_S(cpuid_to_nasid(_cpuid), \
SUBNODE(cpuid_to_slice(_cpuid)), \
PI_INT_PEND_MOD, (0x100|(_level)))
/*
* When clearing the interrupt, make sure this clear does make it
* to the hub. Otherwise we could end up losing interrupts.
* We do an uncached load of the int_pend0 register to ensure this.
*/
#define LOCAL_HUB_CLR_INTR(_level) \
LOCAL_HUB_S(PI_INT_PEND_MOD, (_level)), \
LOCAL_HUB_L(PI_INT_PEND0)
#define REMOTE_HUB_PI_CLR_INTR(_hub, _sn, _level) \
REMOTE_HUB_PI_S((_hub), (_sn), PI_INT_PEND_MOD, (_level)), \
REMOTE_HUB_PI_L((_hub), (_sn), PI_INT_PEND0)
/* Special support for use by gfx driver only. Supports special gfx hub interrupt. */
extern void install_gfxintr(cpuid_t cpu, ilvl_t swlevel, intr_func_t intr_func, void *intr_arg);
void setrtvector(intr_func_t func);
/*
* Interrupt blocking
*/
extern void intr_block_bit(cpuid_t cpu, int bit);
extern void intr_unblock_bit(cpuid_t cpu, int bit);
#endif /* __ASSEMBLY__ */
/*
* Hard-coded interrupt levels:
*/
/*
* L0 = SW1
* L1 = SW2
* L2 = INT_PEND0
* L3 = INT_PEND1
* L4 = RTC
* L5 = Profiling Timer
* L6 = Hub Errors
* L7 = Count/Compare (T5 counters)
*/
/* INT_PEND0 hard-coded bits. */
#ifdef DEBUG_INTR_TSTAMP
/* hard coded interrupt level for interrupt latency test interrupt */
#define CPU_INTRLAT_B 62
#define CPU_INTRLAT_A 61
#endif
/* Hardcoded bits required by software. */
#define MSC_MESG_INTR 9
#define CPU_ACTION_B 8
#define CPU_ACTION_A 7
/* These are determined by hardware: */
#define CC_PEND_B 6
#define CC_PEND_A 5
#define UART_INTR 4
#define PG_MIG_INTR 3
#define GFX_INTR_B 2
#define GFX_INTR_A 1
#define RESERVED_INTR 0
/* INT_PEND1 hard-coded bits: */
#define MSC_PANIC_INTR 63
#define NI_ERROR_INTR 62
#define MD_COR_ERR_INTR 61
#define COR_ERR_INTR_B 60
#define COR_ERR_INTR_A 59
#define CLK_ERR_INTR 58
# define NACK_INT_B 57
# define NACK_INT_A 56
# define LB_ERROR 55
# define XB_ERROR 54
#define BRIDGE_ERROR_INTR 53 /* Setup by PROM to catch Bridge Errors */
#define IP27_INTR_0 52 /* Reserved for PROM use */
#define IP27_INTR_1 51 /* (do not use in Kernel) */
#define IP27_INTR_2 50
#define IP27_INTR_3 49
#define IP27_INTR_4 48
#define IP27_INTR_5 47
#define IP27_INTR_6 46
#define IP27_INTR_7 45
#define TLB_INTR_B 44 /* used for tlb flush random */
#define TLB_INTR_A 43
#define LLP_PFAIL_INTR_B 42 /* see ml/SN/SN0/sysctlr.c */
#define LLP_PFAIL_INTR_A 41
#define NI_BRDCAST_ERR_B 40
#define NI_BRDCAST_ERR_A 39
# define IO_ERROR_INTR 38 /* set up by prom */
# define DEBUG_INTR_B 37 /* used by symmon to stop all cpus */
# define DEBUG_INTR_A 36
// These aren't strictly accurate or complete. See the
// Synergy Spec. for details.
#define SGI_UART_IRQ (65)
#define SGI_HUB_ERROR_IRQ (182)
#endif /* _ASM_IA64_SN_SN1_INTR_H */
|