Fri Apr 2 12:11:42 2021 UTC ()
For ports with __HAVE_LEGACY_INTRCNT, turn intrcnt[] and derived
variables into u_int, to match with kern/subr_evcnt.c.


(rin)
diff -r1.21 -r1.22 src/sys/arch/atari/include/intr.h
diff -r1.18 -r1.19 src/sys/arch/cesfic/cesfic/isr.c
diff -r1.24 -r1.25 src/sys/arch/luna68k/luna68k/isr.c
diff -r1.31 -r1.32 src/sys/arch/mac68k/mac68k/intr.c
diff -r1.35 -r1.36 src/sys/arch/mvme68k/mvme68k/isr.c
diff -r1.31 -r1.32 src/sys/arch/next68k/next68k/isr.c
diff -r1.64 -r1.65 src/sys/arch/sun3/sun3/clock.c
diff -r1.40 -r1.41 src/sys/arch/sun3/sun3x/clock.c

cvs diff -r1.21 -r1.22 src/sys/arch/atari/include/intr.h (switch to unified diff)

--- src/sys/arch/atari/include/intr.h 2009/07/08 12:23:10 1.21
+++ src/sys/arch/atari/include/intr.h 2021/04/02 12:11:41 1.22
@@ -1,136 +1,136 @@ @@ -1,136 +1,136 @@
1/* $NetBSD: intr.h,v 1.21 2009/07/08 12:23:10 tsutsui Exp $ */ 1/* $NetBSD: intr.h,v 1.22 2021/04/02 12:11:41 rin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1996, 1997, 2007 The NetBSD Foundation, Inc. 4 * Copyright (c) 1996, 1997, 2007 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Leo Weppelman. 8 * by Leo Weppelman.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#ifndef _ATARI_INTR_H_ 32#ifndef _ATARI_INTR_H_
33#define _ATARI_INTR_H_ 33#define _ATARI_INTR_H_
34 34
35#define IPL_NONE 0 /* disable no interrupts */ 35#define IPL_NONE 0 /* disable no interrupts */
36#define IPL_SOFTCLOCK 1 36#define IPL_SOFTCLOCK 1
37#define IPL_SOFTBIO 2 37#define IPL_SOFTBIO 2
38#define IPL_SOFTNET 3 38#define IPL_SOFTNET 3
39#define IPL_SOFTSERIAL 4 39#define IPL_SOFTSERIAL 4
40#define IPL_VM 5 40#define IPL_VM 5
41#define IPL_SCHED 6 41#define IPL_SCHED 6
42#define IPL_HIGH 7 42#define IPL_HIGH 7
43#define NIPL 8 43#define NIPL 8
44 44
45#define IST_UNUSABLE -1 /* interrupt cannot be used */ 45#define IST_UNUSABLE -1 /* interrupt cannot be used */
46#define IST_NONE 0 /* none (dummy) */ 46#define IST_NONE 0 /* none (dummy) */
47#define IST_PULSE 1 /* pulsed */ 47#define IST_PULSE 1 /* pulsed */
48#define IST_EDGE 2 /* edge-triggered */ 48#define IST_EDGE 2 /* edge-triggered */
49#define IST_LEVEL 3 /* level-triggered */ 49#define IST_LEVEL 3 /* level-triggered */
50 50
51/* 51/*
52 * spl functions; all but spl0 are done in-line 52 * spl functions; all but spl0 are done in-line
53 */ 53 */
54#include <machine/psl.h> 54#include <machine/psl.h>
55 55
56/* spl0 requires checking for software interrupts */ 56/* spl0 requires checking for software interrupts */
57 57
58#define splsoftclock() splraise1() 58#define splsoftclock() splraise1()
59#define splsoftbio() splraise1() 59#define splsoftbio() splraise1()
60#define splsoftnet() splraise1() 60#define splsoftnet() splraise1()
61#define splsoftserial() splraise1() 61#define splsoftserial() splraise1()
62#define splvm() splraise4() 62#define splvm() splraise4()
63#define splsched() splraise6() 63#define splsched() splraise6()
64#define splhigh() spl7() 64#define splhigh() spl7()
65#define splx(s) ((s) & PSL_IPL ? _spl(s) : spl0()) 65#define splx(s) ((s) & PSL_IPL ? _spl(s) : spl0())
66 66
67#ifdef _KERNEL 67#ifdef _KERNEL
68int spl0(void); 68int spl0(void);
69 69
70extern const uint16_t ipl2psl_table[NIPL]; 70extern const uint16_t ipl2psl_table[NIPL];
71extern int idepth; 71extern int idepth;
72 72
73typedef int ipl_t; 73typedef int ipl_t;
74typedef struct { 74typedef struct {
75 uint16_t _psl; 75 uint16_t _psl;
76} ipl_cookie_t; 76} ipl_cookie_t;
77 77
78static inline ipl_cookie_t 78static inline ipl_cookie_t
79makeiplcookie(ipl_t ipl) 79makeiplcookie(ipl_t ipl)
80{ 80{
81 81
82 return (ipl_cookie_t){._psl = ipl2psl_table[ipl]}; 82 return (ipl_cookie_t){._psl = ipl2psl_table[ipl]};
83} 83}
84 84
85static inline int 85static inline int
86splraiseipl(ipl_cookie_t icookie) 86splraiseipl(ipl_cookie_t icookie)
87{ 87{
88 88
89 return _splraise(icookie._psl); 89 return _splraise(icookie._psl);
90} 90}
91 91
92#include <sys/queue.h> 92#include <sys/queue.h>
93#include <machine/cpu.h> /* XXX: for clockframe */ 93#include <machine/cpu.h> /* XXX: for clockframe */
94 94
95struct clockframe; 95struct clockframe;
96 96
97#define AUTO_VEC 0x0001 /* We're dealing with an auto-vector */ 97#define AUTO_VEC 0x0001 /* We're dealing with an auto-vector */
98#define USER_VEC 0x0002 /* We're dealing with an user-vector */ 98#define USER_VEC 0x0002 /* We're dealing with an user-vector */
99 99
100#define FAST_VEC 0x0010 /* Fast, stash right into vector-table */ 100#define FAST_VEC 0x0010 /* Fast, stash right into vector-table */
101#define ARG_CLOCKFRAME 0x0020 /* Supply clockframe as an argument */ 101#define ARG_CLOCKFRAME 0x0020 /* Supply clockframe as an argument */
102 102
103/* 103/*
104 * Interrupt handler chains. intr_establish() inserts a handler into 104 * Interrupt handler chains. intr_establish() inserts a handler into
105 * the list. The handler is called with its (single) argument or with a 105 * the list. The handler is called with its (single) argument or with a
106 * 'standard' clockframe. This depends on 'ih_type'. 106 * 'standard' clockframe. This depends on 'ih_type'.
107 */ 107 */
108typedef int (*hw_ifun_t)(void *, int); 108typedef int (*hw_ifun_t)(void *, int);
109 109
110struct intrhand { 110struct intrhand {
111 LIST_ENTRY(intrhand) ih_link; 111 LIST_ENTRY(intrhand) ih_link;
112 hw_ifun_t ih_fun; 112 hw_ifun_t ih_fun;
113 void *ih_arg; 113 void *ih_arg;
114 int ih_type; 114 int ih_type;
115 int ih_pri; 115 int ih_pri;
116 int ih_vector; 116 int ih_vector;
117 u_long *ih_intrcnt; 117 u_int *ih_intrcnt;
118}; 118};
119 119
120void intr_init(void); 120void intr_init(void);
121struct intrhand *intr_establish(int, int, int, hw_ifun_t, void *); 121struct intrhand *intr_establish(int, int, int, hw_ifun_t, void *);
122int intr_disestablish(struct intrhand *); 122int intr_disestablish(struct intrhand *);
123void intr_dispatch(struct clockframe); 123void intr_dispatch(struct clockframe);
124void intr_glue(void); 124void intr_glue(void);
125 125
126/* 126/*
127 * Exported by intrcnt.h 127 * Exported by intrcnt.h
128 */ 128 */
129extern u_long autovects[]; 129extern u_long autovects[];
130extern u_long intrcnt_auto[]; 130extern u_int intrcnt_auto[];
131extern u_long uservects[]; 131extern u_long uservects[];
132extern u_long intrcnt_user[]; 132extern u_int intrcnt_user[];
133 133
134#endif /* _KERNEL */ 134#endif /* _KERNEL */
135 135
136#endif /* _ATARI_INTR_H_ */ 136#endif /* _ATARI_INTR_H_ */

cvs diff -r1.18 -r1.19 src/sys/arch/cesfic/cesfic/isr.c (switch to unified diff)

--- src/sys/arch/cesfic/cesfic/isr.c 2020/11/18 03:40:50 1.18
+++ src/sys/arch/cesfic/cesfic/isr.c 2021/04/02 12:11:41 1.19
@@ -1,218 +1,218 @@ @@ -1,218 +1,218 @@
1/* $NetBSD: isr.c,v 1.18 2020/11/18 03:40:50 thorpej Exp $ */ 1/* $NetBSD: isr.c,v 1.19 2021/04/02 12:11:41 rin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1996 The NetBSD Foundation, Inc. 4 * Copyright (c) 1996 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Adam Glass, Gordon W. Ross, and Jason R. Thorpe. 8 * by Adam Glass, Gordon W. Ross, and Jason R. Thorpe.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Link and dispatch interrupts. 33 * Link and dispatch interrupts.
34 */ 34 */
35 35
36#include <sys/cdefs.h> 36#include <sys/cdefs.h>
37__KERNEL_RCSID(0, "$NetBSD: isr.c,v 1.18 2020/11/18 03:40:50 thorpej Exp $"); 37__KERNEL_RCSID(0, "$NetBSD: isr.c,v 1.19 2021/04/02 12:11:41 rin Exp $");
38 38
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/systm.h> 40#include <sys/systm.h>
41#include <sys/queue.h> 41#include <sys/queue.h>
42#include <sys/kmem.h> 42#include <sys/kmem.h>
43#include <sys/vmmeter.h> 43#include <sys/vmmeter.h>
44#include <sys/cpu.h> 44#include <sys/cpu.h>
45 45
46#include <uvm/uvm_extern.h> 46#include <uvm/uvm_extern.h>
47 47
48#include <cesfic/cesfic/isr.h> 48#include <cesfic/cesfic/isr.h>
49 49
50typedef LIST_HEAD(, isr) isr_list_t; 50typedef LIST_HEAD(, isr) isr_list_t;
51isr_list_t isr_list[NISR]; 51isr_list_t isr_list[NISR];
52 52
53extern int intrcnt[]; /* from locore.s */ 53extern u_int intrcnt[]; /* from locore.s */
54 54
55void 55void
56isrinit(void) 56isrinit(void)
57{ 57{
58 int i; 58 int i;
59 59
60 /* Initialize the ISR lists. */ 60 /* Initialize the ISR lists. */
61 for (i = 0; i < NISR; ++i) { 61 for (i = 0; i < NISR; ++i) {
62 LIST_INIT(&isr_list[i]); 62 LIST_INIT(&isr_list[i]);
63 } 63 }
64} 64}
65 65
66/* 66/*
67 * Establish an interrupt handler. 67 * Establish an interrupt handler.
68 * Called by driver attach functions. 68 * Called by driver attach functions.
69 */ 69 */
70void * 70void *
71isrlink(int (*func)(void *), void *arg, int ipl, int priority) 71isrlink(int (*func)(void *), void *arg, int ipl, int priority)
72{ 72{
73 struct isr *newisr, *curisr; 73 struct isr *newisr, *curisr;
74 isr_list_t *list; 74 isr_list_t *list;
75 75
76 if ((ipl < 0) || (ipl >= NISR)) 76 if ((ipl < 0) || (ipl >= NISR))
77 panic("isrlink: bad ipl %d", ipl); 77 panic("isrlink: bad ipl %d", ipl);
78 78
79 newisr = kmem_alloc(sizeof(*newisr), KM_SLEEP); 79 newisr = kmem_alloc(sizeof(*newisr), KM_SLEEP);
80 newisr->isr_func = func; 80 newisr->isr_func = func;
81 newisr->isr_arg = arg; 81 newisr->isr_arg = arg;
82 newisr->isr_ipl = ipl; 82 newisr->isr_ipl = ipl;
83 newisr->isr_priority = priority; 83 newisr->isr_priority = priority;
84 84
85 /* 85 /*
86 * Some devices are particularly sensitive to interrupt 86 * Some devices are particularly sensitive to interrupt
87 * handling latency. The DCA, for example, can lose many 87 * handling latency. The DCA, for example, can lose many
88 * characters if its interrupt isn't handled with reasonable 88 * characters if its interrupt isn't handled with reasonable
89 * speed. 89 * speed.
90 * 90 *
91 * To work around this problem, each device can give itself a 91 * To work around this problem, each device can give itself a
92 * "priority". An unbuffered DCA would give itself a higher 92 * "priority". An unbuffered DCA would give itself a higher
93 * priority than a SCSI device, for example. 93 * priority than a SCSI device, for example.
94 * 94 *
95 * This is necessary because of the flat spl scheme employed by 95 * This is necessary because of the flat spl scheme employed by
96 * the hp300. Each device can be set from ipl 3 to ipl 5, which 96 * the hp300. Each device can be set from ipl 3 to ipl 5, which
97 * in turn means that splbio, splnet, and spltty must all be at 97 * in turn means that splbio, splnet, and spltty must all be at
98 * spl5. 98 * spl5.
99 * 99 *
100 * Don't blame me...I just work here. 100 * Don't blame me...I just work here.
101 */ 101 */
102 102
103 /* 103 /*
104 * Get the appropriate ISR list. If the list is empty, no 104 * Get the appropriate ISR list. If the list is empty, no
105 * additional work is necessary; we simply insert ourselves 105 * additional work is necessary; we simply insert ourselves
106 * at the head of the list. 106 * at the head of the list.
107 */ 107 */
108 list = &isr_list[ipl]; 108 list = &isr_list[ipl];
109 if (list->lh_first == NULL) { 109 if (list->lh_first == NULL) {
110 LIST_INSERT_HEAD(list, newisr, isr_link); 110 LIST_INSERT_HEAD(list, newisr, isr_link);
111 goto done; 111 goto done;
112 } 112 }
113 113
114 /* 114 /*
115 * A little extra work is required. We traverse the list 115 * A little extra work is required. We traverse the list
116 * and place ourselves after any ISRs with our current (or 116 * and place ourselves after any ISRs with our current (or
117 * higher) priority. 117 * higher) priority.
118 */ 118 */
119 for (curisr = list->lh_first; curisr->isr_link.le_next != NULL; 119 for (curisr = list->lh_first; curisr->isr_link.le_next != NULL;
120 curisr = curisr->isr_link.le_next) { 120 curisr = curisr->isr_link.le_next) {
121 if (newisr->isr_priority > curisr->isr_priority) { 121 if (newisr->isr_priority > curisr->isr_priority) {
122 LIST_INSERT_BEFORE(curisr, newisr, isr_link); 122 LIST_INSERT_BEFORE(curisr, newisr, isr_link);
123 goto done; 123 goto done;
124 } 124 }
125 } 125 }
126 126
127 /* 127 /*
128 * We're the least important entry, it seems. We just go 128 * We're the least important entry, it seems. We just go
129 * on the end. 129 * on the end.
130 */ 130 */
131 LIST_INSERT_AFTER(curisr, newisr, isr_link); 131 LIST_INSERT_AFTER(curisr, newisr, isr_link);
132 132
133 done: 133 done:
134 return (newisr); 134 return (newisr);
135} 135}
136 136
137#if 0 137#if 0
138/* 138/*
139 * Disestablish an interrupt handler. 139 * Disestablish an interrupt handler.
140 */ 140 */
141void 141void
142isrunlink(void *arg) 142isrunlink(void *arg)
143{ 143{
144 struct isr *isr = arg; 144 struct isr *isr = arg;
145 145
146 LIST_REMOVE(isr, isr_link); 146 LIST_REMOVE(isr, isr_link);
147 kmem_free(isr, sizeof(*isr)); 147 kmem_free(isr, sizeof(*isr));
148} 148}
149#endif 149#endif
150 150
151/* 151/*
152 * This is the dispatcher called by the low-level 152 * This is the dispatcher called by the low-level
153 * assembly language interrupt routine. 153 * assembly language interrupt routine.
154 */ 154 */
155static unsigned int idepth; 155static unsigned int idepth;
156  156
157void 157void
158isrdispatch(int evec) 158isrdispatch(int evec)
159 /* evec: format | vector offset */ 159 /* evec: format | vector offset */
160{ 160{
161 struct isr *isr; 161 struct isr *isr;
162 isr_list_t *list; 162 isr_list_t *list;
163 int handled, ipl, vec; 163 int handled, ipl, vec;
164 static int straycount, unexpected; 164 static int straycount, unexpected;
165 165
166 vec = (evec & 0xfff) >> 2; 166 vec = (evec & 0xfff) >> 2;
167 if ((vec < ISRLOC) || (vec >= (ISRLOC + NISR))) 167 if ((vec < ISRLOC) || (vec >= (ISRLOC + NISR)))
168 panic("isrdispatch: bad vec 0x%x", vec); 168 panic("isrdispatch: bad vec 0x%x", vec);
169 ipl = vec - ISRLOC; 169 ipl = vec - ISRLOC;
170 170
171 intrcnt[ipl]++; 171 intrcnt[ipl]++;
172 curcpu()->ci_data.cpu_nintr++; 172 curcpu()->ci_data.cpu_nintr++;
173 173
174 if (ipl >= IPL_VM) 174 if (ipl >= IPL_VM)
175 idepth++; 175 idepth++;
176 176
177 list = &isr_list[ipl]; 177 list = &isr_list[ipl];
178 if (list->lh_first == NULL) { 178 if (list->lh_first == NULL) {
179 printf("intrhand: ipl %d unexpected\n", ipl); 179 printf("intrhand: ipl %d unexpected\n", ipl);
180 if (++unexpected > 10) 180 if (++unexpected > 10)
181 panic("isrdispatch: too many unexpected interrupts"); 181 panic("isrdispatch: too many unexpected interrupts");
182 goto out; 182 goto out;
183 } 183 }
184 184
185 handled = 0; 185 handled = 0;
186 /* Give all the handlers a chance. */ 186 /* Give all the handlers a chance. */
187 for (isr = list->lh_first ; isr != NULL; isr = isr->isr_link.le_next) 187 for (isr = list->lh_first ; isr != NULL; isr = isr->isr_link.le_next)
188 handled |= (*isr->isr_func)(isr->isr_arg); 188 handled |= (*isr->isr_func)(isr->isr_arg);
189 189
190 if (handled) 190 if (handled)
191 straycount = 0; 191 straycount = 0;
192 else if (++straycount > 50) 192 else if (++straycount > 50)
193 panic("isrdispatch: too many stray interrupts"); 193 panic("isrdispatch: too many stray interrupts");
194 else 194 else
195 printf("isrdispatch: stray level %d interrupt\n", ipl); 195 printf("isrdispatch: stray level %d interrupt\n", ipl);
196 196
197 out: 197 out:
198 if (ipl >= IPL_VM) 198 if (ipl >= IPL_VM)
199 idepth--; 199 idepth--;
200} 200}
201 201
202bool 202bool
203cpu_intr_p(void) 203cpu_intr_p(void)
204{ 204{
205 205
206 return idepth != 0; 206 return idepth != 0;
207} 207}
208 208
209const uint16_t ipl2psl_table[NIPL] = { 209const uint16_t ipl2psl_table[NIPL] = {
210 [IPL_NONE] = PSL_S|PSL_IPL0, 210 [IPL_NONE] = PSL_S|PSL_IPL0,
211 [IPL_SOFTCLOCK] = PSL_S|PSL_IPL1, 211 [IPL_SOFTCLOCK] = PSL_S|PSL_IPL1,
212 [IPL_SOFTBIO] = PSL_S|PSL_IPL1, 212 [IPL_SOFTBIO] = PSL_S|PSL_IPL1,
213 [IPL_SOFTNET] = PSL_S|PSL_IPL1, 213 [IPL_SOFTNET] = PSL_S|PSL_IPL1,
214 [IPL_SOFTSERIAL] = PSL_S|PSL_IPL1, 214 [IPL_SOFTSERIAL] = PSL_S|PSL_IPL1,
215 [IPL_VM] = PSL_S|PSL_IPL4, 215 [IPL_VM] = PSL_S|PSL_IPL4,
216 [IPL_SCHED] = PSL_S|PSL_IPL6, 216 [IPL_SCHED] = PSL_S|PSL_IPL6,
217 [IPL_HIGH] = PSL_S|PSL_IPL7, 217 [IPL_HIGH] = PSL_S|PSL_IPL7,
218}; 218};

