aboutsummaryrefslogtreecommitdiff
path: root/sys/mips/nlm/hal/pic.h
blob: 05a2678797275b0abd5c583067e0934979da246f (plain) (blame)
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
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
/*-
 * SPDX-License-Identifier: BSD-2-Clause
 *
 * Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 * NETLOGIC_BSD
 * $FreeBSD$
 */

#ifndef _NLM_HAL_PIC_H
#define	_NLM_HAL_PIC_H

/* PIC Specific registers */
#define	PIC_CTRL                0x00

/* PIC control register defines */
#define	PIC_CTRL_ITV		32 /* interrupt timeout value */
#define	PIC_CTRL_ICI		19 /* ICI interrupt timeout enable */
#define	PIC_CTRL_ITE		18 /* interrupt timeout enable */
#define	PIC_CTRL_STE		10 /* system timer interrupt enable */
#define	PIC_CTRL_WWR1		8  /* watchdog 1 wraparound count for reset */
#define	PIC_CTRL_WWR0		6  /* watchdog 0 wraparound count for reset */
#define	PIC_CTRL_WWN1		4  /* watchdog 1 wraparound count for NMI */
#define	PIC_CTRL_WWN0		2  /* watchdog 0 wraparound count for NMI */
#define	PIC_CTRL_WTE		0  /* watchdog timer enable */

/* PIC Status register defines */
#define	PIC_ICI_STATUS		33 /* ICI interrupt timeout status */
#define	PIC_ITE_STATUS		32 /* interrupt timeout status */
#define	PIC_STS_STATUS		4  /* System timer interrupt status */
#define	PIC_WNS_STATUS		2  /* NMI status for watchdog timers */
#define	PIC_WIS_STATUS		0  /* Interrupt status for watchdog timers */

/* PIC IPI control register offsets */
#define	PIC_IPICTRL_NMI		32
#define	PIC_IPICTRL_RIV		20 /* received interrupt vector */
#define	PIC_IPICTRL_IDB		16 /* interrupt destination base */
#define	PIC_IPICTRL_DTE		 0 /* interrupt destination thread enables */

/* PIC IRT register offsets */
#define	PIC_IRT_ENABLE		31
#define	PIC_IRT_NMI		29
#define	PIC_IRT_SCH		28 /* Scheduling scheme */
#define	PIC_IRT_RVEC		20 /* Interrupt receive vectors */
#define	PIC_IRT_DT		19 /* Destination type */
#define	PIC_IRT_DB		16 /* Destination base */
#define	PIC_IRT_DTE		0  /* Destination thread enables */

#define	PIC_BYTESWAP		0x02
#define	PIC_STATUS		0x04
#define	PIC_INTR_TIMEOUT	0x06
#define	PIC_ICI0_INTR_TIMEOUT	0x08
#define	PIC_ICI1_INTR_TIMEOUT	0x0a
#define	PIC_ICI2_INTR_TIMEOUT	0x0c
#define	PIC_IPI_CTL		0x0e
#define	PIC_INT_ACK		0x10
#define	PIC_INT_PENDING0	0x12
#define	PIC_INT_PENDING1	0x14
#define	PIC_INT_PENDING2	0x16

#define	PIC_WDOG0_MAXVAL	0x18
#define	PIC_WDOG0_COUNT		0x1a
#define	PIC_WDOG0_ENABLE0	0x1c
#define	PIC_WDOG0_ENABLE1	0x1e
#define	PIC_WDOG0_BEATCMD	0x20
#define	PIC_WDOG0_BEAT0		0x22
#define	PIC_WDOG0_BEAT1		0x24

#define	PIC_WDOG1_MAXVAL	0x26
#define	PIC_WDOG1_COUNT		0x28
#define	PIC_WDOG1_ENABLE0	0x2a
#define	PIC_WDOG1_ENABLE1	0x2c
#define	PIC_WDOG1_BEATCMD	0x2e
#define	PIC_WDOG1_BEAT0		0x30
#define	PIC_WDOG1_BEAT1		0x32

#define	PIC_WDOG_MAXVAL(i)	(PIC_WDOG0_MAXVAL + ((i) ? 7 : 0))
#define	PIC_WDOG_COUNT(i)	(PIC_WDOG0_COUNT + ((i) ? 7 : 0))
#define	PIC_WDOG_ENABLE0(i)	(PIC_WDOG0_ENABLE0 + ((i) ? 7 : 0))
#define	PIC_WDOG_ENABLE1(i)	(PIC_WDOG0_ENABLE1 + ((i) ? 7 : 0))
#define	PIC_WDOG_BEATCMD(i)	(PIC_WDOG0_BEATCMD + ((i) ? 7 : 0))
#define	PIC_WDOG_BEAT0(i)	(PIC_WDOG0_BEAT0 + ((i) ? 7 : 0))
#define	PIC_WDOG_BEAT1(i)	(PIC_WDOG0_BEAT1 + ((i) ? 7 : 0))

