Home | History | Annotate | Line # | Download | only in sgimips
      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
     83 cpu_match(device_t parent, cfdata_t cf, void *aux)
     84 {
     85 	return 1;
     86 }
     87 
     88 static void
     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
    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 *
    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
    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