cvs diff -r1.24 -r1.25 src/sys/arch/luna68k/luna68k/isr.c (switch to unified diff)

--- src/sys/arch/luna68k/luna68k/isr.c 2020/12/19 21:38:30 1.24
+++ src/sys/arch/luna68k/luna68k/isr.c 2021/04/02 12:11:41 1.25
@@ -1,279 +1,279 @@ @@ -1,279 +1,279 @@
1/* $NetBSD: isr.c,v 1.24 2020/12/19 21:38:30 thorpej Exp $ */ 1/* $NetBSD: isr.c,v 1.25 2021/04/02 12:11:41 rin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1996 The NetBSD Foundation, Inc. 4 * Copyright (c) 1996 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Adam Glass, Gordon W. Ross, and Jason R. Thorpe. 8 * by Adam Glass, Gordon W. Ross, and Jason R. Thorpe.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 32#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
33 33
34__KERNEL_RCSID(0, "$NetBSD: isr.c,v 1.24 2020/12/19 21:38:30 thorpej Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: isr.c,v 1.25 2021/04/02 12:11:41 rin Exp $");
35 35
36/* 36/*
37 * Link and dispatch interrupts. 37 * Link and dispatch interrupts.
38 */ 38 */
39 39
40#include <sys/param.h> 40#include <sys/param.h>
41#include <sys/systm.h> 41#include <sys/systm.h>
42#include <sys/kmem.h> 42#include <sys/kmem.h>
43#include <sys/vmmeter.h> 43#include <sys/vmmeter.h>
44#include <sys/cpu.h> 44#include <sys/cpu.h>
45 45
46#include <uvm/uvm_extern.h> 46#include <uvm/uvm_extern.h>
47 47
48#include <luna68k/luna68k/isr.h> 48#include <luna68k/luna68k/isr.h>
49 49
50isr_autovec_list_t isr_autovec[NISRAUTOVEC]; 50isr_autovec_list_t isr_autovec[NISRAUTOVEC];
51struct isr_vectored isr_vectored[NISRVECTORED]; 51struct isr_vectored isr_vectored[NISRVECTORED];
52int idepth; 52int idepth;
53 53
54extern int intrcnt[]; /* from locore.s */ 54extern u_int intrcnt[]; /* from locore.s */
55extern void (*vectab[])(void); 55extern void (*vectab[])(void);
56extern void badtrap(void); 56extern void badtrap(void);
57extern void intrhand_vectored(void); 57extern void intrhand_vectored(void);
58 58
59extern int getsr(void); /* in locore.s */ 59extern int getsr(void); /* in locore.s */
60 60
61void 61void
62isrinit(void) 62isrinit(void)
63{ 63{
64 int i; 64 int i;
65 65
66 /* Initialize the autovector lists. */ 66 /* Initialize the autovector lists. */
67 for (i = 0; i < NISRAUTOVEC; ++i) { 67 for (i = 0; i < NISRAUTOVEC; ++i) {
68 LIST_INIT(&isr_autovec[i]); 68 LIST_INIT(&isr_autovec[i]);
69 } 69 }
70} 70}
71 71
72/* 72/*
73 * Establish an autovectored interrupt handler. 73 * Establish an autovectored interrupt handler.
74 * Called by driver attach functions. 74 * Called by driver attach functions.
75 */ 75 */
76void 76void
77isrlink_autovec(int (*func)(void *), void *arg, int ipl, int priority) 77isrlink_autovec(int (*func)(void *), void *arg, int ipl, int priority)
78{ 78{
79 struct isr_autovec *newisr, *curisr; 79 struct isr_autovec *newisr, *curisr;
80 isr_autovec_list_t *list; 80 isr_autovec_list_t *list;
81 81
82 if ((ipl < 0) || (ipl >= NISRAUTOVEC)) 82 if ((ipl < 0) || (ipl >= NISRAUTOVEC))
83 panic("isrlink_autovec: bad ipl %d", ipl); 83 panic("isrlink_autovec: bad ipl %d", ipl);
84 84
85 newisr = kmem_alloc(sizeof(*newisr), KM_SLEEP); 85 newisr = kmem_alloc(sizeof(*newisr), KM_SLEEP);
86 newisr->isr_func = func; 86 newisr->isr_func = func;
87 newisr->isr_arg = arg; 87 newisr->isr_arg = arg;
88 newisr->isr_ipl = ipl; 88 newisr->isr_ipl = ipl;
89 newisr->isr_priority = priority; 89 newisr->isr_priority = priority;
90 90
91 /* 91 /*
92 * Some devices are particularly sensitive to interrupt 92 * Some devices are particularly sensitive to interrupt
93 * handling latency. The SCC, for example, can lose many 93 * handling latency. The SCC, for example, can lose many
94 * characters if its interrupt isn't handled with reasonable 94 * characters if its interrupt isn't handled with reasonable
95 * speed. 95 * speed.
96 * 96 *
97 * To work around this problem, each device can give itself a 97 * To work around this problem, each device can give itself a
98 * "priority". An unbuffered SCC would give itself a higher 98 * "priority". An unbuffered SCC would give itself a higher
99 * priority than a SCSI device, for example. 99 * priority than a SCSI device, for example.
100 * 100 *
101 * This solution was originally developed for the hp300, which 101 * This solution was originally developed for the hp300, which
102 * has a flat spl scheme (by necessity). Thankfully, the 102 * has a flat spl scheme (by necessity). Thankfully, the
103 * MVME systems don't have this problem, though this may serve 103 * MVME systems don't have this problem, though this may serve
104 * a useful purpose in any case. 104 * a useful purpose in any case.
105 */ 105 */
106 106
107 /* 107 /*
108 * Get the appropriate ISR list. If the list is empty, no 108 * Get the appropriate ISR list. If the list is empty, no
109 * additional work is necessary; we simply insert ourselves 109 * additional work is necessary; we simply insert ourselves
110 * at the head of the list. 110 * at the head of the list.
111 */ 111 */
112 list = &isr_autovec[ipl]; 112 list = &isr_autovec[ipl];
113 if (list->lh_first == NULL) { 113 if (list->lh_first == NULL) {
114 LIST_INSERT_HEAD(list, newisr, isr_link); 114 LIST_INSERT_HEAD(list, newisr, isr_link);
115 return; 115 return;
116 } 116 }
117 117
118 /* 118 /*
119 * A little extra work is required. We traverse the list 119 * A little extra work is required. We traverse the list
120 * and place ourselves after any ISRs with our current (or 120 * and place ourselves after any ISRs with our current (or
121 * higher) priority. 121 * higher) priority.
122 */ 122 */
123 for (curisr = list->lh_first; curisr->isr_link.le_next != NULL; 123 for (curisr = list->lh_first; curisr->isr_link.le_next != NULL;
124 curisr = curisr->isr_link.le_next) { 124 curisr = curisr->isr_link.le_next) {
125 if (newisr->isr_priority > curisr->isr_priority) { 125 if (newisr->isr_priority > curisr->isr_priority) {
126 LIST_INSERT_BEFORE(curisr, newisr, isr_link); 126 LIST_INSERT_BEFORE(curisr, newisr, isr_link);
127 return; 127 return;
128 } 128 }
129 } 129 }
130 130
131 /* 131 /*
132 * We're the least important entry, it seems. We just go 132 * We're the least important entry, it seems. We just go
133 * on the end. 133 * on the end.
134 */ 134 */
135 LIST_INSERT_AFTER(curisr, newisr, isr_link); 135 LIST_INSERT_AFTER(curisr, newisr, isr_link);
136} 136}
137 137
138/* 138/*
139 * Establish a vectored interrupt handler. 139 * Establish a vectored interrupt handler.
140 * Called by bus interrupt establish functions. 140 * Called by bus interrupt establish functions.
141 */ 141 */
142void 142void
143isrlink_vectored(int (*func)(void *), void *arg, int ipl, int vec) 143isrlink_vectored(int (*func)(void *), void *arg, int ipl, int vec)
144{ 144{
145 struct isr_vectored *isr; 145 struct isr_vectored *isr;
146 146
147 if ((ipl < 0) || (ipl >= NISRAUTOVEC)) 147 if ((ipl < 0) || (ipl >= NISRAUTOVEC))
148 panic("isrlink_vectored: bad ipl %d", ipl); 148 panic("isrlink_vectored: bad ipl %d", ipl);
149 if ((vec < ISRVECTORED) || (vec >= ISRVECTORED + NISRVECTORED)) 149 if ((vec < ISRVECTORED) || (vec >= ISRVECTORED + NISRVECTORED))
150 panic("isrlink_vectored: bad vec 0x%x", vec); 150 panic("isrlink_vectored: bad vec 0x%x", vec);
151 151
152 isr = &isr_vectored[vec - ISRVECTORED]; 152 isr = &isr_vectored[vec - ISRVECTORED];
153 153
154 if ((vectab[vec] != badtrap) || (isr->isr_func != NULL)) 154 if ((vectab[vec] != badtrap) || (isr->isr_func != NULL))
155 panic("isrlink_vectored: vec 0x%x not available", vec); 155 panic("isrlink_vectored: vec 0x%x not available", vec);
156 156
157 /* Fill in the new entry. */ 157 /* Fill in the new entry. */
158 isr->isr_func = func; 158 isr->isr_func = func;
159 isr->isr_arg = arg; 159 isr->isr_arg = arg;
160 isr->isr_ipl = ipl; 160 isr->isr_ipl = ipl;
161 161
162 /* Hook into the vector table. */ 162 /* Hook into the vector table. */
163 vectab[vec] = intrhand_vectored; 163 vectab[vec] = intrhand_vectored;
164} 164}
165 165
166/* 166/*
167 * Unhook a vectored interrupt. 167 * Unhook a vectored interrupt.
168 */ 168 */
169void 169void
170isrunlink_vectored(int vec) 170isrunlink_vectored(int vec)
171{ 171{
172 172
173 if ((vec < ISRVECTORED) || (vec >= ISRVECTORED + NISRVECTORED)) 173 if ((vec < ISRVECTORED) || (vec >= ISRVECTORED + NISRVECTORED))
174 panic("isrunlink_vectored: bad vec 0x%x", vec); 174 panic("isrunlink_vectored: bad vec 0x%x", vec);
175 175
176 if (vectab[vec] != intrhand_vectored) 176 if (vectab[vec] != intrhand_vectored)
177 panic("isrunlink_vectored: not vectored interrupt"); 177 panic("isrunlink_vectored: not vectored interrupt");
178 178
179 vectab[vec] = badtrap; 179 vectab[vec] = badtrap;
180 memset(&isr_vectored[vec - ISRVECTORED], 0, sizeof(struct isr_vectored)); 180 memset(&isr_vectored[vec - ISRVECTORED], 0, sizeof(struct isr_vectored));
181} 181}
182 182
183/* 183/*
184 * This is the dispatcher called by the low-level 184 * This is the dispatcher called by the low-level
185 * assembly language autovectored interrupt routine. 185 * assembly language autovectored interrupt routine.
186 */ 186 */
187void 187void
188isrdispatch_autovec(int evec) 188isrdispatch_autovec(int evec)
189 /* evec: format | vector offset */ 189 /* evec: format | vector offset */
190{ 190{
191 struct isr_autovec *isr; 191 struct isr_autovec *isr;
192 isr_autovec_list_t *list; 192 isr_autovec_list_t *list;
193 int handled = 0, ipl, vec; 193 int handled = 0, ipl, vec;
194 static int straycount, unexpected; 194 static int straycount, unexpected;
195 195
196 idepth++; 196 idepth++;
197 vec = (evec & 0xfff) >> 2; 197 vec = (evec & 0xfff) >> 2;
198 if ((vec < ISRAUTOVEC) || (vec >= (ISRAUTOVEC + NISRAUTOVEC))) 198 if ((vec < ISRAUTOVEC) || (vec >= (ISRAUTOVEC + NISRAUTOVEC)))
199 panic("isrdispatch_autovec: bad vec 0x%x", vec); 199 panic("isrdispatch_autovec: bad vec 0x%x", vec);
200 ipl = vec - ISRAUTOVEC; 200 ipl = vec - ISRAUTOVEC;
201 201
202 intrcnt[ipl]++; 202 intrcnt[ipl]++;
203 curcpu()->ci_data.cpu_nintr++; 203 curcpu()->ci_data.cpu_nintr++;
204 204
205 list = &isr_autovec[ipl]; 205 list = &isr_autovec[ipl];
206 if (list->lh_first == NULL) { 206 if (list->lh_first == NULL) {
207 printf("isrdispatch_autovec: ipl %d unexpected\n", ipl); 207 printf("isrdispatch_autovec: ipl %d unexpected\n", ipl);
208 if (++unexpected > 10) 208 if (++unexpected > 10)
209 panic("too many unexpected interrupts"); 209 panic("too many unexpected interrupts");
210 idepth--; 210 idepth--;
211 return; 211 return;
212 } 212 }
213 213
214 /* Give all the handlers a chance. */ 214 /* Give all the handlers a chance. */
215 for (isr = list->lh_first ; isr != NULL; isr = isr->isr_link.le_next) 215 for (isr = list->lh_first ; isr != NULL; isr = isr->isr_link.le_next)
216 handled |= (*isr->isr_func)(isr->isr_arg); 216 handled |= (*isr->isr_func)(isr->isr_arg);
217 217
218 if (handled) 218 if (handled)
219 straycount = 0; 219 straycount = 0;
220 else if (++straycount > 50) 220 else if (++straycount > 50)
221 panic("isr_dispatch_autovec: too many stray interrupts"); 221 panic("isr_dispatch_autovec: too many stray interrupts");
222 else 222 else
223 printf("isrdispatch_autovec: stray level %d interrupt\n", ipl); 223 printf("isrdispatch_autovec: stray level %d interrupt\n", ipl);
224 idepth--; 224 idepth--;
225} 225}
226 226
227/* 227/*
228 * This is the dispatcher called by the low-level 228 * This is the dispatcher called by the low-level
229 * assembly language vectored interrupt routine. 229 * assembly language vectored interrupt routine.
230 */ 230 */
231void 231void
232isrdispatch_vectored(int pc, int evec, void *frame) 232isrdispatch_vectored(int pc, int evec, void *frame)
233{ 233{
234 struct isr_vectored *isr; 234 struct isr_vectored *isr;
235 int ipl, vec; 235 int ipl, vec;
236 236
237 idepth++; 237 idepth++;
238 vec = (evec & 0xfff) >> 2; 238 vec = (evec & 0xfff) >> 2;
239 ipl = (getsr() >> 8) & 7; 239 ipl = (getsr() >> 8) & 7;
240 240
241 intrcnt[ipl]++; 241 intrcnt[ipl]++;
242 curcpu()->ci_data.cpu_nintr++; 242 curcpu()->ci_data.cpu_nintr++;
243 243
244 if ((vec < ISRVECTORED) || (vec >= (ISRVECTORED + NISRVECTORED))) 244 if ((vec < ISRVECTORED) || (vec >= (ISRVECTORED + NISRVECTORED)))
245 panic("isrdispatch_vectored: bad vec 0x%x", vec); 245 panic("isrdispatch_vectored: bad vec 0x%x", vec);
246 isr = &isr_vectored[vec - ISRVECTORED]; 246 isr = &isr_vectored[vec - ISRVECTORED];
247 247
248 if (isr->isr_func == NULL) { 248 if (isr->isr_func == NULL) {
249 printf("isrdispatch_vectored: no handler for vec 0x%x\n", vec); 249 printf("isrdispatch_vectored: no handler for vec 0x%x\n", vec);
250 vectab[vec] = badtrap; 250 vectab[vec] = badtrap;
251 idepth--; 251 idepth--;
252 return; 252 return;
253 } 253 }
254 254
255 /* 255 /*
256 * Handler gets exception frame if argument is NULL. 256 * Handler gets exception frame if argument is NULL.
257 */ 257 */
258 if ((*isr->isr_func)(isr->isr_arg ? isr->isr_arg : frame) == 0) 258 if ((*isr->isr_func)(isr->isr_arg ? isr->isr_arg : frame) == 0)
259 printf("isrdispatch_vectored: vec 0x%x not claimed\n", vec); 259 printf("isrdispatch_vectored: vec 0x%x not claimed\n", vec);
260 idepth--; 260 idepth--;
261} 261}
262 262
263bool 263bool
264cpu_intr_p(void) 264cpu_intr_p(void)
265{ 265{
266 266
267 return idepth != 0; 267 return idepth != 0;
268} 268}
269 269
270const uint16_t ipl2psl_table[NIPL] = { 270const uint16_t ipl2psl_table[NIPL] = {
271 [IPL_NONE] = PSL_S|PSL_IPL0, 271 [IPL_NONE] = PSL_S|PSL_IPL0,
272 [IPL_SOFTCLOCK] = PSL_S|PSL_IPL1, 272 [IPL_SOFTCLOCK] = PSL_S|PSL_IPL1,
273 [IPL_SOFTBIO] = PSL_S|PSL_IPL1, 273 [IPL_SOFTBIO] = PSL_S|PSL_IPL1,
274 [IPL_SOFTNET] = PSL_S|PSL_IPL1, 274 [IPL_SOFTNET] = PSL_S|PSL_IPL1,
275 [IPL_SOFTSERIAL] = PSL_S|PSL_IPL1, 275 [IPL_SOFTSERIAL] = PSL_S|PSL_IPL1,
276 [IPL_VM] = PSL_S|PSL_IPL4, 276 [IPL_VM] = PSL_S|PSL_IPL4,
277 [IPL_SCHED] = PSL_S|PSL_IPL5, 277 [IPL_SCHED] = PSL_S|PSL_IPL5,
278 [IPL_HIGH] = PSL_S|PSL_IPL7, 278 [IPL_HIGH] = PSL_S|PSL_IPL7,
279}; 279};

