autoconf.c revision 1.29 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