1 /* $NetBSD: mips_3x30.c,v 1.5 2001/03/30 23:51:14 wdk Exp $ */ 2 3 /* 4 * Copyright (c) 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Wayne Knowles 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 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 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 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 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 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 #include <sys/device.h> 42 #include <sys/proc.h> 43 #include <sys/kernel.h> 44 45 #include <machine/trap.h> 46 #include <machine/psl.h> 47 #include <machine/cpu.h> 48 #include <machine/intr.h> 49 #include <machine/mainboard.h> 50 #include <machine/sysconf.h> 51 52 extern void MachFPInterrupt (u_int, u_int, u_int, struct frame *); 53 54 /* Local functions */ 55 void pizazz_init (void); 56 void pizazz_intr (u_int, u_int, u_int, u_int); 57 int pizazz_level0_intr (void *); 58 void pizazz_level5_intr (int, int, int); 59 void pizazz_intr_establish (int, int (*)(void *), void *); 60 61 #define INT_MASK_FPU MIPS_INT_MASK_3 62 63 void 64 pizazz_init(void) 65 { 66 platform.iobus = "obio"; 67 platform.cons_init = NULL; 68 platform.iointr = pizazz_intr; 69 platform.intr_establish = pizazz_intr_establish; 70 71 pizazz_intr_establish(SYS_INTR_LEVEL0, pizazz_level0_intr, NULL); 72 73 strcpy(cpu_model, "Mips 3230 Magnum (Pizazz)"); 74 cpuspeed = 25; 75 } 76 77 #define HANDLE_INTR(intr, mask) \ 78 do { \ 79 if (ipending & (mask)) { \ 80 CALL_INTR(intr); \ 81 } \ 82 } while (0) 83 84 void 85 pizazz_intr(status, cause, pc, ipending) 86 u_int status; /* status register at time of the exception */ 87 u_int cause; /* cause register at time of exception */ 88 u_int pc; /* program counter where to continue */ 89 u_int ipending; 90 { 91 /* handle clock interrupts ASAP */ 92 if (ipending & MIPS_INT_MASK_2) { /* Timer Interrupt */ 93 void rambo_clkintr (struct clockframe *); 94 struct clockframe cf; 95 96 cf.pc = pc; 97 cf.sr = status; 98 99 rambo_clkintr(&cf); 100 101 /* keep clock interrupts enabled when we return */ 102 cause &= ~MIPS_INT_MASK_2; 103 } 104 105 /* If clock interrupts were enabled, re-enable them ASAP. */ 106 _splset(MIPS_SR_INT_IE | (status & MIPS_INT_MASK_2)); 107 108 if (ipending & MIPS_INT_MASK_5) /* level 5 interrupt */ 109 pizazz_level5_intr(pc, cause, status); 110 111 HANDLE_INTR(SYS_INTR_FDC, MIPS_INT_MASK_4); 112 HANDLE_INTR(SYS_INTR_SCSI, MIPS_INT_MASK_1); 113 HANDLE_INTR(SYS_INTR_LEVEL0, MIPS_INT_MASK_0); 114 115 /* XXX: Keep FDC interrupt masked off */ 116 cause &= ~(MIPS_INT_MASK_0 | MIPS_INT_MASK_1 | MIPS_INT_MASK_5); 117 118 _splset((status & ~cause & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE); 119 120 /* FPU nofiticaition */ 121 if (ipending & INT_MASK_FPU) { 122 if (!USERMODE(status)) 123 panic("kernel used FPU: PC %x, CR %x, SR %x", 124 pc, cause, status); 125 MachFPInterrupt(status, cause, pc, curproc->p_md.md_regs); 126 } 127 } 128 129 /* 130 * Level 0 interrupt handler 131 * 132 * Pizazz shares Lance, SCC, Expansion slot and Keyboard on level 0 133 * A secondary interrupt status register shows the real interrupt source 134 */ 135 int 136 pizazz_level0_intr(arg) 137 void *arg; 138 { 139 register int stat; 140 141 /* stat register is active low */ 142 stat = ~*(volatile u_char *)INTREG_0; 143 144 if (stat & INT_ExpSlot) 145 CALL_INTR(SYS_INTR_ATBUS); 146 147 if (stat & INT_Lance) 148 CALL_INTR(SYS_INTR_ETHER); 149 150 if (stat & INT_SCC) 151 CALL_INTR(SYS_INTR_SCC0); 152 153 return 0; 154 } 155 156 /* 157 * Motherboard Parity Error 158 */ 159 void 160 pizazz_level5_intr(pc, cause, status) 161 int pc; 162 int cause; 163 int status; 164 { 165 u_int32_t ereg; 166 167 ereg = *(u_int32_t *)RAMBO_ERREG; 168 169 printf("interrupt: pc=%p cr=%x sr=%x\n", (void *)pc, cause, status); 170 printf("parity error: %p mask: 0x%x\n", (void *)ereg, ereg & 0xf); 171 panic("memory fault"); 172 } 173 174 void 175 pizazz_intr_establish(level, func, arg) 176 int level; 177 int (*func) (void *); 178 void *arg; 179 { 180 if (level < 0 || level >= MAX_INTR_COOKIES) 181 panic("invalid interrupt level"); 182 183 if (intrtab[level].ih_fun != NULL) 184 panic("cannot share interrupt %d", level); 185 186 intrtab[level].ih_fun = func; 187 intrtab[level].ih_arg = arg; 188 } 189