cvs diff -r1.31 -r1.32 src/sys/arch/mac68k/mac68k/intr.c (switch to unified diff)

--- src/sys/arch/mac68k/mac68k/intr.c 2020/07/21 06:10:26 1.31
+++ src/sys/arch/mac68k/mac68k/intr.c 2021/04/02 12:11:41 1.32
@@ -1,259 +1,259 @@ @@ -1,259 +1,259 @@
1/* $NetBSD: intr.c,v 1.31 2020/07/21 06:10:26 rin Exp $ */ 1/* $NetBSD: intr.c,v 1.32 2021/04/02 12:11:41 rin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. 4 * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Adam Glass, Gordon W. Ross, and Jason R. Thorpe. 8 * by Adam Glass, Gordon W. Ross, and Jason R. Thorpe.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Link and dispatch interrupts. 33 * Link and dispatch interrupts.
34 */ 34 */
35 35
36#include <sys/cdefs.h> 36#include <sys/cdefs.h>
37__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.31 2020/07/21 06:10:26 rin Exp $"); 37__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.32 2021/04/02 12:11:41 rin Exp $");
38 38
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/systm.h> 40#include <sys/systm.h>
41#include <sys/malloc.h> 41#include <sys/malloc.h>
42#include <sys/vmmeter.h> 42#include <sys/vmmeter.h>
43#include <sys/cpu.h> 43#include <sys/cpu.h>
44#include <sys/intr.h> 44#include <sys/intr.h>
45 45
46#include <machine/psc.h> 46#include <machine/psc.h>
47#include <machine/viareg.h> 47#include <machine/viareg.h>
48 48
49#define NISR 8 49#define NISR 8
50#define ISRLOC 0x18 50#define ISRLOC 0x18
51 51
52static int intr_noint(void *); 52static int intr_noint(void *);
53 53
54static int ((*intr_func[NISR])(void *)) = { 54static int ((*intr_func[NISR])(void *)) = {
55 intr_noint, 55 intr_noint,
56 intr_noint, 56 intr_noint,
57 intr_noint, 57 intr_noint,
58 intr_noint, 58 intr_noint,
59 intr_noint, 59 intr_noint,
60 intr_noint, 60 intr_noint,
61 intr_noint, 61 intr_noint,
62 intr_noint 62 intr_noint
63}; 63};
64static void *intr_arg[NISR] = { 64static void *intr_arg[NISR] = {
65 (void *)0, 65 (void *)0,
66 (void *)1, 66 (void *)1,
67 (void *)2, 67 (void *)2,
68 (void *)3, 68 (void *)3,
69 (void *)4, 69 (void *)4,
70 (void *)5, 70 (void *)5,
71 (void *)6, 71 (void *)6,
72 (void *)7 72 (void *)7
73}; 73};
74 74
75#ifdef DEBUG 75#ifdef DEBUG
76int intr_debug = 0; 76int intr_debug = 0;
77#endif 77#endif
78 78
79/* 79/*
80 * Some of the below are not used yet, but might be used someday on the 80 * Some of the below are not used yet, but might be used someday on the
81 * IIfx/Q700/900/950/etc. where the interrupt controller may be reprogrammed 81 * IIfx/Q700/900/950/etc. where the interrupt controller may be reprogrammed
82 * to interrupt on different levels as listed in locore.s 82 * to interrupt on different levels as listed in locore.s
83 */ 83 */
84uint16_t ipl2psl_table[NIPL]; 84uint16_t ipl2psl_table[NIPL];
85int idepth; 85int idepth;
86volatile int ssir; 86volatile int ssir;
87 87
88extern int intrcnt[]; /* from locore.s */ 88extern u_int intrcnt[]; /* from locore.s */
89 89
90void intr_computeipl(void); 90void intr_computeipl(void);
91 91
92#define MAX_INAME_LENGTH 53 92#define MAX_INAME_LENGTH 53
93#define STD_INAMES \ 93#define STD_INAMES \
94 "spur\0via1\0via2\0unused1\0scc\0unused2\0unused3\0nmi\0clock\0" 94 "spur\0via1\0via2\0unused1\0scc\0unused2\0unused3\0nmi\0clock\0"
95#define AUX_INAMES \ 95#define AUX_INAMES \
96 "spur\0soft\0via2\0ethernet\0scc\0sound\0via1\0nmi\0clock\0 " 96 "spur\0soft\0via2\0ethernet\0scc\0sound\0via1\0nmi\0clock\0 "
97#define AV_INAMES \ 97#define AV_INAMES \
98 "spur\0via1\0via2\0ethernet\0scc\0dsp\0unused1\0nmi\0clock\0 " 98 "spur\0via1\0via2\0ethernet\0scc\0dsp\0unused1\0nmi\0clock\0 "
99 99
100void 100void
101intr_init(void) 101intr_init(void)
102{ 102{
103 extern char intrnames[MAX_INAME_LENGTH]; 103 extern char intrnames[MAX_INAME_LENGTH];
104 extern char eintrnames[] __diagused; 104 extern char eintrnames[] __diagused;
105 const char *inames; 105 const char *inames;
106 106
107 ipl2psl_table[IPL_NONE] = 0; 107 ipl2psl_table[IPL_NONE] = 0;
108 ipl2psl_table[IPL_SOFTCLOCK] = PSL_S|PSL_IPL1; 108 ipl2psl_table[IPL_SOFTCLOCK] = PSL_S|PSL_IPL1;
109 ipl2psl_table[IPL_SOFTNET] = PSL_S|PSL_IPL1; 109 ipl2psl_table[IPL_SOFTNET] = PSL_S|PSL_IPL1;
110 ipl2psl_table[IPL_SOFTSERIAL] = PSL_S|PSL_IPL1; 110 ipl2psl_table[IPL_SOFTSERIAL] = PSL_S|PSL_IPL1;
111 ipl2psl_table[IPL_SOFTBIO] = PSL_S|PSL_IPL1; 111 ipl2psl_table[IPL_SOFTBIO] = PSL_S|PSL_IPL1;
112 ipl2psl_table[IPL_HIGH] = PSL_S|PSL_IPL7; 112 ipl2psl_table[IPL_HIGH] = PSL_S|PSL_IPL7;
113 113
114 if (mac68k_machine.aux_interrupts) { 114 if (mac68k_machine.aux_interrupts) {
115 inames = AUX_INAMES; 115 inames = AUX_INAMES;
116 116
117 /* Standard spl(9) interrupt priorities */ 117 /* Standard spl(9) interrupt priorities */
118 ipl2psl_table[IPL_VM] = (PSL_S | PSL_IPL6); 118 ipl2psl_table[IPL_VM] = (PSL_S | PSL_IPL6);
119 ipl2psl_table[IPL_SCHED] = (PSL_S | PSL_IPL6); 119 ipl2psl_table[IPL_SCHED] = (PSL_S | PSL_IPL6);
120 } else { 120 } else {
121 inames = STD_INAMES; 121 inames = STD_INAMES;
122 122
123 /* Standard spl(9) interrupt priorities */ 123 /* Standard spl(9) interrupt priorities */
124 ipl2psl_table[IPL_VM] = (PSL_S | PSL_IPL2); 124 ipl2psl_table[IPL_VM] = (PSL_S | PSL_IPL2);
125 ipl2psl_table[IPL_SCHED] = (PSL_S | PSL_IPL3); 125 ipl2psl_table[IPL_SCHED] = (PSL_S | PSL_IPL3);
126 126
127 if (current_mac_model->class == MACH_CLASSAV) { 127 if (current_mac_model->class == MACH_CLASSAV) {
128 inames = AV_INAMES; 128 inames = AV_INAMES;
129 ipl2psl_table[IPL_VM] = (PSL_S | PSL_IPL4); 129 ipl2psl_table[IPL_VM] = (PSL_S | PSL_IPL4);
130 ipl2psl_table[IPL_SCHED] = (PSL_S | PSL_IPL4); 130 ipl2psl_table[IPL_SCHED] = (PSL_S | PSL_IPL4);
131 } 131 }
132 } 132 }
133 133
134 KASSERT(MAX_INAME_LENGTH <= 134 KASSERT(MAX_INAME_LENGTH <=
135 ((uintptr_t)eintrnames - (uintptr_t)intrnames)); 135 ((uintptr_t)eintrnames - (uintptr_t)intrnames));
136 memcpy(intrnames, inames, MAX_INAME_LENGTH); 136 memcpy(intrnames, inames, MAX_INAME_LENGTH);
137 137
138 intr_computeipl(); 138 intr_computeipl();
139 139
140 /* Initialize the VIAs */ 140 /* Initialize the VIAs */
141 via_init(); 141 via_init();
142 142
143 /* Initialize the PSC (if present) */ 143 /* Initialize the PSC (if present) */
144 psc_init(); 144 psc_init();
145} 145}
146 146
147 147
148/* 148/*
149 * Compute the interrupt levels for the spl*() 149 * Compute the interrupt levels for the spl*()
150 * calls. This doesn't have to be fast. 150 * calls. This doesn't have to be fast.
151 */ 151 */
152void 152void
153intr_computeipl(void) 153intr_computeipl(void)
154{ 154{
155 /* 155 /*
156 * Enforce the following relationship, as defined in spl(9): 156 * Enforce the following relationship, as defined in spl(9):
157 * `bio <= net <= tty <= vm <= statclock <= clock <= sched <= serial' 157 * `bio <= net <= tty <= vm <= statclock <= clock <= sched <= serial'
158 */ 158 */
159 if (ipl2psl_table[IPL_VM] > ipl2psl_table[IPL_SCHED]) 159 if (ipl2psl_table[IPL_VM] > ipl2psl_table[IPL_SCHED])
160 ipl2psl_table[IPL_SCHED] = ipl2psl_table[IPL_VM]; 160 ipl2psl_table[IPL_SCHED] = ipl2psl_table[IPL_VM];
161 161
162 if (ipl2psl_table[IPL_SCHED] > ipl2psl_table[IPL_HIGH]) 162 if (ipl2psl_table[IPL_SCHED] > ipl2psl_table[IPL_HIGH])
163 ipl2psl_table[IPL_HIGH] = ipl2psl_table[IPL_SCHED]; 163 ipl2psl_table[IPL_HIGH] = ipl2psl_table[IPL_SCHED];
164} 164}
165 165
166/* 166/*
167 * Establish an autovectored interrupt handler. 167 * Establish an autovectored interrupt handler.
168 * Called by driver attach functions. 168 * Called by driver attach functions.
169 * 169 *
170 * XXX Warning! DO NOT use Macintosh ROM traps from an interrupt handler 170 * XXX Warning! DO NOT use Macintosh ROM traps from an interrupt handler
171 * established by this routine, either directly or indirectly, without 171 * established by this routine, either directly or indirectly, without
172 * properly saving and restoring all registers. If not, chaos _will_ 172 * properly saving and restoring all registers. If not, chaos _will_
173 * ensue! (sar 19980806) 173 * ensue! (sar 19980806)
174 */ 174 */
175void 175void
176intr_establish(int (*func)(void *), void *arg, int ipl) 176intr_establish(int (*func)(void *), void *arg, int ipl)
177{ 177{
178 if ((ipl < 0) || (ipl >= NISR)) 178 if ((ipl < 0) || (ipl >= NISR))
179 panic("intr_establish: bad ipl %d", ipl); 179 panic("intr_establish: bad ipl %d", ipl);
180 180
181#ifdef DIAGNOSTIC 181#ifdef DIAGNOSTIC
182 if (intr_func[ipl] != intr_noint) 182 if (intr_func[ipl] != intr_noint)
183 printf("intr_establish: attempt to share ipl %d\n", ipl); 183 printf("intr_establish: attempt to share ipl %d\n", ipl);
184#endif 184#endif
185 185
186 intr_func[ipl] = func; 186 intr_func[ipl] = func;
187 intr_arg[ipl] = arg; 187 intr_arg[ipl] = arg;
188} 188}
189 189
190/* 190/*
191 * Disestablish an interrupt handler. 191 * Disestablish an interrupt handler.
192 */ 192 */
193void 193void
194intr_disestablish(int ipl) 194intr_disestablish(int ipl)
195{ 195{
196 if ((ipl < 0) || (ipl >= NISR)) 196 if ((ipl < 0) || (ipl >= NISR))
197 panic("intr_disestablish: bad ipl %d", ipl); 197 panic("intr_disestablish: bad ipl %d", ipl);
198 198
199 intr_func[ipl] = intr_noint; 199 intr_func[ipl] = intr_noint;
200 intr_arg[ipl] = (void *)ipl; 200 intr_arg[ipl] = (void *)ipl;
201} 201}
202 202
203/* 203/*
204 * This is the dispatcher called by the low-level 204 * This is the dispatcher called by the low-level
205 * assembly language interrupt routine. 205 * assembly language interrupt routine.
206 * 206 *
207 * XXX Note: see the warning in intr_establish() 207 * XXX Note: see the warning in intr_establish()
208 */ 208 */
209#if __GNUC_PREREQ__(8, 0) 209#if __GNUC_PREREQ__(8, 0)
210/* 210/*
211 * XXX rtclock_intr() requires this for unwinding stack frame. 211 * XXX rtclock_intr() requires this for unwinding stack frame.
212 */ 212 */
213#pragma GCC push_options 213#pragma GCC push_options
214#pragma GCC optimize "-fno-omit-frame-pointer" 214#pragma GCC optimize "-fno-omit-frame-pointer"
215#endif 215#endif
216void 216void
217intr_dispatch(int evec) /* format | vector offset */ 217intr_dispatch(int evec) /* format | vector offset */
218{ 218{
219 int ipl, vec; 219 int ipl, vec;
220 220
221 idepth++; 221 idepth++;
222 vec = (evec & 0xfff) >> 2; 222 vec = (evec & 0xfff) >> 2;
223#ifdef DIAGNOSTIC 223#ifdef DIAGNOSTIC
224 if ((vec < ISRLOC) || (vec >= (ISRLOC + NISR))) 224 if ((vec < ISRLOC) || (vec >= (ISRLOC + NISR)))
225 panic("intr_dispatch: bad vec 0x%x", vec); 225 panic("intr_dispatch: bad vec 0x%x", vec);
226#endif 226#endif
227 ipl = vec - ISRLOC; 227 ipl = vec - ISRLOC;
228 228
229 intrcnt[ipl]++; 229 intrcnt[ipl]++;
230 curcpu()->ci_data.cpu_nintr++; 230 curcpu()->ci_data.cpu_nintr++;
231 231
232 (void)(*intr_func[ipl])(intr_arg[ipl]); 232 (void)(*intr_func[ipl])(intr_arg[ipl]);
233 idepth--; 233 idepth--;
234} 234}
235#if __GNUC_PREREQ__(8, 0) 235#if __GNUC_PREREQ__(8, 0)
236#pragma GCC pop_options 236#pragma GCC pop_options
237#endif 237#endif
238 238
239/* 239/*
240 * Default interrupt handler: do nothing. 240 * Default interrupt handler: do nothing.
241 */ 241 */
242static int 242static int
243intr_noint(void *arg) 243intr_noint(void *arg)
244{ 244{
245#ifdef DEBUG 245#ifdef DEBUG
246 idepth++; 246 idepth++;
247 if (intr_debug) 247 if (intr_debug)
248 printf("intr_noint: ipl %d\n", (int)arg); 248 printf("intr_noint: ipl %d\n", (int)arg);
249 idepth--; 249 idepth--;
250#endif 250#endif
251 return 0; 251 return 0;
252} 252}
253 253
254bool 254bool
255cpu_intr_p(void) 255cpu_intr_p(void)
256{ 256{
257 257
258 return idepth != 0; 258 return idepth != 0;
259} 259}

cvs diff -r1.35 -r1.36 src/sys/arch/mvme68k/mvme68k/isr.c (switch to unified diff)