#define	PIC_TIMER0_MAXVAL	0x34
#define	PIC_TIMER1_MAXVAL	0x36
#define	PIC_TIMER2_MAXVAL	0x38
#define	PIC_TIMER3_MAXVAL	0x3a
#define	PIC_TIMER4_MAXVAL	0x3c
#define	PIC_TIMER5_MAXVAL	0x3e
#define	PIC_TIMER6_MAXVAL	0x40
#define	PIC_TIMER7_MAXVAL	0x42
#define	PIC_TIMER_MAXVAL(i)	(PIC_TIMER0_MAXVAL + ((i) * 2))

#define	PIC_TIMER0_COUNT	0x44
#define	PIC_TIMER1_COUNT	0x46
#define	PIC_TIMER2_COUNT	0x48
#define	PIC_TIMER3_COUNT	0x4a
#define	PIC_TIMER4_COUNT	0x4c
#define	PIC_TIMER5_COUNT	0x4e
#define	PIC_TIMER6_COUNT	0x50
#define	PIC_TIMER7_COUNT	0x52
#define	PIC_TIMER_COUNT(i)	(PIC_TIMER0_COUNT + ((i) * 2))

#define	PIC_ITE0_N0_N1		0x54
#define	PIC_ITE1_N0_N1		0x58
#define	PIC_ITE2_N0_N1		0x5c
#define	PIC_ITE3_N0_N1		0x60
#define	PIC_ITE4_N0_N1		0x64
#define	PIC_ITE5_N0_N1		0x68
#define	PIC_ITE6_N0_N1		0x6c
#define	PIC_ITE7_N0_N1		0x70
#define	PIC_ITE_N0_N1(i)	(PIC_ITE0_N0_N1 + ((i) * 4))

#define	PIC_ITE0_N2_N3		0x56
#define	PIC_ITE1_N2_N3		0x5a
#define	PIC_ITE2_N2_N3		0x5e
#define	PIC_ITE3_N2_N3		0x62
#define	PIC_ITE4_N2_N3		0x66
#define	PIC_ITE5_N2_N3		0x6a
#define	PIC_ITE6_N2_N3		0x6e
#define	PIC_ITE7_N2_N3		0x72
#define	PIC_ITE_N2_N3(i)		(PIC_ITE0_N2_N3 + ((i) * 4))

#define	PIC_IRT0		0x74
#define	PIC_IRT(i)		(PIC_IRT0 + ((i) * 2))

#define	TIMER_CYCLES_MAXVAL	0xffffffffffffffffULL

/*
 *    IRT Map
 */
#define	PIC_IRT_WD_0_INDEX	0
#define	PIC_IRT_WD_1_INDEX	1
#define	PIC_IRT_WD_NMI_0_INDEX	2
#define	PIC_IRT_WD_NMI_1_INDEX	3
#define	PIC_IRT_TIMER_0_INDEX	4
#define	PIC_IRT_TIMER_1_INDEX	5
#define	PIC_IRT_TIMER_2_INDEX	6
#define	PIC_IRT_TIMER_3_INDEX	7
#define	PIC_IRT_TIMER_4_INDEX	8
#define	PIC_IRT_TIMER_5_INDEX	9
#define	PIC_IRT_TIMER_6_INDEX	10
#define	PIC_IRT_TIMER_7_INDEX	11
#define	PIC_IRT_CLOCK_INDEX	PIC_IRT_TIMER_7_INDEX
#define	PIC_IRT_TIMER_INDEX(num)	((num) + PIC_IRT_TIMER_0_INDEX)

#define	PIC_CLOCK_TIMER			7

#if !defined(LOCORE) && !defined(__ASSEMBLY__)

/*
 *   Misc
 */
#define	PIC_IRT_VALID			1
#define	PIC_LOCAL_SCHEDULING		1
#define	PIC_GLOBAL_SCHEDULING		0

