xref: /netbsd-src/sys/arch/sgimips/sgimips/cpu.c (revision 42362de5c5d3e56bfb7cde4673410087cb67521c)
1 /*	$NetBSD: cpu.c,v 1.28 2022/03/03 06:27:03 riastradh Exp $	*/
2 
3 /*
4  * Copyright (c) 2000 Soren S. Jorvang
5  * Copyright (c) 2001 Jason R. Thorpe.
6  * Copyright (c) 2004 Christopher SEKIYA
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *          This product includes software developed for the
20  *          NetBSD Project.  See http://www.NetBSD.org/ for
21  *          information about NetBSD.
22  * 4. The name of the author may not be used to endorse or promote products
23  *    derived from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  */
36 
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.28 2022/03/03 06:27:03 riastradh Exp $");
39 
40 #include <sys/param.h>
41 #include <sys/device.h>
42 #include <sys/systm.h>
43 #include <sys/cpu.h>
44 
45 #include <uvm/uvm_extern.h>
46 
47 #include <machine/locore.h>
48 #include <machine/psl.h>
49 #include <machine/autoconf.h>
50 #include <machine/machtype.h>
51 #include <machine/sysconf.h>
52 
53 #include <dev/arcbios/arcbios.h>
54 #include <dev/arcbios/arcbiosvar.h>
55 
56 static int	cpu_match(device_t, cfdata_t, void *);
57 static void	cpu_attach(device_t, device_t, void *);
58 void		cpu_intr(int, vaddr_t, uint32_t);
59 void		*cpu_intr_establish(int, int, int (*func)(void *), void *);
60 
61 static struct evcnt mips_int0_evcnt =
62 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "mips", "int 0");
63 
64 static struct evcnt mips_int1_evcnt =
65 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "mips", "int 1");
66 
67 static struct evcnt mips_int2_evcnt =
68 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "mips", "int 2");
69 
70 static struct evcnt mips_int3_evcnt =
71 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "mips", "int 3");
72 
73 static struct evcnt mips_int4_evcnt =
74 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "mips", "int 4");
75 
76 static struct evcnt mips_int5_evcnt =
77 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "mips", "int 5");
78 
79 CFATTACH_DECL_NEW(cpu, 0,
80     cpu_match, cpu_attach, NULL, NULL);
81 
82 static int
cpu_match(device_t parent,cfdata_t cf,void * aux)83 cpu_match(device_t parent, cfdata_t cf, void *aux)
84 {
85 	return 1;
86 }
87 
88 static void
cpu_attach(device_t parent,device_t self,void * aux)89 cpu_attach(device_t parent, device_t self, void *aux)
90 {
91 	struct cpu_info * const ci = curcpu();
92 
93 	ci->ci_dev = self;
94 	device_set_private(self, ci);
95 
96 	aprint_normal(": ");
97 	cpu_identify(self);
98 }
99 
100 /*
101  * NB: Do not re-enable interrupts here -- reentrancy here can cause all
102  * sorts of Bad Things(tm) to happen, including kernel stack overflows.
103  */
104 void
cpu_intr(int ppl,vaddr_t pc,uint32_t status)105 cpu_intr(int ppl, vaddr_t pc, uint32_t status)
106 {
107 	uint32_t pending;
108 	int ipl;
109 
110 	curcpu()->ci_data.cpu_nintr++;
111 
112 #if !defined(__mips_o32)
113 	KASSERTMSG(mips_cp0_status_read() & MIPS_SR_KX,
114 	           "pc %"PRIxVADDR ", status %x\n", pc, status);
115 #endif
116 
117 	(void)(*platform.watchdog_reset)();
118 
119 	while (ppl < (ipl = splintr(&pending))) {
120 		splx(ipl);		/* enable interrupts */
121 
122         	if (pending & MIPS_INT_MASK_5) {
123                		(void)(*platform.intr5)(pc, status, pending);
124 			mips_int5_evcnt.ev_count++;
125         	}
126 
127 		if (pending & MIPS_INT_MASK_4) {
128                		(void)(*platform.intr4)(pc, status, pending);
129 			mips_int4_evcnt.ev_count++;
130 		}
131 
132 		if (pending & MIPS_INT_MASK_3) {
133                		(void)(*platform.intr3)(pc, status, pending);
134 			mips_int3_evcnt.ev_count++;
135 		}
136 
137 	        if (pending & MIPS_INT_MASK_2) {
138                		(void)(*platform.intr2)(pc, status, pending);
139 			mips_int2_evcnt.ev_count++;
140 		}
141 
142 		if (pending & MIPS_INT_MASK_1) {
143                		(void)(*platform.intr1)(pc, status, pending);
144 			mips_int1_evcnt.ev_count++;
145 		}
146 
147 		if (pending & MIPS_INT_MASK_0) {
148                		(void)(*platform.intr0)(pc, status, pending);
149 			mips_int0_evcnt.ev_count++;
150 		}
151 		(void)splhigh();
152 	}
153 }
154 
155 void *
cpu_intr_establish(int level,int ipl,int (* func)(void *),void * arg)156 cpu_intr_establish(int level, int ipl, int (*func)(void *), void *arg)
157 {
158 	(*platform.intr_establish)(level, ipl, func, arg);
159 	return (void *) -1;
160 }
161 
162 #ifdef MIPS1
163 void
mips1_fpu_intr(vaddr_t pc,uint32_t status,uint32_t pending)164 mips1_fpu_intr(vaddr_t pc, uint32_t status, uint32_t pending)
165 {
166 	if (!USERMODE(status))
167 		panic("kernel used FPU: PC 0x%08x, SR 0x%08x",
168 		    pc, status);
169 
170 #if !defined(NOFPU) && !defined(FPEMUL)
171 	mips_fpu_intr(pc, curlwp->l_md.md_utf);
172 #endif
173 }
174 #endif
175