--- src/sys/arch/mvme68k/mvme68k/isr.c 2020/11/21 17:59:13 1.35
+++ src/sys/arch/mvme68k/mvme68k/isr.c 2021/04/02 12:11:41 1.36
@@ -1,342 +1,342 @@ @@ -1,342 +1,342 @@
1/* $NetBSD: isr.c,v 1.35 2020/11/21 17:59:13 thorpej Exp $ */ 1/* $NetBSD: isr.c,v 1.36 2021/04/02 12:11:41 rin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1996 The NetBSD Foundation, Inc. 4 * Copyright (c) 1996 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Adam Glass, Gordon W. Ross, and Jason R. Thorpe. 8 * by Adam Glass, Gordon W. Ross, and Jason R. Thorpe.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Link and dispatch interrupts. 33 * Link and dispatch interrupts.
34 */ 34 */
35 35
36#include <sys/cdefs.h> 36#include <sys/cdefs.h>
37__KERNEL_RCSID(0, "$NetBSD: isr.c,v 1.35 2020/11/21 17:59:13 thorpej Exp $"); 37__KERNEL_RCSID(0, "$NetBSD: isr.c,v 1.36 2021/04/02 12:11:41 rin Exp $");
38 38
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/systm.h> 40#include <sys/systm.h>
41#include <sys/kmem.h> 41#include <sys/kmem.h>
42#include <sys/vmmeter.h> 42#include <sys/vmmeter.h>
43#include <sys/device.h> 43#include <sys/device.h>
44#include <sys/cpu.h> 44#include <sys/cpu.h>
45 45
46#include <uvm/uvm_extern.h> 46#include <uvm/uvm_extern.h>
47 47
48#include <mvme68k/mvme68k/isr.h> 48#include <mvme68k/mvme68k/isr.h>
49 49
50volatile unsigned int interrupt_depth; 50volatile unsigned int interrupt_depth;
51isr_autovec_list_t isr_autovec[NISRAUTOVEC]; 51isr_autovec_list_t isr_autovec[NISRAUTOVEC];
52struct isr_vectored isr_vectored[NISRVECTORED]; 52struct isr_vectored isr_vectored[NISRVECTORED];
53static const char irqgroupname[] = "hard irqs"; 53static const char irqgroupname[] = "hard irqs";
54struct evcnt mvme68k_irq_evcnt[] = { 54struct evcnt mvme68k_irq_evcnt[] = {
55 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "spur"), 55 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "spur"),
56 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev1"), 56 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev1"),
57 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev2"), 57 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev2"),
58 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev3"), 58 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev3"),
59 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev4"), 59 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev4"),
60 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev5"), 60 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev5"),
61 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev6"), 61 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev6"),
62 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "nmi") 62 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "nmi")
63}; 63};
64static int idepth; 64static int idepth;
65 65
66extern int intrcnt[]; /* from locore.s. XXXSCW: will go away soon */ 66extern u_int intrcnt[]; /* from locore.s. XXXSCW: will go away soon */
67extern void (*vectab[])(void); 67extern void (*vectab[])(void);
68extern void badtrap(void); 68extern void badtrap(void);
69extern void intrhand_vectored(void); 69extern void intrhand_vectored(void);
70 70
71static int spurintr(void *); 71static int spurintr(void *);
72 72
73 73
74void 74void
75isrinit(void) 75isrinit(void)
76{ 76{
77 int i; 77 int i;
78 78
79 /* Initialize the autovector lists. */ 79 /* Initialize the autovector lists. */
80 for (i = 0; i < NISRAUTOVEC; ++i) 80 for (i = 0; i < NISRAUTOVEC; ++i)
81 LIST_INIT(&isr_autovec[i]); 81 LIST_INIT(&isr_autovec[i]);
82 82
83 /* Initialise the interrupt event counts */ 83 /* Initialise the interrupt event counts */
84 for (i = 0; i < (sizeof(mvme68k_irq_evcnt) / sizeof(struct evcnt)); i++) 84 for (i = 0; i < (sizeof(mvme68k_irq_evcnt) / sizeof(struct evcnt)); i++)
85 evcnt_attach_static(&mvme68k_irq_evcnt[i]); 85 evcnt_attach_static(&mvme68k_irq_evcnt[i]);
86 86
87 /* Arrange to trap Spurious and NMI auto-vectored Interrupts */ 87 /* Arrange to trap Spurious and NMI auto-vectored Interrupts */
88 isrlink_autovec(spurintr, NULL, 0, 0, NULL); 88 isrlink_autovec(spurintr, NULL, 0, 0, NULL);
89 isrlink_autovec(nmihand, NULL, 7, 0, NULL); 89 isrlink_autovec(nmihand, NULL, 7, 0, NULL);
90} 90}
91 91
92/* 92/*
93 * Establish an autovectored interrupt handler. 93 * Establish an autovectored interrupt handler.
94 * Called by driver attach functions. 94 * Called by driver attach functions.
95 */ 95 */
96void 96void
97isrlink_autovec(int (*func)(void *), void *arg, int ipl, int priority, 97isrlink_autovec(int (*func)(void *), void *arg, int ipl, int priority,
98 struct evcnt *evcnt) 98 struct evcnt *evcnt)
99{ 99{
100 struct isr_autovec *newisr, *curisr; 100 struct isr_autovec *newisr, *curisr;
101 isr_autovec_list_t *list; 101 isr_autovec_list_t *list;
102 102
103#ifdef DIAGNOSTIC 103#ifdef DIAGNOSTIC
104 if ((ipl < 0) || (ipl >= NISRAUTOVEC)) 104 if ((ipl < 0) || (ipl >= NISRAUTOVEC))
105 panic("%s: bad ipl %d", __func__, ipl); 105 panic("%s: bad ipl %d", __func__, ipl);
106#endif 106#endif
107 107
108 newisr = kmem_alloc(sizeof(*newisr), KM_SLEEP); 108 newisr = kmem_alloc(sizeof(*newisr), KM_SLEEP);
109 newisr->isr_func = func; 109 newisr->isr_func = func;
110 newisr->isr_arg = arg; 110 newisr->isr_arg = arg;
111 newisr->isr_ipl = ipl; 111 newisr->isr_ipl = ipl;
112 newisr->isr_priority = priority; 112 newisr->isr_priority = priority;
113 newisr->isr_evcnt = evcnt; 113 newisr->isr_evcnt = evcnt;
114 114
115 /* 115 /*
116 * Some devices are particularly sensitive to interrupt 116 * Some devices are particularly sensitive to interrupt
117 * handling latency. The SCC, for example, can lose many 117 * handling latency. The SCC, for example, can lose many
118 * characters if its interrupt isn't handled with reasonable 118 * characters if its interrupt isn't handled with reasonable
119 * speed. 119 * speed.
120 * 120 *
121 * To work around this problem, each device can give itself a 121 * To work around this problem, each device can give itself a
122 * "priority". An unbuffered SCC would give itself a higher 122 * "priority". An unbuffered SCC would give itself a higher
123 * priority than a SCSI device, for example. 123 * priority than a SCSI device, for example.
124 * 124 *
125 * This solution was originally developed for the hp300, which 125 * This solution was originally developed for the hp300, which
126 * has a flat spl scheme (by necessity). Thankfully, the 126 * has a flat spl scheme (by necessity). Thankfully, the
127 * MVME systems don't have this problem, though this may serve 127 * MVME systems don't have this problem, though this may serve
128 * a useful purpose in any case. 128 * a useful purpose in any case.
129 */ 129 */
130 130
131 /* 131 /*
132 * Get the appropriate ISR list. If the list is empty, no 132 * Get the appropriate ISR list. If the list is empty, no
133 * additional work is necessary; we simply insert ourselves 133 * additional work is necessary; we simply insert ourselves
134 * at the head of the list. 134 * at the head of the list.
135 */ 135 */
136 list = &isr_autovec[ipl]; 136 list = &isr_autovec[ipl];
137 if (list->lh_first == NULL) { 137 if (list->lh_first == NULL) {
138 LIST_INSERT_HEAD(list, newisr, isr_link); 138 LIST_INSERT_HEAD(list, newisr, isr_link);
139 return; 139 return;
140 } 140 }
141 141
142 /* 142 /*
143 * A little extra work is required. We traverse the list 143 * A little extra work is required. We traverse the list
144 * and place ourselves after any ISRs with our current (or 144 * and place ourselves after any ISRs with our current (or
145 * higher) priority. 145 * higher) priority.
146 */ 146 */
147 for (curisr = list->lh_first; curisr->isr_link.le_next != NULL; 147 for (curisr = list->lh_first; curisr->isr_link.le_next != NULL;
148 curisr = curisr->isr_link.le_next) { 148 curisr = curisr->isr_link.le_next) {
149 if (newisr->isr_priority > curisr->isr_priority) { 149 if (newisr->isr_priority > curisr->isr_priority) {
150 LIST_INSERT_BEFORE(curisr, newisr, isr_link); 150 LIST_INSERT_BEFORE(curisr, newisr, isr_link);
151 return; 151 return;
152 } 152 }
153 } 153 }
154 154
155 /* 155 /*
156 * We're the least important entry, it seems. We just go 156 * We're the least important entry, it seems. We just go
157 * on the end. 157 * on the end.
158 */ 158 */
159 LIST_INSERT_AFTER(curisr, newisr, isr_link); 159 LIST_INSERT_AFTER(curisr, newisr, isr_link);
160} 160}
161 161
162/* 162/*
163 * Establish a vectored interrupt handler. 163 * Establish a vectored interrupt handler.
164 * Called by bus interrupt establish functions. 164 * Called by bus interrupt establish functions.
165 */ 165 */
166void 166void
167isrlink_vectored(int (*func)(void *), void *arg, int ipl, int vec, 167isrlink_vectored(int (*func)(void *), void *arg, int ipl, int vec,
168 struct evcnt *evcnt) 168 struct evcnt *evcnt)
169{ 169{
170 struct isr_vectored *isr; 170 struct isr_vectored *isr;
171 171
172#ifdef DIAGNOSTIC 172#ifdef DIAGNOSTIC
173 if ((ipl < 0) || (ipl >= NISRAUTOVEC)) 173 if ((ipl < 0) || (ipl >= NISRAUTOVEC))
174 panic("%s: bad ipl %d", __func__, ipl); 174 panic("%s: bad ipl %d", __func__, ipl);
175 if ((vec < ISRVECTORED) || (vec >= ISRVECTORED + NISRVECTORED)) 175 if ((vec < ISRVECTORED) || (vec >= ISRVECTORED + NISRVECTORED))
176 panic("%s: bad vec 0x%x", __func__, vec); 176 panic("%s: bad vec 0x%x", __func__, vec);
177#endif 177#endif
178 178
179 isr = &isr_vectored[vec - ISRVECTORED]; 179 isr = &isr_vectored[vec - ISRVECTORED];
180 180
181#ifdef DIAGNOSTIC 181#ifdef DIAGNOSTIC
182 if ((vectab[vec] != badtrap) || (isr->isr_func != NULL)) 182 if ((vectab[vec] != badtrap) || (isr->isr_func != NULL))
183 panic("%s: vec 0x%x not available", __func__, vec); 183 panic("%s: vec 0x%x not available", __func__, vec);
184#endif 184#endif
185 185
186 /* Fill in the new entry. */ 186 /* Fill in the new entry. */
187 isr->isr_func = func; 187 isr->isr_func = func;
188 isr->isr_arg = arg; 188 isr->isr_arg = arg;
189 isr->isr_ipl = ipl; 189 isr->isr_ipl = ipl;
190 isr->isr_evcnt = evcnt; 190 isr->isr_evcnt = evcnt;
191 191
192 /* Hook into the vector table. */ 192 /* Hook into the vector table. */
193 vectab[vec] = intrhand_vectored; 193 vectab[vec] = intrhand_vectored;
194} 194}
195 195
196/* 196/*
197 * Return a pointer to the evcnt structure for 197 * Return a pointer to the evcnt structure for
198 * the specified ipl. 198 * the specified ipl.
199 */ 199 */
200struct evcnt * 200struct evcnt *
201isrlink_evcnt(int ipl) 201isrlink_evcnt(int ipl)
202{ 202{
203 203
204#ifdef DIAGNOSTIC 204#ifdef DIAGNOSTIC
205 if (ipl < 0 || 205 if (ipl < 0 ||
206 ipl >= (sizeof(mvme68k_irq_evcnt) / sizeof(struct evcnt))) 206 ipl >= (sizeof(mvme68k_irq_evcnt) / sizeof(struct evcnt)))
207 panic("%s: bad ipl %d", __func__, ipl); 207 panic("%s: bad ipl %d", __func__, ipl);
208#endif 208#endif
209 209
210 return &mvme68k_irq_evcnt[ipl]; 210 return &mvme68k_irq_evcnt[ipl];
211} 211}
212 212
213/* 213/*
214 * Unhook a vectored interrupt. 214 * Unhook a vectored interrupt.
215 */ 215 */
216void 216void
217isrunlink_vectored(int vec) 217isrunlink_vectored(int vec)
218{ 218{
219 219
220#ifdef DIAGNOSTIC 220#ifdef DIAGNOSTIC
221 if ((vec < ISRVECTORED) || (vec >= ISRVECTORED + NISRVECTORED)) 221 if ((vec < ISRVECTORED) || (vec >= ISRVECTORED + NISRVECTORED))
222 panic("%s: bad vec 0x%x", __func__, vec); 222 panic("%s: bad vec 0x%x", __func__, vec);
223 223
224 if (vectab[vec] != intrhand_vectored) 224 if (vectab[vec] != intrhand_vectored)
225 panic("%s: not vectored interrupt", __func__); 225 panic("%s: not vectored interrupt", __func__);
226#endif 226#endif
227 227
228 vectab[vec] = badtrap; 228 vectab[vec] = badtrap;
229 memset(&isr_vectored[vec - ISRVECTORED], 0, 229 memset(&isr_vectored[vec - ISRVECTORED], 0,
230 sizeof(struct isr_vectored)); 230 sizeof(struct isr_vectored));
231} 231}
232 232
233/* 233/*
234 * This is the dispatcher called by the low-level 234 * This is the dispatcher called by the low-level
235 * assembly language autovectored interrupt routine. 235 * assembly language autovectored interrupt routine.
236 */ 236 */
237void 237void
238isrdispatch_autovec(struct clockframe *frame) 238isrdispatch_autovec(struct clockframe *frame)
239{ 239{
240 struct isr_autovec *isr; 240 struct isr_autovec *isr;
241 isr_autovec_list_t *list; 241 isr_autovec_list_t *list;
242 int handled, ipl; 242 int handled, ipl;
243 void *arg; 243 void *arg;
244 static int straycount, unexpected; 244 static int straycount, unexpected;
245 245
246 idepth++; 246 idepth++;
247 ipl = (frame->vec >> 2) - ISRAUTOVEC; 247 ipl = (frame->vec >> 2) - ISRAUTOVEC;
248 248
249#ifdef DIAGNOSTIC 249#ifdef DIAGNOSTIC
250 if ((ipl < 0) || (ipl >= NISRAUTOVEC)) 250 if ((ipl < 0) || (ipl >= NISRAUTOVEC))
251 panic("%s: bad vec 0x%x", __func__, frame->vec); 251 panic("%s: bad vec 0x%x", __func__, frame->vec);
252#endif 252#endif
253 253
254 intrcnt[ipl]++; /* XXXSCW: Will go away soon */ 254 intrcnt[ipl]++; /* XXXSCW: Will go away soon */
255 mvme68k_irq_evcnt[ipl].ev_count++; 255 mvme68k_irq_evcnt[ipl].ev_count++;
256 curcpu()->ci_data.cpu_nintr++; 256 curcpu()->ci_data.cpu_nintr++;
257 257
258 list = &isr_autovec[ipl]; 258 list = &isr_autovec[ipl];
259 if (list->lh_first == NULL) { 259 if (list->lh_first == NULL) {
260 printf("%s: ipl %d unexpected\n", __func__, ipl); 260 printf("%s: ipl %d unexpected\n", __func__, ipl);
261 if (++unexpected > 10) 261 if (++unexpected > 10)
262 panic("too many unexpected interrupts"); 262 panic("too many unexpected interrupts");
263 idepth--; 263 idepth--;
264 return; 264 return;
265 } 265 }
266 266
267 /* Give all the handlers a chance. */ 267 /* Give all the handlers a chance. */
268 handled = 0; 268 handled = 0;
269 for (isr = list->lh_first ; isr != NULL; isr = isr->isr_link.le_next) { 269 for (isr = list->lh_first ; isr != NULL; isr = isr->isr_link.le_next) {
270 arg = isr->isr_arg ? isr->isr_arg : frame; 270 arg = isr->isr_arg ? isr->isr_arg : frame;
271 if ((*isr->isr_func)(arg) != 0) { 271 if ((*isr->isr_func)(arg) != 0) {
272 if (isr->isr_evcnt) 272 if (isr->isr_evcnt)
273 isr->isr_evcnt->ev_count++; 273 isr->isr_evcnt->ev_count++;
274 handled++; 274 handled++;
275 } 275 }
276 } 276 }
277 277
278 if (handled) 278 if (handled)
279 straycount = 0; 279 straycount = 0;
280 else if (++straycount > 50) 280 else if (++straycount > 50)
281 panic("%s: too many stray interrupts", __func__); 281 panic("%s: too many stray interrupts", __func__);
282 else 282 else
283 printf("%s: stray level %d interrupt\n", __func__, ipl); 283 printf("%s: stray level %d interrupt\n", __func__, ipl);
284 284
285 idepth--; 285 idepth--;
286} 286}
287 287
288/* 288/*
289 * This is the dispatcher called by the low-level 289 * This is the dispatcher called by the low-level
290 * assembly language vectored interrupt routine. 290 * assembly language vectored interrupt routine.
291 */ 291 */
292void 292void
293isrdispatch_vectored(int ipl, struct clockframe *frame) 293isrdispatch_vectored(int ipl, struct clockframe *frame)
294{ 294{
295 struct isr_vectored *isr; 295 struct isr_vectored *isr;
296 int vec; 296 int vec;
297 297
298 idepth++; 298 idepth++;
299 vec = (frame->vec >> 2) - ISRVECTORED; 299 vec = (frame->vec >> 2) - ISRVECTORED;
300 300
301#ifdef DIAGNOSTIC 301#ifdef DIAGNOSTIC
302 if ((vec < 0) || (vec >= NISRVECTORED)) 302 if ((vec < 0) || (vec >= NISRVECTORED))
303 panic("%s: bad vec 0x%x", __func__, frame->vec); 303 panic("%s: bad vec 0x%x", __func__, frame->vec);
304#endif 304#endif
305 305
306 isr = &isr_vectored[vec]; 306 isr = &isr_vectored[vec];
307 307
308 intrcnt[ipl]++; /* XXXSCW: Will go away soon */ 308 intrcnt[ipl]++; /* XXXSCW: Will go away soon */
309 mvme68k_irq_evcnt[ipl].ev_count++; 309 mvme68k_irq_evcnt[ipl].ev_count++;
310 curcpu()->ci_data.cpu_nintr++; 310 curcpu()->ci_data.cpu_nintr++;
311 311
312 if (isr->isr_func == NULL) { 312 if (isr->isr_func == NULL) {
313 printf("%s: no handler for vec 0x%x\n", __func__, frame->vec); 313 printf("%s: no handler for vec 0x%x\n", __func__, frame->vec);
314 vectab[vec + ISRVECTORED] = badtrap; 314 vectab[vec + ISRVECTORED] = badtrap;
315 idepth--; 315 idepth--;
316 return; 316 return;
317 } 317 }
318 318
319 /* 319 /*
320 * Handler gets exception frame if argument is NULL. 320 * Handler gets exception frame if argument is NULL.
321 */ 321 */
322 if ((*isr->isr_func)(isr->isr_arg ? isr->isr_arg : frame) == 0) 322 if ((*isr->isr_func)(isr->isr_arg ? isr->isr_arg : frame) == 0)
323 printf("%s: vec 0x%x not claimed\n", __func__, frame->vec); 323 printf("%s: vec 0x%x not claimed\n", __func__, frame->vec);
324 else if (isr->isr_evcnt) 324 else if (isr->isr_evcnt)
325 isr->isr_evcnt->ev_count++; 325 isr->isr_evcnt->ev_count++;
326 idepth--; 326 idepth--;
327} 327}
328 328
329bool 329bool
330cpu_intr_p(void) 330cpu_intr_p(void)
331{ 331{
332 332
333 return idepth != 0; 333 return idepth != 0;
334} 334}
335 335
336/* ARGSUSED */ 336/* ARGSUSED */
337static int 337static int
338spurintr(void *arg) 338spurintr(void *arg)
339{ 339{
340 340
341 return 1; 341 return 1;
342} 342}

cvs diff -r1.31 -r1.32 src/sys/arch/next68k/next68k/isr.c (switch to unified diff)