#define	nlm_read_pic_reg(b, r)	nlm_read_reg64(b, r)
#define	nlm_write_pic_reg(b, r, v) nlm_write_reg64(b, r, v)
#define	nlm_get_pic_pcibase(node) nlm_pcicfg_base(XLP_IO_PIC_OFFSET(node))
#define	nlm_get_pic_regbase(node) (nlm_get_pic_pcibase(node) + XLP_IO_PCI_HDRSZ)

/* IRT and h/w interrupt routines */
static inline int
nlm_pic_read_irt(uint64_t base, int irt_index)
{
	return nlm_read_pic_reg(base, PIC_IRT(irt_index));
}

static inline void
nlm_pic_send_ipi(uint64_t base, int cpu, int vec, int nmi)
{
	uint64_t ipi;
	int	node, ncpu;

	node = cpu / 32;
	ncpu = cpu & 0x1f;
	ipi = ((uint64_t)nmi << 31) | (vec << 20) | (node << 17) |
		(1 << (cpu & 0xf));
	if (ncpu > 15)
		ipi |= 0x10000; /* Setting bit 16 to select cpus 16-31 */

	nlm_write_pic_reg(base, PIC_IPI_CTL, ipi);
}

static inline uint64_t
nlm_pic_read_control(uint64_t base)
{
	return nlm_read_pic_reg(base, PIC_CTRL);
}

static inline void
nlm_pic_write_control(uint64_t base, uint64_t control)
{
	nlm_write_pic_reg(base, PIC_CTRL, control);
}

static inline void
nlm_pic_update_control(uint64_t base, uint64_t control)
{
	uint64_t val;

	val = nlm_read_pic_reg(base, PIC_CTRL);
	nlm_write_pic_reg(base, PIC_CTRL, control | val);
}

static inline void
nlm_pic_ack(uint64_t base, int irt_num)
{
	nlm_write_pic_reg(base, PIC_INT_ACK, irt_num);

	/* Ack the Status register for Watchdog & System timers */
	if (irt_num < 12)
		nlm_write_pic_reg(base, PIC_STATUS, (1 << irt_num));
}

static inline void
nlm_set_irt_to_cpu(uint64_t base, int irt, int cpu)
{
	uint64_t val;

	val = nlm_read_pic_reg(base, PIC_IRT(irt));
	val |= cpu & 0xf;
	if (cpu > 15)
		val |= 1 << 16;
	nlm_write_pic_reg(base, PIC_IRT(irt), val);
}

static inline void
nlm_pic_write_irt(uint64_t base, int irt_num, int en, int nmi,
	int sch, int vec, int dt, int db, int dte)
{
	uint64_t val;

	val = (((uint64_t)en & 0x1) << 31) | ((nmi & 0x1) << 29) |
			((sch & 0x1) << 28) | ((vec & 0x3f) << 20) |
			((dt & 0x1) << 19) | ((db & 0x7) << 16) |
			(dte & 0xffff);

	nlm_write_pic_reg(base, PIC_IRT(irt_num), val);
}

static inline void
nlm_pic_write_irt_direct(uint64_t base, int irt_num, int en, int nmi,
	int sch, int vec, int cpu)
{
	nlm_pic_write_irt(base, irt_num, en, nmi, sch, vec, 1,
		(cpu >> 4),		/* thread group */
		1 << (cpu & 0xf));	/* thread mask */
}

static inline uint64_t
nlm_pic_read_timer(uint64_t base, int timer)
{
	return nlm_read_pic_reg(base, PIC_TIMER_COUNT(timer));
}

static inline void
nlm_pic_write_timer(uint64_t base, int timer, uint64_t value)
{
	nlm_write_pic_reg(base, PIC_TIMER_COUNT(timer), value);
}

static inline void
nlm_pic_set_timer(uint64_t base, int timer, uint64_t value, int irq, int cpu)
{
	uint64_t pic_ctrl;
	int en, nmi;

	en = nmi = 0;
	if (irq > 0)
		en = 1;
	else if (irq < 0) {
		en = nmi = 1;
		irq = -irq;
	}
	nlm_write_pic_reg(base, PIC_TIMER_MAXVAL(timer), value);
	nlm_pic_write_irt_direct(base, PIC_IRT_TIMER_INDEX(timer),
		en, nmi, 0, irq, cpu);

	/* enable the timer */
	pic_ctrl = nlm_read_pic_reg(base, PIC_CTRL);
	pic_ctrl |= (1 << (PIC_CTRL_STE + timer));
	nlm_write_pic_reg(base, PIC_CTRL, pic_ctrl);
}

#endif /* __ASSEMBLY__ */
#endif /* _NLM_HAL_PIC_H */