1 /* $NetBSD: autoconf.c,v 1.29 2017/05/22 16:59:32 ragge Exp $ */ 2 /* 3 * Copyright (c) 1994, 1998 Ludd, University of Lule}, Sweden. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 /* All bugs are subject to removal without further notice */ 28 29 30 31 #include <sys/param.h> 32 33 #include <lib/libsa/stand.h> 34 #include <lib/libsa/net.h> 35 36 #include "../include/mtpr.h" 37 #include "../include/sid.h" 38 #include "../include/intr.h" 39 #include "../include/rpb.h" 40 #include "../include/scb.h" 41 42 #include "vaxstand.h" 43 44 void autoconf(void); 45 void findcpu(void); 46 void consinit(void); 47 void scbinit(void); 48 void scb_stray(void *); 49 void longjmp(int *, int); 50 void rtimer(void *); 51 52 long *bootregs; 53 54 /* 55 * Do some initial setup. Also create a fake RPB for net-booted machines 56 * that don't have an in-prom VMB. 57 */ 58 59 void 60 autoconf(void) 61 { 62 int copyrpb = 1; 63 int fromnet = (bootregs[12] != -1); 64 65 findcpu(); /* Configures CPU variables */ 66 consinit(); /* Allow us to print out things */ 67 scbinit(); /* Fix interval clock etc */ 68 69 #ifdef DEV_DEBUG 70 printf("Register contents:\n"); 71 for (copyrpb = 0; copyrpb < 13; copyrpb++) 72 printf("r%d: %lx\n", copyrpb, bootregs[copyrpb]); 73 #endif 74 switch (vax_boardtype) { 75 76 case VAX_BTYP_780: 77 case VAX_BTYP_790: 78 case VAX_BTYP_8000: 79 case VAX_BTYP_9CC: 80 case VAX_BTYP_9RR: 81 case VAX_BTYP_1202: 82 if (fromnet == 0) 83 break; 84 copyrpb = 0; 85 bootrpb.devtyp = bootregs[0]; 86 bootrpb.adpphy = bootregs[1]; 87 bootrpb.csrphy = bootregs[2]; 88 bootrpb.unit = bootregs[3]; 89 bootrpb.rpb_bootr5 = bootregs[5]; 90 bootrpb.pfncnt = 0; 91 break; 92 93 case VAX_BTYP_46: 94 case VAX_BTYP_48: 95 {int *map, i; 96 97 /* Map all 16MB of I/O space to low 16MB of memory */ 98 map = (int *)0x700000; /* XXX */ 99 *(int *)0x20080008 = (int)map; /* XXX */ 100 for (i = 0; i < 0x8000; i++) 101 map[i] = 0x80000000 | i; 102 }break; 103 104 break; 105 } 106 107 if (copyrpb) { 108 struct rpb *prpb = (struct rpb *)bootregs[11]; 109 memcpy(&bootrpb, (void *)prpb, sizeof(struct rpb)); 110 if (prpb->iovec) { 111 bootrpb.iovec = (int)alloc(prpb->iovecsz); 112 memcpy((void *)bootrpb.iovec, (void *)prpb->iovec, 113 prpb->iovecsz); 114 } 115 } 116 } 117 118 /* 119 * Clock handling routines, needed to do timing in standalone programs. 120 */ 121 122 volatile int tickcnt; 123 124 satime_t 125 getsecs(void) 126 { 127 return tickcnt/100; 128 } 129 130 struct ivec_dsp **scb; 131 struct ivec_dsp *scb_vec; 132 extern struct ivec_dsp idsptch; 133 extern int jbuf[10]; 134 135 static void 136 mcheck(void *arg) 137 { 138 int off, *mfp = (int *)(void *)&arg; 139 140 off = (mfp[7]/4 + 8); 141 printf("Machine check, pc=%x, psl=%x\n", mfp[off], mfp[off+1]); 142 longjmp(jbuf, 1); 143 } 144 145 /* 146 * Init the SCB and set up a handler for all vectors in the lower space, 147 * to detect unwanted interrupts. 148 */ 149 void 150 scbinit(void) 151 { 152 int i, addr; 153 154 /* 155 * Allocate space. We need one page for the SCB, and 128*20 == 2.5k 156 * for the vectors. The SCB must be on a page boundary. 157 */ 158 i = (int)alloc(VAX_NBPG + 128*sizeof(scb_vec[0])) + VAX_PGOFSET; 159 i &= ~VAX_PGOFSET; 160 161 mtpr(i, PR_SCBB); 162 scb = (void *)i; 163 scb_vec = (struct ivec_dsp *)(i + VAX_NBPG); 164 165 for (i = 0; i < 128; i++) { 166 scb[i] = &scb_vec[i]; 167 addr = (int)scb[i]; 168 addr |= SCB_ISTACK; /* Only interrupt stack */ 169 scb[i] = (struct ivec_dsp*)addr; 170 scb_vec[i] = idsptch; 171 scb_vec[i].hoppaddr = scb_stray; 172 scb_vec[i].pushlarg = (void *) (i * 4); 173 scb_vec[i].ev = NULL; 174 } 175 scb_vec[0xc0/4].hoppaddr = rtimer; 176 scb_vec[4/4].hoppaddr = mcheck; 177 178 if (vax_boardtype != VAX_BTYP_VXT) 179 mtpr(-10000, PR_NICR); /* Load in count register */ 180 mtpr(0x800000d1, PR_ICCS); /* Start clock and enable interrupt */ 181 182 mtpr(20, PR_IPL); 183 } 184 185 extern int sluttid, senast, skip; 186 187 void 188 rtimer(void *arg) 189 { 190 mtpr(IPL_HIGH, PR_IPL); 191 tickcnt++; 192 mtpr(0xc1, PR_ICCS); 193 if (skip) 194 return; 195 if ((vax_boardtype == VAX_BTYP_46) || 196 (vax_boardtype == VAX_BTYP_48) || 197 (vax_boardtype == VAX_BTYP_49)) { 198 int nu = sluttid - getsecs(); 199 if (senast != nu) { 200 mtpr(20, PR_IPL); 201 longjmp(jbuf, 1); 202 } 203 } 204 } 205 206 #ifdef __ELF__ 207 #define IDSPTCH "idsptch" 208 #define EIDSPTCH "eidsptch" 209 #define CMN_IDSPTCH "cmn_idsptch" 210 #else 211 #define IDSPTCH "_idsptch" 212 #define EIDSPTCH "_eidsptch" 213 #define CMN_IDSPTCH "_cmn_idsptch" 214 #endif 215 216 __asm( 217 " .text;" 218 " .align 2;" 219 " .globl " IDSPTCH ", " EIDSPTCH ";" 220 IDSPTCH ":;" 221 " pushr $0x3f;" 222 " .word 0x9f16;" 223 " .long " CMN_IDSPTCH ";" 224 " .long 0;" 225 " .long 0;" 226 " .long 0;" 227 EIDSPTCH ":;" 228 229 CMN_IDSPTCH ":;" 230 " movl (%sp)+,%r0;" 231 " pushl 4(%r0);" 232 " calls $1,*(%r0);" 233 " popr $0x3f;" 234 " rei;" 235 ); 236 237 /* 238 * Stray interrupt handler. 239 * This function must _not_ save any registers (in the reg save mask). 240 */ 241 void 242 scb_stray(void *arg) 243 { 244 static int vector, ipl; 245 246 ipl = mfpr(PR_IPL); 247 vector = (int) arg; 248 printf("stray interrupt: vector 0x%x, ipl %d\n", vector, ipl); 249 } 250