--- src/sys/arch/next68k/next68k/isr.c 2020/11/21 17:49:20 1.31
+++ src/sys/arch/next68k/next68k/isr.c 2021/04/02 12:11:41 1.32
@@ -1,407 +1,407 @@ @@ -1,407 +1,407 @@
1/* $NetBSD: isr.c,v 1.31 2020/11/21 17:49:20 thorpej Exp $ */ 1/* $NetBSD: isr.c,v 1.32 2021/04/02 12:11:41 rin Exp $ */
2 2
3/* 3/*
4 * This file was taken from mvme68k/mvme68k/isr.c 4 * This file was taken from mvme68k/mvme68k/isr.c
5 * should probably be re-synced when needed. 5 * should probably be re-synced when needed.
6 * Darrin B. Jewell <jewell@mit.edu> Tue Nov 10 05:07:16 1998 6 * Darrin B. Jewell <jewell@mit.edu> Tue Nov 10 05:07:16 1998
7 * original cvs id: NetBSD: isr.c,v 1.12 1998/07/05 06:49:07 jonathan Exp 7 * original cvs id: NetBSD: isr.c,v 1.12 1998/07/05 06:49:07 jonathan Exp
8 */ 8 */
9 9
10/*- 10/*-
11 * Copyright (c) 1996 The NetBSD Foundation, Inc. 11 * Copyright (c) 1996 The NetBSD Foundation, Inc.
12 * All rights reserved. 12 * All rights reserved.
13 * 13 *
14 * This code is derived from software contributed to The NetBSD Foundation 14 * This code is derived from software contributed to The NetBSD Foundation
15 * by Adam Glass, Gordon W. Ross, and Jason R. Thorpe. 15 * by Adam Glass, Gordon W. Ross, and Jason R. Thorpe.
16 * 16 *
17 * Redistribution and use in source and binary forms, with or without 17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions 18 * modification, are permitted provided that the following conditions
19 * are met: 19 * are met:
20 * 1. Redistributions of source code must retain the above copyright 20 * 1. Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer. 21 * notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright 22 * 2. Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the 23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution. 24 * documentation and/or other materials provided with the distribution.
25 * 25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE. 36 * POSSIBILITY OF SUCH DAMAGE.
37 */ 37 */
38 38
39/* 39/*
40 * Link and dispatch interrupts. 40 * Link and dispatch interrupts.
41 */ 41 */
42 42
43#include <sys/cdefs.h> 43#include <sys/cdefs.h>
44__KERNEL_RCSID(0, "$NetBSD: isr.c,v 1.31 2020/11/21 17:49:20 thorpej Exp $"); 44__KERNEL_RCSID(0, "$NetBSD: isr.c,v 1.32 2021/04/02 12:11:41 rin Exp $");
45 45
46#include <sys/param.h> 46#include <sys/param.h>
47#include <sys/systm.h> 47#include <sys/systm.h>
48#include <sys/kmem.h> 48#include <sys/kmem.h>
49#include <sys/vmmeter.h> 49#include <sys/vmmeter.h>
50#include <sys/device.h> 50#include <sys/device.h>
51#include <sys/bus.h> 51#include <sys/bus.h>
52#include <sys/cpu.h> 52#include <sys/cpu.h>
53 53
54#include <uvm/uvm_extern.h> 54#include <uvm/uvm_extern.h>
55 55
56#include <next68k/next68k/isr.h> 56#include <next68k/next68k/isr.h>
57 57
58#include <next68k/dev/intiovar.h> 58#include <next68k/dev/intiovar.h>
59 59
60volatile unsigned int interrupt_depth; 60volatile unsigned int interrupt_depth;
61isr_autovec_list_t isr_autovec[NISRAUTOVEC]; 61isr_autovec_list_t isr_autovec[NISRAUTOVEC];
62struct isr_vectored isr_vectored[NISRVECTORED]; 62struct isr_vectored isr_vectored[NISRVECTORED];
63static const char irqgroupname[] = "hard irqs"; 63static const char irqgroupname[] = "hard irqs";
64struct evcnt next68k_irq_evcnt[] = { 64struct evcnt next68k_irq_evcnt[] = {
65 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "spur"), 65 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "spur"),
66 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev1"), 66 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev1"),
67 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev2"), 67 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev2"),
68 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev3"), 68 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev3"),
69 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev4"), 69 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev4"),
70 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev5"), 70 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev5"),
71 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev6"), 71 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "lev6"),
72 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "nmi") 72 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, irqgroupname, "nmi")
73}; 73};
74 74
75int idepth; 75int idepth;
76int ssir; 76int ssir;
77extern int intrcnt[]; /* from locore.s. XXXSCW: will go away soon */ 77extern u_int intrcnt[]; /* from locore.s. XXXSCW: will go away soon */
78extern void (*vectab[])(void); 78extern void (*vectab[])(void);
79extern void badtrap(void); 79extern void badtrap(void);
80extern void intrhand_vectored(void); 80extern void intrhand_vectored(void);
81 81
82#if 0 82#if 0
83static int spurintr(void *); 83static int spurintr(void *);
84#endif 84#endif
85 85
86void 86void
87isrinit(void) 87isrinit(void)
88{ 88{
89 int i; 89 int i;
90 90
91 /* Initialize the autovector lists. */ 91 /* Initialize the autovector lists. */
92 for (i = 0; i < NISRAUTOVEC; ++i) 92 for (i = 0; i < NISRAUTOVEC; ++i)
93 LIST_INIT(&isr_autovec[i]); 93 LIST_INIT(&isr_autovec[i]);
94 94
95 /* Initialise the interrupt event counts */ 95 /* Initialise the interrupt event counts */
96 for (i = 0; i < (sizeof(next68k_irq_evcnt) / sizeof(struct evcnt)); i++) 96 for (i = 0; i < (sizeof(next68k_irq_evcnt) / sizeof(struct evcnt)); i++)
97 evcnt_attach_static(&next68k_irq_evcnt[i]); 97 evcnt_attach_static(&next68k_irq_evcnt[i]);
98 98
99 /* Arrange to trap Spurious and NMI auto-vectored Interrupts */ 99 /* Arrange to trap Spurious and NMI auto-vectored Interrupts */
100/* isrlink_autovec(spurintr, NULL, 0, 0, NULL); */ 100/* isrlink_autovec(spurintr, NULL, 0, 0, NULL); */
101/* isrlink_autovec(nmihand, NULL, 7, 0, NULL); */ 101/* isrlink_autovec(nmihand, NULL, 7, 0, NULL); */
102} 102}
103 103
104/* 104/*
105 * Establish an autovectored interrupt handler. 105 * Establish an autovectored interrupt handler.
106 * Called by driver attach functions. 106 * Called by driver attach functions.
107 */ 107 */
108void 108void
109isrlink_autovec(int (*func)(void *), void *arg, int ipl, int priority, 109isrlink_autovec(int (*func)(void *), void *arg, int ipl, int priority,
110 struct evcnt *evcnt) 110 struct evcnt *evcnt)
111{ 111{
112 struct isr_autovec *newisr, *curisr; 112 struct isr_autovec *newisr, *curisr;
113 isr_autovec_list_t *list; 113 isr_autovec_list_t *list;
114 114
115#ifdef DIAGNOSTIC 115#ifdef DIAGNOSTIC
116 if ((ipl < 0) || (ipl >= NISRAUTOVEC)) 116 if ((ipl < 0) || (ipl >= NISRAUTOVEC))
117 panic("isrlink_autovec: bad ipl %d", ipl); 117 panic("isrlink_autovec: bad ipl %d", ipl);
118#endif 118#endif
119 119
120 newisr = kmem_alloc(sizeof(*newisr), KM_SLEEP); 120 newisr = kmem_alloc(sizeof(*newisr), KM_SLEEP);
121 newisr->isr_func = func; 121 newisr->isr_func = func;
122 newisr->isr_arg = arg; 122 newisr->isr_arg = arg;
123 newisr->isr_ipl = ipl; 123 newisr->isr_ipl = ipl;
124 newisr->isr_priority = priority; 124 newisr->isr_priority = priority;
125 newisr->isr_evcnt = evcnt; 125 newisr->isr_evcnt = evcnt;
126 126
127 /* 127 /*
128 * Some devices are particularly sensitive to interrupt 128 * Some devices are particularly sensitive to interrupt
129 * handling latency. The SCC, for example, can lose many 129 * handling latency. The SCC, for example, can lose many
130 * characters if its interrupt isn't handled with reasonable 130 * characters if its interrupt isn't handled with reasonable
131 * speed. 131 * speed.
132 * 132 *
133 * To work around this problem, each device can give itself a 133 * To work around this problem, each device can give itself a
134 * "priority". An unbuffered SCC would give itself a higher 134 * "priority". An unbuffered SCC would give itself a higher
135 * priority than a SCSI device, for example. 135 * priority than a SCSI device, for example.
136 * 136 *
137 * This solution was originally developed for the hp300, which 137 * This solution was originally developed for the hp300, which
138 * has a flat spl scheme (by necessity). Thankfully, the 138 * has a flat spl scheme (by necessity). Thankfully, the
139 * MVME systems don't have this problem, though this may serve 139 * MVME systems don't have this problem, though this may serve
140 * a useful purpose in any case. 140 * a useful purpose in any case.
141 */ 141 */
142 142
143 /* 143 /*
144 * Get the appropriate ISR list. If the list is empty, no 144 * Get the appropriate ISR list. If the list is empty, no
145 * additional work is necessary; we simply insert ourselves 145 * additional work is necessary; we simply insert ourselves
146 * at the head of the list. 146 * at the head of the list.
147 */ 147 */
148 list = &isr_autovec[ipl]; 148 list = &isr_autovec[ipl];
149 if (list->lh_first == NULL) { 149 if (list->lh_first == NULL) {
150 LIST_INSERT_HEAD(list, newisr, isr_link); 150 LIST_INSERT_HEAD(list, newisr, isr_link);
151 return; 151 return;
152 } 152 }
153 153
154 /* 154 /*
155 * A little extra work is required. We traverse the list 155 * A little extra work is required. We traverse the list
156 * and place ourselves after any ISRs with our current (or 156 * and place ourselves after any ISRs with our current (or
157 * higher) priority. 157 * higher) priority.
158 */ 158 */
159 for (curisr = list->lh_first; curisr->isr_link.le_next != NULL; 159 for (curisr = list->lh_first; curisr->isr_link.le_next != NULL;
160 curisr = curisr->isr_link.le_next) { 160 curisr = curisr->isr_link.le_next) {
161 if (newisr->isr_priority > curisr->isr_priority) { 161 if (newisr->isr_priority > curisr->isr_priority) {
162 LIST_INSERT_BEFORE(curisr, newisr, isr_link); 162 LIST_INSERT_BEFORE(curisr, newisr, isr_link);
163 return; 163 return;
164 } 164 }
165 } 165 }
166 166
167 /* 167 /*
168 * We're the least important entry, it seems. We just go 168 * We're the least important entry, it seems. We just go
169 * on the end. 169 * on the end.
170 */ 170 */
171 LIST_INSERT_AFTER(curisr, newisr, isr_link); 171 LIST_INSERT_AFTER(curisr, newisr, isr_link);
172} 172}
173 173
174/* 174/*
175 * Establish a vectored interrupt handler. 175 * Establish a vectored interrupt handler.
176 * Called by bus interrupt establish functions. 176 * Called by bus interrupt establish functions.
177 */ 177 */
178void 178void
179isrlink_vectored(int (*func)(void *), void *arg, int ipl, int vec, 179isrlink_vectored(int (*func)(void *), void *arg, int ipl, int vec,
180 struct evcnt *evcnt) 180 struct evcnt *evcnt)
181{ 181{
182 struct isr_vectored *isr; 182 struct isr_vectored *isr;
183 183
184#ifdef DIAGNOSTIC 184#ifdef DIAGNOSTIC
185 if ((ipl < 0) || (ipl >= NISRAUTOVEC)) 185 if ((ipl < 0) || (ipl >= NISRAUTOVEC))
186 panic("isrlink_vectored: bad ipl %d", ipl); 186 panic("isrlink_vectored: bad ipl %d", ipl);
187 if ((vec < ISRVECTORED) || (vec >= ISRVECTORED + NISRVECTORED)) 187 if ((vec < ISRVECTORED) || (vec >= ISRVECTORED + NISRVECTORED))
188 panic("isrlink_vectored: bad vec 0x%x", vec); 188 panic("isrlink_vectored: bad vec 0x%x", vec);
189#endif 189#endif
190 190
191 isr = &isr_vectored[vec - ISRVECTORED]; 191 isr = &isr_vectored[vec - ISRVECTORED];
192 192
193#ifdef DIAGNOSTIC 193#ifdef DIAGNOSTIC
194 if ((vectab[vec] != badtrap) || (isr->isr_func != NULL)) 194 if ((vectab[vec] != badtrap) || (isr->isr_func != NULL))
195 panic("isrlink_vectored: vec 0x%x not available", vec); 195 panic("isrlink_vectored: vec 0x%x not available", vec);
196#endif 196#endif
197 197
198 /* Fill in the new entry. */ 198 /* Fill in the new entry. */
199 isr->isr_func = func; 199 isr->isr_func = func;
200 isr->isr_arg = arg; 200 isr->isr_arg = arg;
201 isr->isr_ipl = ipl; 201 isr->isr_ipl = ipl;
202 isr->isr_evcnt = evcnt; 202 isr->isr_evcnt = evcnt;
203 203
204 /* Hook into the vector table. */ 204 /* Hook into the vector table. */
205 vectab[vec] = intrhand_vectored; 205 vectab[vec] = intrhand_vectored;
206} 206}
207 207
208/* 208/*
209 * Return a pointer to the evcnt structure for 209 * Return a pointer to the evcnt structure for
210 * the specified ipl. 210 * the specified ipl.
211 */ 211 */
212struct evcnt * 212struct evcnt *
213isrlink_evcnt(int ipl) 213isrlink_evcnt(int ipl)
214{ 214{
215 215
216#ifdef DIAGNOSTIC 216#ifdef DIAGNOSTIC
217 if (ipl < 0 || 217 if (ipl < 0 ||
218 ipl >= (sizeof(next68k_irq_evcnt) / sizeof(struct evcnt))) 218 ipl >= (sizeof(next68k_irq_evcnt) / sizeof(struct evcnt)))
219 panic("isrlink_evcnt: bad ipl %d", ipl); 219 panic("isrlink_evcnt: bad ipl %d", ipl);
220#endif 220#endif
221 221
222 return (&next68k_irq_evcnt[ipl]); 222 return (&next68k_irq_evcnt[ipl]);
223} 223}
224 224
225/* 225/*
226 * Unhook a vectored interrupt. 226 * Unhook a vectored interrupt.
227 */ 227 */
228void 228void
229isrunlink_vectored(int vec) 229isrunlink_vectored(int vec)
230{ 230{
231 231
232#ifdef DIAGNOSTIC 232#ifdef DIAGNOSTIC
233 if ((vec < ISRVECTORED) || (vec >= ISRVECTORED + NISRVECTORED)) 233 if ((vec < ISRVECTORED) || (vec >= ISRVECTORED + NISRVECTORED))
234 panic("isrunlink_vectored: bad vec 0x%x", vec); 234 panic("isrunlink_vectored: bad vec 0x%x", vec);
235 235
236 if (vectab[vec] != intrhand_vectored) 236 if (vectab[vec] != intrhand_vectored)
237 panic("isrunlink_vectored: not vectored interrupt"); 237 panic("isrunlink_vectored: not vectored interrupt");
238#endif 238#endif
239 239
240 vectab[vec] = badtrap; 240 vectab[vec] = badtrap;
241 memset(&isr_vectored[vec - ISRVECTORED], 0, sizeof(struct isr_vectored)); 241 memset(&isr_vectored[vec - ISRVECTORED], 0, sizeof(struct isr_vectored));
242} 242}
243 243
244/* 244/*
245 * This is the dispatcher called by the low-level 245 * This is the dispatcher called by the low-level
246 * assembly language autovectored interrupt routine. 246 * assembly language autovectored interrupt routine.
247 */ 247 */
248void 248void
249isrdispatch_autovec(struct clockframe *frame) 249isrdispatch_autovec(struct clockframe *frame)
250{ 250{
251 struct isr_autovec *isr; 251 struct isr_autovec *isr;
252 isr_autovec_list_t *list; 252 isr_autovec_list_t *list;
253 int handled, ipl; 253 int handled, ipl;
254 void *arg; 254 void *arg;
255 static int straycount, unexpected; 255 static int straycount, unexpected;
256#ifdef INTRLOG 256#ifdef INTRLOG
257 static int logptr = 0; 257 static int logptr = 0;
258 static struct { 258 static struct {
259 int ipl; 259 int ipl;
260 u_long intrstat, intrmask; 260 u_long intrstat, intrmask;
261 int handled; 261 int handled;
262 } log[256]; 262 } log[256];
263#endif 263#endif
264 264
265 idepth++; 265 idepth++;
266 266
267 ipl = (frame->vec >> 2) - ISRAUTOVEC; 267 ipl = (frame->vec >> 2) - ISRAUTOVEC;
268 268
269#ifdef DIAGNOSTIC 269#ifdef DIAGNOSTIC
270 if ((ipl < 0) || (ipl >= NISRAUTOVEC)) 270 if ((ipl < 0) || (ipl >= NISRAUTOVEC))
271 panic("isrdispatch_autovec: bad vec 0x%x", frame->vec); 271 panic("isrdispatch_autovec: bad vec 0x%x", frame->vec);
272#endif 272#endif
273 273
274 intrcnt[ipl]++; /* XXXSCW: Will go away soon */ 274 intrcnt[ipl]++; /* XXXSCW: Will go away soon */
275 next68k_irq_evcnt[ipl].ev_count++; 275 next68k_irq_evcnt[ipl].ev_count++;
276 curcpu()->ci_data.cpu_nintr++; 276 curcpu()->ci_data.cpu_nintr++;
277#ifdef INTRLOG 277#ifdef INTRLOG
278 log[logptr].ipl = ipl; 278 log[logptr].ipl = ipl;
279 log[logptr].intrstat = *intrstat; 279 log[logptr].intrstat = *intrstat;
280 log[logptr].intrmask = *intrmask; 280 log[logptr].intrmask = *intrmask;
281#endif 281#endif
282 282
283 list = &isr_autovec[ipl]; 283 list = &isr_autovec[ipl];
284 if (list->lh_first == NULL) { 284 if (list->lh_first == NULL) {
285 printf("isrdispatch_autovec: ipl %d unexpected\n", ipl); 285 printf("isrdispatch_autovec: ipl %d unexpected\n", ipl);
286 if (++unexpected > 10) 286 if (++unexpected > 10)
287 panic("too many unexpected interrupts"); 287 panic("too many unexpected interrupts");
288 idepth--; 288 idepth--;
289 return; 289 return;
290 } 290 }
291 291
292 /* Give all the handlers a chance. */ 292 /* Give all the handlers a chance. */
293 handled = 0; 293 handled = 0;
294 for (isr = list->lh_first ; isr != NULL; isr = isr->isr_link.le_next) { 294 for (isr = list->lh_first ; isr != NULL; isr = isr->isr_link.le_next) {
295 arg = isr->isr_arg ? isr->isr_arg : frame; 295 arg = isr->isr_arg ? isr->isr_arg : frame;
296 if ((*isr->isr_func)(arg) != 0) { 296 if ((*isr->isr_func)(arg) != 0) {
297 if (isr->isr_evcnt) 297 if (isr->isr_evcnt)
298 isr->isr_evcnt->ev_count++; 298 isr->isr_evcnt->ev_count++;
299 handled++; 299 handled++;
300 } 300 }
301 } 301 }
302 302
303#ifdef INTRLOG 303#ifdef INTRLOG
304 log[logptr].handled = handled; 304 log[logptr].handled = handled;
305 logptr = (logptr + 1) & 255; 305 logptr = (logptr + 1) & 255;
306 if (!handled && ++straycount >= 10) { 306 if (!handled && ++straycount >= 10) {
307 int n, m; 307 int n, m;
308 printf("%d stray interrupts, level %d\n", straycount, ipl); 308 printf("%d stray interrupts, level %d\n", straycount, ipl);
309 for (n = 20; n; n--) { 309 for (n = 20; n; n--) {
310 m = (logptr - n) & 255; 310 m = (logptr - n) & 255;
311 printf("%02d: %d %08lx %08lx %d\n", n, log[m].ipl, 311 printf("%02d: %d %08lx %08lx %d\n", n, log[m].ipl,
312 log[m].intrstat, log[m].intrmask, log[m].handled); 312 log[m].intrstat, log[m].intrmask, log[m].handled);
313 } 313 }
314 Debugger(); 314 Debugger();
315 straycount = 0; 315 straycount = 0;
316 } 316 }
317#else 317#else
318 if (handled) 318 if (handled)
319 straycount = 0; 319 straycount = 0;
320 else if (++straycount > 50) 320 else if (++straycount > 50)
321 panic("isr_dispatch_autovec: too many stray interrupts"); 321 panic("isr_dispatch_autovec: too many stray interrupts");
322 else { 322 else {
323 char sbuf[256]; 323 char sbuf[256];
324 324
325 printf("isrdispatch_autovec: stray level %d interrupt\n", ipl); 325 printf("isrdispatch_autovec: stray level %d interrupt\n", ipl);
326 326
327 snprintb(sbuf, sizeof(sbuf), NEXT_INTR_BITS, 327 snprintb(sbuf, sizeof(sbuf), NEXT_INTR_BITS,
328 (*(volatile u_long *)IIOV(NEXT_P_INTRSTAT))); 328 (*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)));
329 printf(" *intrstat = %s\n", sbuf); 329 printf(" *intrstat = %s\n", sbuf);
330 330
331 snprintb(sbuf, sizeof(sbuf), NEXT_INTR_BITS, 331 snprintb(sbuf, sizeof(sbuf), NEXT_INTR_BITS,
332 (*(volatile u_long *)IIOV(NEXT_P_INTRMASK))); 332 (*(volatile u_long *)IIOV(NEXT_P_INTRMASK)));
333 printf(" *intrmask = %s\n", sbuf); 333 printf(" *intrmask = %s\n", sbuf);
334 } 334 }
335#endif 335#endif
336 336
337 idepth--; 337 idepth--;
338} 338}
339 339
340bool 340bool
341cpu_intr_p(void) 341cpu_intr_p(void)
342{ 342{
343 343
344 return idepth != 0; 344 return idepth != 0;
345} 345}
346 346
347/* 347/*
348 * This is the dispatcher called by the low-level 348 * This is the dispatcher called by the low-level
349 * assembly language vectored interrupt routine. 349 * assembly language vectored interrupt routine.
350 */ 350 */
351void 351void
352isrdispatch_vectored(int ipl, struct clockframe *frame) 352isrdispatch_vectored(int ipl, struct clockframe *frame)
353{ 353{
354 struct isr_vectored *isr; 354 struct isr_vectored *isr;
355 int vec; 355 int vec;
356 356
357 vec = (frame->vec >> 2) - ISRVECTORED; 357 vec = (frame->vec >> 2) - ISRVECTORED;
358 358
359#ifdef DIAGNOSTIC 359#ifdef DIAGNOSTIC
360 if ((vec < 0) || (vec >= NISRVECTORED)) 360 if ((vec < 0) || (vec >= NISRVECTORED))
361 panic("isrdispatch_vectored: bad vec 0x%x", frame->vec); 361 panic("isrdispatch_vectored: bad vec 0x%x", frame->vec);
362#endif 362#endif
363 363
364 isr = &isr_vectored[vec]; 364 isr = &isr_vectored[vec];
365 365
366 intrcnt[ipl]++; /* XXXSCW: Will go away soon */ 366 intrcnt[ipl]++; /* XXXSCW: Will go away soon */
367 next68k_irq_evcnt[ipl].ev_count++; 367 next68k_irq_evcnt[ipl].ev_count++;
368 curcpu()->ci_data.cpu_nintr++; 368 curcpu()->ci_data.cpu_nintr++;
369 369
370 if (isr->isr_func == NULL) { 370 if (isr->isr_func == NULL) {
371 printf("isrdispatch_vectored: no handler for vec 0x%x\n", 371 printf("isrdispatch_vectored: no handler for vec 0x%x\n",
372 frame->vec); 372 frame->vec);
373 vectab[vec + ISRVECTORED] = badtrap; 373 vectab[vec + ISRVECTORED] = badtrap;
374 return; 374 return;
375 } 375 }
376 376
377 /* 377 /*
378 * Handler gets exception frame if argument is NULL. 378 * Handler gets exception frame if argument is NULL.
379 */ 379 */
380 if ((*isr->isr_func)(isr->isr_arg ? isr->isr_arg : frame) == 0) 380 if ((*isr->isr_func)(isr->isr_arg ? isr->isr_arg : frame) == 0)
381 printf("isrdispatch_vectored: vec 0x%x not claimed\n", 381 printf("isrdispatch_vectored: vec 0x%x not claimed\n",
382 frame->vec); 382 frame->vec);
383 else 383 else
384 if (isr->isr_evcnt) 384 if (isr->isr_evcnt)
385 isr->isr_evcnt->ev_count++; 385 isr->isr_evcnt->ev_count++;
386} 386}
387 387
388#if 0 388#if 0
389/* ARGSUSED */ 389/* ARGSUSED */
390static int 390static int
391spurintr(void *arg) 391spurintr(void *arg)
392{ 392{
393 393
394 return (1); 394 return (1);
395} 395}
396#endif 396#endif
397 397
398const uint16_t ipl2psl_table[NIPL] = { 398const uint16_t ipl2psl_table[NIPL] = {
399 [IPL_NONE] = PSL_S | PSL_IPL0, 399 [IPL_NONE] = PSL_S | PSL_IPL0,
400 [IPL_SOFTCLOCK] = PSL_S | PSL_IPL1, 400 [IPL_SOFTCLOCK] = PSL_S | PSL_IPL1,
401 [IPL_SOFTNET] = PSL_S | PSL_IPL1, 401 [IPL_SOFTNET] = PSL_S | PSL_IPL1,
402 [IPL_SOFTSERIAL] = PSL_S | PSL_IPL1, 402 [IPL_SOFTSERIAL] = PSL_S | PSL_IPL1,
403 [IPL_SOFTBIO] = PSL_S | PSL_IPL1, 403 [IPL_SOFTBIO] = PSL_S | PSL_IPL1,
404 [IPL_VM] = PSL_S | PSL_IPL6, 404 [IPL_VM] = PSL_S | PSL_IPL6,
405 [IPL_SCHED] = PSL_S | PSL_IPL7, 405 [IPL_SCHED] = PSL_S | PSL_IPL7,
406 [IPL_HIGH] = PSL_S | PSL_IPL7, 406 [IPL_HIGH] = PSL_S | PSL_IPL7,
407}; 407};

cvs diff -r1.64 -r1.65 src/sys/arch/sun3/sun3/clock.c (switch to unified diff)

--- src/sys/arch/sun3/sun3/clock.c 2013/09/07 15:56:11 1.64
+++ src/sys/arch/sun3/sun3/clock.c 2021/04/02 12:11:41 1.65
@@ -1,335 +1,335 @@ @@ -1,335 +1,335 @@
1/* $NetBSD: clock.c,v 1.64 2013/09/07 15:56:11 tsutsui Exp $ */ 1/* $NetBSD: clock.c,v 1.65 2021/04/02 12:11:41 rin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1982, 1990, 1993 4 * Copyright (c) 1982, 1990, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * the Systems Programming Group of the University of Utah Computer 8 * the Systems Programming Group of the University of Utah Computer
9 * Science Department. 9 * Science Department.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors 19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software 20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 21 * without specific prior written permission.
22 * 22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE. 33 * SUCH DAMAGE.
34 * 34 *
35 * from: Utah Hdr: clock.c 1.18 91/01/21$ 35 * from: Utah Hdr: clock.c 1.18 91/01/21$
36 * from: @(#)clock.c 8.2 (Berkeley) 1/12/94 36 * from: @(#)clock.c 8.2 (Berkeley) 1/12/94
37 */ 37 */
38 38
39/* 39/*
40 * Copyright (c) 1994 Gordon W. Ross 40 * Copyright (c) 1994 Gordon W. Ross
41 * Copyright (c) 1993 Adam Glass 41 * Copyright (c) 1993 Adam Glass
42 * Copyright (c) 1988 University of Utah. 42 * Copyright (c) 1988 University of Utah.
43 * 43 *
44 * This code is derived from software contributed to Berkeley by 44 * This code is derived from software contributed to Berkeley by
45 * the Systems Programming Group of the University of Utah Computer 45 * the Systems Programming Group of the University of Utah Computer
46 * Science Department. 46 * Science Department.
47 * 47 *
48 * Redistribution and use in source and binary forms, with or without 48 * Redistribution and use in source and binary forms, with or without
49 * modification, are permitted provided that the following conditions 49 * modification, are permitted provided that the following conditions
50 * are met: 50 * are met:
51 * 1. Redistributions of source code must retain the above copyright 51 * 1. Redistributions of source code must retain the above copyright
52 * notice, this list of conditions and the following disclaimer. 52 * notice, this list of conditions and the following disclaimer.
53 * 2. Redistributions in binary form must reproduce the above copyright 53 * 2. Redistributions in binary form must reproduce the above copyright
54 * notice, this list of conditions and the following disclaimer in the 54 * notice, this list of conditions and the following disclaimer in the
55 * documentation and/or other materials provided with the distribution. 55 * documentation and/or other materials provided with the distribution.
56 * 3. All advertising materials mentioning features or use of this software 56 * 3. All advertising materials mentioning features or use of this software
57 * must display the following acknowledgement: 57 * must display the following acknowledgement:
58 * This product includes software developed by the University of 58 * This product includes software developed by the University of
59 * California, Berkeley and its contributors. 59 * California, Berkeley and its contributors.
60 * 4. Neither the name of the University nor the names of its contributors 60 * 4. Neither the name of the University nor the names of its contributors
61 * may be used to endorse or promote products derived from this software 61 * may be used to endorse or promote products derived from this software
62 * without specific prior written permission. 62 * without specific prior written permission.
63 * 63 *
64 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 64 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
65 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 65 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
66 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 66 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
67 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 67 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
68 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 68 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
69 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 69 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
70 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 70 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
71 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 71 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
72 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 72 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
73 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 73 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74 * SUCH DAMAGE. 74 * SUCH DAMAGE.
75 * 75 *
76 * from: Utah Hdr: clock.c 1.18 91/01/21$ 76 * from: Utah Hdr: clock.c 1.18 91/01/21$
77 * from: @(#)clock.c 8.2 (Berkeley) 1/12/94 77 * from: @(#)clock.c 8.2 (Berkeley) 1/12/94
78 */ 78 */
79 79
80/* 80/*
81 * Machine-dependent clock routines for the Intersil 7170: 81 * Machine-dependent clock routines for the Intersil 7170:
82 * Original by Adam Glass; partially rewritten by Gordon Ross. 82 * Original by Adam Glass; partially rewritten by Gordon Ross.
83 */ 83 */
84 84
85#include <sys/cdefs.h> 85#include <sys/cdefs.h>
86__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.64 2013/09/07 15:56:11 tsutsui Exp $"); 86__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.65 2021/04/02 12:11:41 rin Exp $");
87 87
88#include <sys/param.h> 88#include <sys/param.h>
89#include <sys/systm.h> 89#include <sys/systm.h>
90#include <sys/time.h> 90#include <sys/time.h>
91#include <sys/kernel.h> 91#include <sys/kernel.h>
92#include <sys/device.h> 92#include <sys/device.h>
93 93
94#include <uvm/uvm_extern.h> 94#include <uvm/uvm_extern.h>
95 95
96#include <m68k/asm_single.h> 96#include <m68k/asm_single.h>
97 97
98#include <machine/autoconf.h> 98#include <machine/autoconf.h>
99#include <machine/bus.h> 99#include <machine/bus.h>
100#include <machine/cpu.h> 100#include <machine/cpu.h>
101#include <machine/leds.h> 101#include <machine/leds.h>
102 102
103#include <sun3/sun3/control.h> 103#include <sun3/sun3/control.h>
104#include <sun3/sun3/interreg.h> 104#include <sun3/sun3/interreg.h>
105#include <sun3/sun3/machdep.h> 105#include <sun3/sun3/machdep.h>
106 106
107#include <dev/clock_subr.h> 107#include <dev/clock_subr.h>
108#include <dev/ic/intersil7170reg.h> 108#include <dev/ic/intersil7170reg.h>
109#include <dev/ic/intersil7170var.h> 109#include <dev/ic/intersil7170var.h>
110 110
111extern int intrcnt[]; 111extern u_int intrcnt[];
112 112
113#define CLOCK_PRI 5 113#define CLOCK_PRI 5
114#define IREG_CLK_BITS (IREG_CLOCK_ENAB_7 | IREG_CLOCK_ENAB_5) 114#define IREG_CLK_BITS (IREG_CLOCK_ENAB_7 | IREG_CLOCK_ENAB_5)
115 115
116void _isr_clock(void); /* in locore.s */ 116void _isr_clock(void); /* in locore.s */
117void clock_intr(struct clockframe); 117void clock_intr(struct clockframe);
118 118
119static volatile void *intersil_va; 119static volatile void *intersil_va;
120 120
121#define intersil_clock ((volatile struct intersil7170 *)intersil_va) 121#define intersil_clock ((volatile struct intersil7170 *)intersil_va)
122 122
123#define intersil_clear() (void)intersil_clock->clk_intr_reg 123#define intersil_clear() (void)intersil_clock->clk_intr_reg
124 124
125static int oclock_match(device_t, cfdata_t, void *); 125static int oclock_match(device_t, cfdata_t, void *);
126static void oclock_attach(device_t, device_t, void *); 126static void oclock_attach(device_t, device_t, void *);
127 127
128CFATTACH_DECL_NEW(oclock, sizeof(struct intersil7170_softc), 128CFATTACH_DECL_NEW(oclock, sizeof(struct intersil7170_softc),
129 oclock_match, oclock_attach, NULL, NULL); 129 oclock_match, oclock_attach, NULL, NULL);
130 130
131static int 131static int
132oclock_match(device_t parent, cfdata_t cf, void *aux) 132oclock_match(device_t parent, cfdata_t cf, void *aux)
133{ 133{
134 struct confargs *ca = aux; 134 struct confargs *ca = aux;
135 135
136 /* This driver only supports one unit. */ 136 /* This driver only supports one unit. */
137 if (intersil_va) 137 if (intersil_va)
138 return 0; 138 return 0;
139 139
140 /* Make sure there is something there... */ 140 /* Make sure there is something there... */
141 if (bus_peek(ca->ca_bustype, ca->ca_paddr, 1) == -1) 141 if (bus_peek(ca->ca_bustype, ca->ca_paddr, 1) == -1)
142 return 0; 142 return 0;
143 143
144 /* Default interrupt priority. */ 144 /* Default interrupt priority. */
145 if (ca->ca_intpri == -1) 145 if (ca->ca_intpri == -1)
146 ca->ca_intpri = CLOCK_PRI; 146 ca->ca_intpri = CLOCK_PRI;
147 147
148 return 1; 148 return 1;
149} 149}
150 150
151static void 151static void
152oclock_attach(device_t parent, device_t self, void *aux) 152oclock_attach(device_t parent, device_t self, void *aux)
153{ 153{
154 struct intersil7170_softc *sc = device_private(self); 154 struct intersil7170_softc *sc = device_private(self);
155 struct confargs *ca = aux; 155 struct confargs *ca = aux;
156 156
157 sc->sc_dev = self; 157 sc->sc_dev = self;
158 158
159 /* Get a mapping for it. */ 159 /* Get a mapping for it. */
160 sc->sc_bst = ca->ca_bustag; 160 sc->sc_bst = ca->ca_bustag;
161 if (bus_space_map(sc->sc_bst, ca->ca_paddr, sizeof(struct intersil7170), 161 if (bus_space_map(sc->sc_bst, ca->ca_paddr, sizeof(struct intersil7170),
162 0, &sc->sc_bsh) != 0) { 162 0, &sc->sc_bsh) != 0) {
163 aprint_error(": can't map registers\n"); 163 aprint_error(": can't map registers\n");
164 return; 164 return;
165 } 165 }
166 166
167 intersil_va = bus_space_vaddr(sc->sc_bst, sc->sc_bsh); 167 intersil_va = bus_space_vaddr(sc->sc_bst, sc->sc_bsh);
168 168
169 /* 169 /*
170 * Set the clock to the correct interrupt rate, but 170 * Set the clock to the correct interrupt rate, but
171 * do not enable the interrupt until cpu_initclocks. 171 * do not enable the interrupt until cpu_initclocks.
172 * XXX: Actually, the interrupt_reg should be zero 172 * XXX: Actually, the interrupt_reg should be zero
173 * at this point, so the clock interrupts should not 173 * at this point, so the clock interrupts should not
174 * affect us, but we need to set the rate... 174 * affect us, but we need to set the rate...
175 */ 175 */
176 bus_space_write_1(sc->sc_bst, sc->sc_bsh, INTERSIL_ICMD, 176 bus_space_write_1(sc->sc_bst, sc->sc_bsh, INTERSIL_ICMD,
177 INTERSIL_COMMAND(INTERSIL_CMD_RUN, INTERSIL_CMD_IDISABLE)); 177 INTERSIL_COMMAND(INTERSIL_CMD_RUN, INTERSIL_CMD_IDISABLE));
178 (void)bus_space_read_1(sc->sc_bst, sc->sc_bsh, INTERSIL_IINTR); 178 (void)bus_space_read_1(sc->sc_bst, sc->sc_bsh, INTERSIL_IINTR);
179 179
180 /* Set the clock to 100 Hz, but do not enable it yet. */ 180 /* Set the clock to 100 Hz, but do not enable it yet. */
181 bus_space_write_1(sc->sc_bst, sc->sc_bsh, 181 bus_space_write_1(sc->sc_bst, sc->sc_bsh,
182 INTERSIL_IINTR, INTERSIL_INTER_CSECONDS); 182 INTERSIL_IINTR, INTERSIL_INTER_CSECONDS);
183 183
184 sc->sc_year0 = 1968; 184 sc->sc_year0 = 1968;
185 intersil7170_attach(sc); 185 intersil7170_attach(sc);
186 186
187 aprint_normal("\n"); 187 aprint_normal("\n");
188 188
189 /* 189 /*
190 * Can not hook up the ISR until cpu_initclocks() 190 * Can not hook up the ISR until cpu_initclocks()
191 * because hardclock is not ready until then. 191 * because hardclock is not ready until then.
192 * For now, the handler is _isr_autovec(), which 192 * For now, the handler is _isr_autovec(), which
193 * will complain if it gets clock interrupts. 193 * will complain if it gets clock interrupts.
194 */ 194 */
195} 195}
196 196
197/* 197/*
198 * Set and/or clear the desired clock bits in the interrupt 198 * Set and/or clear the desired clock bits in the interrupt
199 * register. We have to be extremely careful that we do it 199 * register. We have to be extremely careful that we do it
200 * in such a manner that we don't get ourselves lost. 200 * in such a manner that we don't get ourselves lost.
201 * XXX: Watch out! It's really easy to break this! 201 * XXX: Watch out! It's really easy to break this!
202 */ 202 */
203void 203void
204set_clk_mode(u_char on, u_char off, int enable_clk) 204set_clk_mode(u_char on, u_char off, int enable_clk)
205{ 205{
206 u_char interreg; 206 u_char interreg;
207 207
208 /* 208 /*
209 * If we have not yet mapped the register, 209 * If we have not yet mapped the register,
210 * then we do not want to do any of this... 210 * then we do not want to do any of this...
211 */ 211 */
212 if (!interrupt_reg) 212 if (!interrupt_reg)
213 return; 213 return;
214 214
215#ifdef DIAGNOSTIC 215#ifdef DIAGNOSTIC
216 /* Assertion: were are at splhigh! */ 216 /* Assertion: were are at splhigh! */
217 if ((getsr() & PSL_IPL) < PSL_IPL7) 217 if ((getsr() & PSL_IPL) < PSL_IPL7)
218 panic("set_clk_mode: bad ipl"); 218 panic("set_clk_mode: bad ipl");
219#endif 219#endif
220 220
221 /* 221 /*
222 * make sure that we are only playing w/ 222 * make sure that we are only playing w/
223 * clock interrupt register bits 223 * clock interrupt register bits
224 */ 224 */
225 on &= IREG_CLK_BITS; 225 on &= IREG_CLK_BITS;
226 off &= IREG_CLK_BITS; 226 off &= IREG_CLK_BITS;
227 227
228 /* First, turn off the "master" enable bit. */ 228 /* First, turn off the "master" enable bit. */
229 single_inst_bclr_b(*interrupt_reg, IREG_ALL_ENAB); 229 single_inst_bclr_b(*interrupt_reg, IREG_ALL_ENAB);
230 230
231 /* 231 /*
232 * Save the current interrupt register clock bits, 232 * Save the current interrupt register clock bits,
233 * and turn off/on the requested bits in the copy. 233 * and turn off/on the requested bits in the copy.
234 */ 234 */
235 interreg = *interrupt_reg & IREG_CLK_BITS; 235 interreg = *interrupt_reg & IREG_CLK_BITS;
236 interreg &= ~off; 236 interreg &= ~off;
237 interreg |= on; 237 interreg |= on;
238 238
239 /* Clear the CLK5 and CLK7 bits to clear the flip-flops. */ 239 /* Clear the CLK5 and CLK7 bits to clear the flip-flops. */
240 single_inst_bclr_b(*interrupt_reg, IREG_CLK_BITS); 240 single_inst_bclr_b(*interrupt_reg, IREG_CLK_BITS);
241 241
242 if (intersil_va) { 242 if (intersil_va) {
243 /* 243 /*
244 * Then disable clock interrupts, and read the clock's 244 * Then disable clock interrupts, and read the clock's
245 * interrupt register to clear any pending signals there. 245 * interrupt register to clear any pending signals there.
246 */ 246 */
247 intersil_clock->clk_cmd_reg = 247 intersil_clock->clk_cmd_reg =
248 INTERSIL_COMMAND(INTERSIL_CMD_RUN, INTERSIL_CMD_IDISABLE); 248 INTERSIL_COMMAND(INTERSIL_CMD_RUN, INTERSIL_CMD_IDISABLE);
249 intersil_clear(); 249 intersil_clear();
250 } 250 }
251 251
252 /* Set the requested bits in the interrupt register. */ 252 /* Set the requested bits in the interrupt register. */
253 single_inst_bset_b(*interrupt_reg, interreg); 253 single_inst_bset_b(*interrupt_reg, interreg);
254 254
255 /* Turn the clock back on (maybe) */ 255 /* Turn the clock back on (maybe) */
256 if (intersil_va && enable_clk) 256 if (intersil_va && enable_clk)
257 intersil_clock->clk_cmd_reg = 257 intersil_clock->clk_cmd_reg =
258 INTERSIL_COMMAND(INTERSIL_CMD_RUN, INTERSIL_CMD_IENABLE); 258 INTERSIL_COMMAND(INTERSIL_CMD_RUN, INTERSIL_CMD_IENABLE);
259 259
260 /* Finally, turn the "master" enable back on. */ 260 /* Finally, turn the "master" enable back on. */
261 single_inst_bset_b(*interrupt_reg, IREG_ALL_ENAB); 261 single_inst_bset_b(*interrupt_reg, IREG_ALL_ENAB);
262} 262}
263 263
264/* 264/*
265 * Set up the real-time clock (enable clock interrupts). 265 * Set up the real-time clock (enable clock interrupts).
266 * Leave stathz 0 since there is no secondary clock available. 266 * Leave stathz 0 since there is no secondary clock available.
267 * Note that clock interrupts MUST STAY DISABLED until here. 267 * Note that clock interrupts MUST STAY DISABLED until here.
268 */ 268 */
269void 269void
270cpu_initclocks(void) 270cpu_initclocks(void)
271{ 271{
272 int s; 272 int s;
273 273
274 s = splhigh(); 274 s = splhigh();
275 275
276 /* Install isr (in locore.s) that calls clock_intr(). */ 276 /* Install isr (in locore.s) that calls clock_intr(). */
277 isr_add_custom(CLOCK_PRI, (void *)_isr_clock); 277 isr_add_custom(CLOCK_PRI, (void *)_isr_clock);
278 278
279 /* Now enable the clock at level 5 in the interrupt reg. */ 279 /* Now enable the clock at level 5 in the interrupt reg. */
280 set_clk_mode(IREG_CLOCK_ENAB_5, 0, 1); 280 set_clk_mode(IREG_CLOCK_ENAB_5, 0, 1);
281 281
282 splx(s); 282 splx(s);
283} 283}
284 284
285/* 285/*
286 * This doesn't need to do anything, as we have only one timer and 286 * This doesn't need to do anything, as we have only one timer and
287 * profhz==stathz==hz. 287 * profhz==stathz==hz.
288 */ 288 */
289void 289void
290setstatclockrate(int newhz) 290setstatclockrate(int newhz)
291{ 291{
292 292
293 /* nothing */ 293 /* nothing */
294} 294}
295 295
296/* 296/*
297 * This is called by the "custom" interrupt handler. 297 * This is called by the "custom" interrupt handler.
298 * Note that we can get ZS interrupts while this runs, 298 * Note that we can get ZS interrupts while this runs,
299 * and zshard may touch the interrupt_reg, so we must 299 * and zshard may touch the interrupt_reg, so we must
300 * be careful to use the single_inst_* macros to modify 300 * be careful to use the single_inst_* macros to modify
301 * the interrupt register atomically. 301 * the interrupt register atomically.
302 */ 302 */
303void 303void
304clock_intr(struct clockframe cf) 304clock_intr(struct clockframe cf)
305{ 305{
306 306
307 idepth++; 307 idepth++;
308 308
309 /* Read the clock interrupt register. */ 309 /* Read the clock interrupt register. */
310 intersil_clear(); 310 intersil_clear();
311 311
312 /* Pulse the clock intr. enable low. */ 312 /* Pulse the clock intr. enable low. */
313 single_inst_bclr_b(*interrupt_reg, IREG_CLOCK_ENAB_5); 313 single_inst_bclr_b(*interrupt_reg, IREG_CLOCK_ENAB_5);
314 single_inst_bset_b(*interrupt_reg, IREG_CLOCK_ENAB_5); 314 single_inst_bset_b(*interrupt_reg, IREG_CLOCK_ENAB_5);
315 315
316 /* Read the clock intr. reg. AGAIN! */ 316 /* Read the clock intr. reg. AGAIN! */
317 intersil_clear(); 317 intersil_clear();
318 318
319 intrcnt[CLOCK_PRI]++; 319 intrcnt[CLOCK_PRI]++;
320 curcpu()->ci_data.cpu_nintr++; 320 curcpu()->ci_data.cpu_nintr++;
321 321
322 { /* Entertainment! */ 322 { /* Entertainment! */
323#ifdef LED_IDLE_CHECK 323#ifdef LED_IDLE_CHECK
324 /* With this option, LEDs move only when CPU is idle. */ 324 /* With this option, LEDs move only when CPU is idle. */
325 extern char _Idle[]; /* locore.s */ 325 extern char _Idle[]; /* locore.s */
326 if (cf.cf_pc == (long)_Idle) 326 if (cf.cf_pc == (long)_Idle)
327#endif 327#endif
328 leds_intr(); 328 leds_intr();
329 } 329 }
330 330
331 /* Call common clock interrupt handler. */ 331 /* Call common clock interrupt handler. */
332 hardclock(&cf); 332 hardclock(&cf);
333 333
334 idepth--; 334 idepth--;
335} 335}

cvs diff -r1.40 -r1.41 src/sys/arch/sun3/sun3x/clock.c (switch to unified diff)

--- src/sys/arch/sun3/sun3x/clock.c 2013/09/06 17:43:19 1.40
+++ src/sys/arch/sun3/sun3x/clock.c 2021/04/02 12:11:41 1.41
@@ -1,456 +1,456 @@ @@ -1,456 +1,456 @@
1/* $NetBSD: clock.c,v 1.40 2013/09/06 17:43:19 tsutsui Exp $ */ 1/* $NetBSD: clock.c,v 1.41 2021/04/02 12:11:41 rin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1982, 1990, 1993 4 * Copyright (c) 1982, 1990, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * the Systems Programming Group of the University of Utah Computer 8 * the Systems Programming Group of the University of Utah Computer
9 * Science Department. 9 * Science Department.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors 19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software 20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 21 * without specific prior written permission.
22 * 22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE. 33 * SUCH DAMAGE.
34 * 34 *
35 * from: Utah Hdr: clock.c 1.18 91/01/21$ 35 * from: Utah Hdr: clock.c 1.18 91/01/21$
36 * from: @(#)clock.c 8.2 (Berkeley) 1/12/94 36 * from: @(#)clock.c 8.2 (Berkeley) 1/12/94
37 */ 37 */
38 38
39/* 39/*
40 * Copyright (c) 1994 Gordon W. Ross 40 * Copyright (c) 1994 Gordon W. Ross
41 * Copyright (c) 1993 Adam Glass 41 * Copyright (c) 1993 Adam Glass
42 * Copyright (c) 1988 University of Utah. 42 * Copyright (c) 1988 University of Utah.
43 * 43 *
44 * This code is derived from software contributed to Berkeley by 44 * This code is derived from software contributed to Berkeley by
45 * the Systems Programming Group of the University of Utah Computer 45 * the Systems Programming Group of the University of Utah Computer
46 * Science Department. 46 * Science Department.
47 * 47 *
48 * Redistribution and use in source and binary forms, with or without 48 * Redistribution and use in source and binary forms, with or without
49 * modification, are permitted provided that the following conditions 49 * modification, are permitted provided that the following conditions
50 * are met: 50 * are met:
51 * 1. Redistributions of source code must retain the above copyright 51 * 1. Redistributions of source code must retain the above copyright
52 * notice, this list of conditions and the following disclaimer. 52 * notice, this list of conditions and the following disclaimer.
53 * 2. Redistributions in binary form must reproduce the above copyright 53 * 2. Redistributions in binary form must reproduce the above copyright
54 * notice, this list of conditions and the following disclaimer in the 54 * notice, this list of conditions and the following disclaimer in the
55 * documentation and/or other materials provided with the distribution. 55 * documentation and/or other materials provided with the distribution.
56 * 3. All advertising materials mentioning features or use of this software 56 * 3. All advertising materials mentioning features or use of this software
57 * must display the following acknowledgement: 57 * must display the following acknowledgement:
58 * This product includes software developed by the University of 58 * This product includes software developed by the University of
59 * California, Berkeley and its contributors. 59 * California, Berkeley and its contributors.
60 * 4. Neither the name of the University nor the names of its contributors 60 * 4. Neither the name of the University nor the names of its contributors
61 * may be used to endorse or promote products derived from this software 61 * may be used to endorse or promote products derived from this software
62 * without specific prior written permission. 62 * without specific prior written permission.
63 * 63 *
64 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 64 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
65 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 65 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
66 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 66 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
67 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 67 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
68 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 68 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
69 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 69 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
70 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 70 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
71 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 71 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
72 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 72 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
73 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 73 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74 * SUCH DAMAGE. 74 * SUCH DAMAGE.
75 * 75 *
76 * from: Utah Hdr: clock.c 1.18 91/01/21$ 76 * from: Utah Hdr: clock.c 1.18 91/01/21$
77 * from: @(#)clock.c 8.2 (Berkeley) 1/12/94 77 * from: @(#)clock.c 8.2 (Berkeley) 1/12/94
78 */ 78 */
79 79
80/* 80/*
81 * Machine-dependent clock routines. Sun3X machines may have 81 * Machine-dependent clock routines. Sun3X machines may have
82 * either the Mostek 48T02 or the Intersil 7170 clock. 82 * either the Mostek 48T02 or the Intersil 7170 clock.
83 * 83 *
84 * It is tricky to determine which you have, because there is 84 * It is tricky to determine which you have, because there is
85 * always something responding at the address where the Mostek 85 * always something responding at the address where the Mostek
86 * clock might be found: either a Mostek or plain-old EEPROM. 86 * clock might be found: either a Mostek or plain-old EEPROM.
87 * Therefore, we cheat. If we find an Intersil clock, assume 87 * Therefore, we cheat. If we find an Intersil clock, assume
88 * that what responds at the end of the EEPROM space is just 88 * that what responds at the end of the EEPROM space is just
89 * plain-old EEPROM (not a Mostek clock). Worse, there are 89 * plain-old EEPROM (not a Mostek clock). Worse, there are
90 * H/W problems with probing for an Intersil on the 3/80, so 90 * H/W problems with probing for an Intersil on the 3/80, so
91 * on that machine we "know" there is a Mostek clock. 91 * on that machine we "know" there is a Mostek clock.
92 * 92 *
93 * Note that the probing algorithm described above requires 93 * Note that the probing algorithm described above requires
94 * that we probe the intersil before we probe the mostek! 94 * that we probe the intersil before we probe the mostek!
95 */ 95 */
96 96
97#include <sys/cdefs.h> 97#include <sys/cdefs.h>
98__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.40 2013/09/06 17:43:19 tsutsui Exp $"); 98__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.41 2021/04/02 12:11:41 rin Exp $");
99 99
100#include <sys/param.h> 100#include <sys/param.h>
101#include <sys/systm.h> 101#include <sys/systm.h>
102#include <sys/time.h> 102#include <sys/time.h>
103#include <sys/kernel.h> 103#include <sys/kernel.h>
104#include <sys/device.h> 104#include <sys/device.h>
105 105
106#include <uvm/uvm_extern.h> 106#include <uvm/uvm_extern.h>
107 107
108#include <m68k/asm_single.h> 108#include <m68k/asm_single.h>
109 109
110#include <machine/autoconf.h> 110#include <machine/autoconf.h>
111#include <machine/bus.h> 111#include <machine/bus.h>
112#include <machine/cpu.h> 112#include <machine/cpu.h>
113#include <machine/idprom.h> 113#include <machine/idprom.h>
114#include <machine/leds.h> 114#include <machine/leds.h>
115 115
116#include <dev/clock_subr.h> 116#include <dev/clock_subr.h>
117#include <dev/ic/intersil7170reg.h> 117#include <dev/ic/intersil7170reg.h>
118#include <dev/ic/intersil7170var.h> 118#include <dev/ic/intersil7170var.h>
119#include <dev/ic/mk48txxreg.h> 119#include <dev/ic/mk48txxreg.h>
120#include <dev/ic/mk48txxvar.h> 120#include <dev/ic/mk48txxvar.h>
121 121
122#include <sun3/sun3/machdep.h> 122#include <sun3/sun3/machdep.h>
123#include <sun3/sun3/interreg.h> 123#include <sun3/sun3/interreg.h>
124 124
125extern int intrcnt[]; 125extern u_int intrcnt[];
126 126
127#define SUN3_470 Yes 127#define SUN3_470 Yes
128 128
129#define CLOCK_PRI 5 129#define CLOCK_PRI 5
130#define IREG_CLK_BITS (IREG_CLOCK_ENAB_7 | IREG_CLOCK_ENAB_5) 130#define IREG_CLK_BITS (IREG_CLOCK_ENAB_7 | IREG_CLOCK_ENAB_5)
131 131
132#define MKCLOCK_REG_OFFSET (MK48T02_CLKOFF + MK48TXX_ICSR) 132#define MKCLOCK_REG_OFFSET (MK48T02_CLKOFF + MK48TXX_ICSR)
133 133
134/* 134/*
135 * Only one of these two variables should be non-zero after 135 * Only one of these two variables should be non-zero after
136 * autoconfiguration determines which clock we have. 136 * autoconfiguration determines which clock we have.
137 */ 137 */
138static volatile void *intersil_va; 138static volatile void *intersil_va;
139static volatile void *mostek_clk_va; 139static volatile void *mostek_clk_va;
140 140
141void _isr_clock(void); /* in locore.s */ 141void _isr_clock(void); /* in locore.s */
142void clock_intr(struct clockframe); 142void clock_intr(struct clockframe);
143 143
144 144
145static int clock_match(device_t, cfdata_t, void *); 145static int clock_match(device_t, cfdata_t, void *);
146static void clock_attach(device_t, device_t, void *); 146static void clock_attach(device_t, device_t, void *);
147 147
148CFATTACH_DECL_NEW(clock, sizeof(struct mk48txx_softc), 148CFATTACH_DECL_NEW(clock, sizeof(struct mk48txx_softc),
149 clock_match, clock_attach, NULL, NULL); 149 clock_match, clock_attach, NULL, NULL);
150 150
151#ifdef SUN3_470 151#ifdef SUN3_470
152 152
153#define intersil_clock ((volatile struct intersil7170 *)intersil_va) 153#define intersil_clock ((volatile struct intersil7170 *)intersil_va)
154 154
155#define intersil_clear() (void)intersil_clock->clk_intr_reg 155#define intersil_clear() (void)intersil_clock->clk_intr_reg
156 156
157static int oclock_match(device_t, cfdata_t, void *); 157static int oclock_match(device_t, cfdata_t, void *);
158static void oclock_attach(device_t, device_t, void *); 158static void oclock_attach(device_t, device_t, void *);
159 159
160CFATTACH_DECL_NEW(oclock, sizeof(struct intersil7170_softc), 160CFATTACH_DECL_NEW(oclock, sizeof(struct intersil7170_softc),
161 oclock_match, oclock_attach, NULL, NULL); 161 oclock_match, oclock_attach, NULL, NULL);
162 162
163 163
164/* 164/*
165 * Is there an intersil clock? 165 * Is there an intersil clock?
166 */ 166 */
167static int 167static int
168oclock_match(device_t parent, cfdata_t cf, void *aux) 168oclock_match(device_t parent, cfdata_t cf, void *aux)
169{ 169{
170 struct confargs *ca = aux; 170 struct confargs *ca = aux;
171 171
172 /* This driver only supports one unit. */ 172 /* This driver only supports one unit. */
173 if (intersil_va) 173 if (intersil_va)
174 return 0; 174 return 0;
175 175
176 /* 176 /*
177 * The 3/80 can not probe the Intersil absent, 177 * The 3/80 can not probe the Intersil absent,
178 * but it never has one, so "just say no." 178 * but it never has one, so "just say no."
179 */ 179 */
180 if (cpu_machine_id == ID_SUN3X_80) 180 if (cpu_machine_id == ID_SUN3X_80)
181 return 0; 181 return 0;
182 182
183 /* OK, really probe for the Intersil. */ 183 /* OK, really probe for the Intersil. */
184 if (bus_peek(ca->ca_bustype, ca->ca_paddr, 1) == -1) 184 if (bus_peek(ca->ca_bustype, ca->ca_paddr, 1) == -1)
185 return 0; 185 return 0;
186 186
187 /* Default interrupt priority. */ 187 /* Default interrupt priority. */
188 if (ca->ca_intpri == -1) 188 if (ca->ca_intpri == -1)
189 ca->ca_intpri = CLOCK_PRI; 189 ca->ca_intpri = CLOCK_PRI;
190 190
191 return 1; 191 return 1;
192} 192}
193 193
194/* 194/*
195 * Attach the intersil clock. 195 * Attach the intersil clock.
196 */ 196 */
197static void 197static void
198oclock_attach(device_t parent, device_t self, void *aux) 198oclock_attach(device_t parent, device_t self, void *aux)
199{ 199{
200 struct intersil7170_softc *sc = device_private(self); 200 struct intersil7170_softc *sc = device_private(self);
201 struct confargs *ca = aux; 201 struct confargs *ca = aux;
202 202
203 sc->sc_dev = self; 203 sc->sc_dev = self;
204 204
205 /* Get a mapping for it. */ 205 /* Get a mapping for it. */
206 sc->sc_bst = ca->ca_bustag; 206 sc->sc_bst = ca->ca_bustag;
207 if (bus_space_map(sc->sc_bst, ca->ca_paddr, sizeof(struct intersil7170), 207 if (bus_space_map(sc->sc_bst, ca->ca_paddr, sizeof(struct intersil7170),
208 0, &sc->sc_bsh) != 0) { 208 0, &sc->sc_bsh) != 0) {
209 aprint_error(": can't map registers\n"); 209 aprint_error(": can't map registers\n");
210 return; 210 return;
211 } 211 }
212 212
213 intersil_va = bus_space_vaddr(sc->sc_bst, sc->sc_bsh); 213 intersil_va = bus_space_vaddr(sc->sc_bst, sc->sc_bsh);
214 214
215#ifdef DIAGNOSTIC 215#ifdef DIAGNOSTIC
216 /* Verify correct probe order... */ 216 /* Verify correct probe order... */
217 if (mostek_clk_va) { 217 if (mostek_clk_va) {
218 mostek_clk_va = NULL; 218 mostek_clk_va = NULL;
219 aprint_normal("\n"); 219 aprint_normal("\n");
220 aprint_error_dev(self, "warning - mostek found also!\n"); 220 aprint_error_dev(self, "warning - mostek found also!\n");
221 } 221 }
222#endif 222#endif
223 223
224 /* 224 /*
225 * Set the clock to the correct interrupt rate, but 225 * Set the clock to the correct interrupt rate, but
226 * do not enable the interrupt until cpu_initclocks. 226 * do not enable the interrupt until cpu_initclocks.
227 * XXX: Actually, the interrupt_reg should be zero 227 * XXX: Actually, the interrupt_reg should be zero
228 * at this point, so the clock interrupts should not 228 * at this point, so the clock interrupts should not
229 * affect us, but we need to set the rate... 229 * affect us, but we need to set the rate...
230 */ 230 */
231 bus_space_write_1(sc->sc_bst, sc->sc_bsh, INTERSIL_ICMD, 231 bus_space_write_1(sc->sc_bst, sc->sc_bsh, INTERSIL_ICMD,
232 INTERSIL_COMMAND(INTERSIL_CMD_RUN, INTERSIL_CMD_IDISABLE)); 232 INTERSIL_COMMAND(INTERSIL_CMD_RUN, INTERSIL_CMD_IDISABLE));
233 (void)bus_space_read_1(sc->sc_bst, sc->sc_bsh, INTERSIL_IINTR); 233 (void)bus_space_read_1(sc->sc_bst, sc->sc_bsh, INTERSIL_IINTR);
234 234
235 /* Set the clock to 100 Hz, but do not enable it yet. */ 235 /* Set the clock to 100 Hz, but do not enable it yet. */
236 bus_space_write_1(sc->sc_bst, sc->sc_bsh, 236 bus_space_write_1(sc->sc_bst, sc->sc_bsh,
237 INTERSIL_IINTR, INTERSIL_INTER_CSECONDS); 237 INTERSIL_IINTR, INTERSIL_INTER_CSECONDS);
238 238
239 sc->sc_year0 = 1968; 239 sc->sc_year0 = 1968;
240 intersil7170_attach(sc); 240 intersil7170_attach(sc);
241 241
242 aprint_normal("\n"); 242 aprint_normal("\n");
243 243
244 /* 244 /*
245 * Can not hook up the ISR until cpu_initclocks() 245 * Can not hook up the ISR until cpu_initclocks()
246 * because hardclock is not ready until then. 246 * because hardclock is not ready until then.
247 * For now, the handler is _isr_autovec(), which 247 * For now, the handler is _isr_autovec(), which
248 * will complain if it gets clock interrupts. 248 * will complain if it gets clock interrupts.
249 */ 249 */
250} 250}
251#endif /* SUN3_470 */ 251#endif /* SUN3_470 */
252 252
253 253
254/* 254/*
255 * Is there a Mostek clock? Hard to tell... 255 * Is there a Mostek clock? Hard to tell...
256 * (See comment at top of this file.) 256 * (See comment at top of this file.)
257 */ 257 */
258static int 258static int
259clock_match(device_t parent, cfdata_t cf, void *args) 259clock_match(device_t parent, cfdata_t cf, void *args)
260{ 260{
261 struct confargs *ca = args; 261 struct confargs *ca = args;
262 262
263 /* This driver only supports one unit. */ 263 /* This driver only supports one unit. */
264 if (mostek_clk_va) 264 if (mostek_clk_va)
265 return 0; 265 return 0;
266 266
267 /* If intersil was found, use that. */ 267 /* If intersil was found, use that. */
268 if (intersil_va) 268 if (intersil_va)
269 return 0; 269 return 0;
270 /* Else assume a Mostek is there... */ 270 /* Else assume a Mostek is there... */
271 271
272 /* Default interrupt priority. */ 272 /* Default interrupt priority. */
273 if (ca->ca_intpri == -1) 273 if (ca->ca_intpri == -1)
274 ca->ca_intpri = CLOCK_PRI; 274 ca->ca_intpri = CLOCK_PRI;
275 275
276 return 1; 276 return 1;
277} 277}
278 278
279/* 279/*
280 * Attach the mostek clock. 280 * Attach the mostek clock.
281 */ 281 */
282static void 282static void
283clock_attach(device_t parent, device_t self, void *aux) 283clock_attach(device_t parent, device_t self, void *aux)
284{ 284{
285 struct mk48txx_softc *sc = device_private(self); 285 struct mk48txx_softc *sc = device_private(self);
286 struct confargs *ca = aux; 286 struct confargs *ca = aux;
287 287
288 sc->sc_dev = self; 288 sc->sc_dev = self;
289 sc->sc_bst = ca->ca_bustag; 289 sc->sc_bst = ca->ca_bustag;
290 if (bus_space_map(sc->sc_bst, ca->ca_paddr - MKCLOCK_REG_OFFSET, 290 if (bus_space_map(sc->sc_bst, ca->ca_paddr - MKCLOCK_REG_OFFSET,
291 MK48T02_CLKSZ, 0, &sc->sc_bsh) != 0) { 291 MK48T02_CLKSZ, 0, &sc->sc_bsh) != 0) {
292 aprint_error(": can't map device space\n"); 292 aprint_error(": can't map device space\n");
293 return; 293 return;
294 } 294 }
295 295
296 mostek_clk_va = bus_space_vaddr(sc->sc_bst, sc->sc_bsh); 296 mostek_clk_va = bus_space_vaddr(sc->sc_bst, sc->sc_bsh);
297 297
298 sc->sc_model = "mk48t02"; 298 sc->sc_model = "mk48t02";
299 sc->sc_year0 = 1968; 299 sc->sc_year0 = 1968;
300 300
301 mk48txx_attach(sc); 301 mk48txx_attach(sc);
302 302
303 aprint_normal("\n"); 303 aprint_normal("\n");
304} 304}
305 305
306/* 306/*
307 * Set and/or clear the desired clock bits in the interrupt 307 * Set and/or clear the desired clock bits in the interrupt
308 * register. We have to be extremely careful that we do it 308 * register. We have to be extremely careful that we do it
309 * in such a manner that we don't get ourselves lost. 309 * in such a manner that we don't get ourselves lost.
310 * XXX: Watch out! It's really easy to break this! 310 * XXX: Watch out! It's really easy to break this!
311 */ 311 */
312void 312void
313set_clk_mode(u_char on, u_char off, int enable_clk) 313set_clk_mode(u_char on, u_char off, int enable_clk)
314{ 314{
315 u_char interreg; 315 u_char interreg;
316 316
317 /* 317 /*
318 * If we have not yet mapped the register, 318 * If we have not yet mapped the register,
319 * then we do not want to do any of this... 319 * then we do not want to do any of this...
320 */ 320 */
321 if (!interrupt_reg) 321 if (!interrupt_reg)
322 return; 322 return;
323 323
324#ifdef DIAGNOSTIC 324#ifdef DIAGNOSTIC
325 /* Assertion: were are at splhigh! */ 325 /* Assertion: were are at splhigh! */
326 if ((getsr() & PSL_IPL) < PSL_IPL7) 326 if ((getsr() & PSL_IPL) < PSL_IPL7)
327 panic("set_clk_mode: bad ipl"); 327 panic("set_clk_mode: bad ipl");
328#endif 328#endif
329 329
330 /* 330 /*
331 * make sure that we are only playing w/ 331 * make sure that we are only playing w/
332 * clock interrupt register bits 332 * clock interrupt register bits
333 */ 333 */
334 on &= IREG_CLK_BITS; 334 on &= IREG_CLK_BITS;
335 off &= IREG_CLK_BITS; 335 off &= IREG_CLK_BITS;
336 336
337 /* First, turn off the "master" enable bit. */ 337 /* First, turn off the "master" enable bit. */
338 single_inst_bclr_b(*interrupt_reg, IREG_ALL_ENAB); 338 single_inst_bclr_b(*interrupt_reg, IREG_ALL_ENAB);
339 339
340 /* 340 /*
341 * Save the current interrupt register clock bits, 341 * Save the current interrupt register clock bits,
342 * and turn off/on the requested bits in the copy. 342 * and turn off/on the requested bits in the copy.
343 */ 343 */
344 interreg = *interrupt_reg & IREG_CLK_BITS; 344 interreg = *interrupt_reg & IREG_CLK_BITS;
345 interreg &= ~off; 345 interreg &= ~off;
346 interreg |= on; 346 interreg |= on;
347 347
348 /* Clear the CLK5 and CLK7 bits to clear the flip-flops. */ 348 /* Clear the CLK5 and CLK7 bits to clear the flip-flops. */
349 single_inst_bclr_b(*interrupt_reg, IREG_CLK_BITS); 349 single_inst_bclr_b(*interrupt_reg, IREG_CLK_BITS);
350 350
351#ifdef SUN3_470 351#ifdef SUN3_470
352 if (intersil_va) { 352 if (intersil_va) {
353 /* 353 /*
354 * Then disable clock interrupts, and read the clock's 354 * Then disable clock interrupts, and read the clock's
355 * interrupt register to clear any pending signals there. 355 * interrupt register to clear any pending signals there.
356 */ 356 */
357 intersil_clock->clk_cmd_reg = 357 intersil_clock->clk_cmd_reg =
358 INTERSIL_COMMAND(INTERSIL_CMD_RUN, INTERSIL_CMD_IDISABLE); 358 INTERSIL_COMMAND(INTERSIL_CMD_RUN, INTERSIL_CMD_IDISABLE);
359 intersil_clear(); 359 intersil_clear();
360 } 360 }
361#endif /* SUN3_470 */ 361#endif /* SUN3_470 */
362 362
363 /* Set the requested bits in the interrupt register. */ 363 /* Set the requested bits in the interrupt register. */
364 single_inst_bset_b(*interrupt_reg, interreg); 364 single_inst_bset_b(*interrupt_reg, interreg);
365 365
366#ifdef SUN3_470 366#ifdef SUN3_470
367 /* Turn the clock back on (maybe) */ 367 /* Turn the clock back on (maybe) */
368 if (intersil_va && enable_clk) 368 if (intersil_va && enable_clk)
369 intersil_clock->clk_cmd_reg = 369 intersil_clock->clk_cmd_reg =
370 INTERSIL_COMMAND(INTERSIL_CMD_RUN, INTERSIL_CMD_IENABLE); 370 INTERSIL_COMMAND(INTERSIL_CMD_RUN, INTERSIL_CMD_IENABLE);
371#endif /* SUN3_470 */ 371#endif /* SUN3_470 */
372 372
373 /* Finally, turn the "master" enable back on. */ 373 /* Finally, turn the "master" enable back on. */
374 single_inst_bset_b(*interrupt_reg, IREG_ALL_ENAB); 374 single_inst_bset_b(*interrupt_reg, IREG_ALL_ENAB);
375} 375}
376 376
377/* 377/*
378 * Set up the real-time clock (enable clock interrupts). 378 * Set up the real-time clock (enable clock interrupts).
379 * Leave stathz 0 since there is no secondary clock available. 379 * Leave stathz 0 since there is no secondary clock available.
380 * Note that clock interrupts MUST STAY DISABLED until here. 380 * Note that clock interrupts MUST STAY DISABLED until here.
381 */ 381 */
382void 382void
383cpu_initclocks(void) 383cpu_initclocks(void)
384{ 384{
385 int s; 385 int s;
386 386
387 s = splhigh(); 387 s = splhigh();
388 388
389 /* Install isr (in locore.s) that calls clock_intr(). */ 389 /* Install isr (in locore.s) that calls clock_intr(). */
390 isr_add_custom(CLOCK_PRI, (void *)_isr_clock); 390 isr_add_custom(CLOCK_PRI, (void *)_isr_clock);
391 391
392 /* Now enable the clock at level 5 in the interrupt reg. */ 392 /* Now enable the clock at level 5 in the interrupt reg. */
393 set_clk_mode(IREG_CLOCK_ENAB_5, 0, 1); 393 set_clk_mode(IREG_CLOCK_ENAB_5, 0, 1);
394 394
395 splx(s); 395 splx(s);
396} 396}
397 397
398/* 398/*
399 * This doesn't need to do anything, as we have only one timer and 399 * This doesn't need to do anything, as we have only one timer and
400 * profhz==stathz==hz. 400 * profhz==stathz==hz.
401 */ 401 */
402void 402void
403setstatclockrate(int newhz) 403setstatclockrate(int newhz)
404{ 404{
405 405
406 /* nothing */ 406 /* nothing */
407} 407}
408 408
409/* 409/*
410 * Clock interrupt handler (for both Intersil and Mostek). 410 * Clock interrupt handler (for both Intersil and Mostek).
411 * XXX - Is it worth the trouble to save a few cycles here 411 * XXX - Is it worth the trouble to save a few cycles here
412 * by making two separate interrupt handlers? 412 * by making two separate interrupt handlers?
413 * 413 *
414 * This is called by the "custom" interrupt handler. 414 * This is called by the "custom" interrupt handler.
415 * Note that we can get ZS interrupts while this runs, 415 * Note that we can get ZS interrupts while this runs,
416 * and zshard may touch the interrupt_reg, so we must 416 * and zshard may touch the interrupt_reg, so we must
417 * be careful to use the single_inst_* macros to modify 417 * be careful to use the single_inst_* macros to modify
418 * the interrupt register atomically. 418 * the interrupt register atomically.
419 */ 419 */
420void 420void
421clock_intr(struct clockframe cf) 421clock_intr(struct clockframe cf)
422{ 422{
423 extern char _Idle[]; /* locore.s */ 423 extern char _Idle[]; /* locore.s */
424 424
425 idepth++; 425 idepth++;
426 426
427#ifdef SUN3_470 427#ifdef SUN3_470
428 if (intersil_va) { 428 if (intersil_va) {
429 /* Read the clock interrupt register. */ 429 /* Read the clock interrupt register. */
430 intersil_clear(); 430 intersil_clear();
431 } 431 }
432#endif /* SUN3_470 */ 432#endif /* SUN3_470 */
433 433
434 /* Pulse the clock intr. enable low. */ 434 /* Pulse the clock intr. enable low. */
435 single_inst_bclr_b(*interrupt_reg, IREG_CLOCK_ENAB_5); 435 single_inst_bclr_b(*interrupt_reg, IREG_CLOCK_ENAB_5);
436 single_inst_bset_b(*interrupt_reg, IREG_CLOCK_ENAB_5); 436 single_inst_bset_b(*interrupt_reg, IREG_CLOCK_ENAB_5);
437 437
438#ifdef SUN3_470 438#ifdef SUN3_470
439 if (intersil_va) { 439 if (intersil_va) {
440 /* Read the clock intr. reg. AGAIN! */ 440 /* Read the clock intr. reg. AGAIN! */
441 intersil_clear(); 441 intersil_clear();
442 } 442 }
443#endif /* SUN3_470 */ 443#endif /* SUN3_470 */
444 444
445 intrcnt[CLOCK_PRI]++; 445 intrcnt[CLOCK_PRI]++;
446 curcpu()->ci_data.cpu_nintr++; 446 curcpu()->ci_data.cpu_nintr++;
447 447
448 /* Entertainment! */ 448 /* Entertainment! */
449 if (cf.cf_pc == (long)_Idle) 449 if (cf.cf_pc == (long)_Idle)
450 leds_intr(); 450 leds_intr();
451 451
452 /* Call common clock interrupt handler. */ 452 /* Call common clock interrupt handler. */
453 hardclock(&cf); 453 hardclock(&cf);
454 454
455 idepth--; 455 idepth--;
456} 456}