vr.c revision 1.12 1 /* $NetBSD: vr.c,v 1.12 2000/02/10 02:15:03 sato Exp $ */
2
3 /*-
4 * Copyright (c) 1999
5 * Shin Takemura and PocketBSD Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the PocketBSD project
18 * and its contributors.
19 * 4. Neither the name of the project nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 */
36 #include <sys/param.h>
37 #include <sys/types.h>
38 #include <sys/systm.h>
39 #include <sys/device.h>
40 #include <sys/reboot.h>
41
42 #include <machine/cpu.h>
43 #include <machine/intr.h>
44 #include <machine/reg.h>
45 #include <machine/psl.h>
46 #include <machine/locore.h>
47 #include <machine/sysconf.h>
48 #include <machine/bus.h>
49 #include <machine/autoconf.h>
50
51 #include <mips/mips_param.h> /* hokey spl()s */
52 #include <mips/mips/mips_mcclock.h> /* mcclock CPUspeed estimation */
53
54 #include <hpcmips/vr/vr.h>
55 #include <hpcmips/vr/vr_asm.h>
56 #include <hpcmips/vr/vripreg.h>
57 #include <hpcmips/vr/rtcreg.h>
58 #include <hpcmips/hpcmips/machdep.h> /* cpu_name */
59 #include <machine/bootinfo.h>
60
61 #include "vrip.h"
62 #if NVRIP > 0
63 #include <hpcmips/vr/vripvar.h>
64 #endif
65
66 #include "vrbcu.h"
67 #if NVRBCU > 0
68 #include <hpcmips/vr/bcuvar.h>
69 #endif
70
71 #include "vrdsu.h"
72 #if NVRDSU > 0
73 #include <hpcmips/vr/vrdsuvar.h>
74 #endif
75
76 #include "com.h"
77 #if NCOM > 0
78 #include <sys/termios.h>
79 #include <sys/ttydefaults.h>
80 #include <dev/ic/comreg.h>
81 #include <dev/ic/comvar.h>
82 #include <hpcmips/vr/siureg.h>
83 #include <hpcmips/vr/com_vripvar.h>
84 #ifndef CONSPEED
85 #define CONSPEED TTYDEF_SPEED
86 #endif
87 #endif
88
89 #include "fb.h"
90 #include "vrkiu.h"
91 #if NFB > 0 || NVRKIU > 0
92 #include <dev/rcons/raster.h>
93 #include <dev/wscons/wsdisplayvar.h>
94 #endif
95
96 #if NFB > 0
97 #include <arch/hpcmips/dev/fbvar.h>
98 #endif
99
100 #if NFB > 0
101 #include <arch/hpcmips/vr/vrkiuvar.h>
102 #endif
103
104 void vr_init __P((void));
105 void vr_os_init __P((void));
106 void vr_bus_reset __P((void));
107 int vr_intr __P((u_int32_t mask, u_int32_t pc, u_int32_t statusReg, u_int32_t causeReg));
108 void vr_cons_init __P((void));
109 void vr_device_register __P((struct device *, void *));
110 void vr_fb_init __P((caddr_t*));
111 int vr_mem_init __P((caddr_t));
112 void vr_reboot __P((int howto, char *bootstr));
113
114 extern unsigned nullclkread __P((void));
115 extern unsigned (*clkread) __P((void));
116
117 /*
118 * CPU interrupt dispatch table (HwInt[0:3])
119 */
120 int null_handler __P((void*, u_int32_t, u_int32_t));
121 static int (*intr_handler[4]) __P((void*, u_int32_t, u_int32_t)) =
122 {
123 null_handler,
124 null_handler,
125 null_handler,
126 null_handler
127 };
128 static void *intr_arg[4];
129
130 void
131 vr_init()
132 {
133 /*
134 * Platform Information.
135 */
136
137 /*
138 * Platform Specific Function Hooks
139 */
140 platform.os_init = vr_os_init;
141 platform.bus_reset = vr_bus_reset;
142 platform.cons_init = vr_cons_init;
143 platform.device_register = vr_device_register;
144 platform.fb_init = vr_fb_init;
145 platform.mem_init = vr_mem_init;
146 platform.reboot = vr_reboot;
147
148 #if NVRBCU > 0
149 sprintf(cpu_name, "NEC %s rev%d.%d %d.%03dMHz",
150 vrbcu_vrip_getcpuname(),
151 vrbcu_vrip_getcpumajor(),
152 vrbcu_vrip_getcpuminor(),
153 vrbcu_vrip_getcpuclock() / 1000000,
154 (vrbcu_vrip_getcpuclock() % 1000000) / 1000);
155 #else
156 sprintf(cpu_name, "NEC VR41xx");
157 #endif
158 }
159
160 int
161 vr_mem_init(kernend)
162 caddr_t kernend; /* kseg0 */
163 {
164 u_int32_t startaddr, endaddr, page;
165 int npage;
166 #define VR41_SYSADDR_DRAMSTART 0x0
167 #define VR41_SYSADDR_DRAM_LEN 0x04000000
168 startaddr = MIPS_PHYS_TO_KSEG1(
169 (btoc((u_int32_t)kernend - MIPS_KSEG0_START)) << PGSHIFT);
170 endaddr = MIPS_PHYS_TO_KSEG1(VR41_SYSADDR_DRAMSTART +
171 VR41_SYSADDR_DRAM_LEN);
172 for(page = startaddr, npage = 0; page < endaddr;
173 page+= NBPG, npage++) {
174 if (badaddr((char*)page, 4))
175 break;
176 ((volatile int *)page)[0] = 0xa5a5a5a5;
177 ((volatile int *)page)[4] = 0x5a5a5a5a;
178 wbflush();
179 if (*(volatile int *)page != 0xa5a5a5a5)
180 break;
181 }
182 /* Clear currently unused D-RAM area (For reboot Windows CE clearly)*/
183 memset((void*)startaddr, 0, npage * NBPG);
184 memset((void*)(KERNBASE + 0x400), 0, KERNTEXTOFF - KERNBASE - 0x800);
185
186 return npage;
187 }
188
189 void
190 vr_fb_init(kernend)
191 caddr_t *kernend;
192 {
193 /* Nothing to do */
194 }
195
196 void
197 vr_os_init()
198 {
199 /*
200 * Set up interrupt handling and I/O addresses.
201 */
202 mips_hardware_intr = vr_intr;
203
204 splvec.splbio = MIPS_SPL0;
205 splvec.splnet = MIPS_SPL0;
206 splvec.spltty = MIPS_SPL0;
207 splvec.splimp = MIPS_SPL0;
208 splvec.splclock = MIPS_SPL_0_1;
209 splvec.splstatclock = MIPS_SPL_0_1;
210
211 /* no high resolution timer circuit; possibly never called */
212 clkread = nullclkread;
213
214 #ifdef NOT_YET
215 mcclock_addr = (volatile struct chiptime *)
216 MIPS_PHYS_TO_KSEG1(Vr_SYS_CLOCK);
217 mc_cpuspeed(mcclock_addr, MIPS_INT_MASK_1);
218 #else
219 printf("%s(%d): cpuspeed estimation is notimplemented\n",
220 __FILE__, __LINE__);
221 #endif
222 #ifdef HPCMIPS_L1CACHE_DISABLE
223 cpuspeed = 1; /* XXX, CPU is very very slow because L1 cache is */
224 /* disabled. */
225 #endif /* HPCMIPS_L1CAHCE_DISABLE */
226 }
227
228
229 /*
230 * Initalize the memory system and I/O buses.
231 */
232 void
233 vr_bus_reset()
234 {
235 printf("%s(%d): vr_bus_reset() not implemented.\n",
236 __FILE__, __LINE__);
237 }
238
239 void
240 vr_cons_init()
241 {
242 #if NCOM > 0 || NFB > 0 || NVRKIU > 0
243 extern bus_space_tag_t system_bus_iot;
244 extern bus_space_tag_t mb_bus_space_init __P((void));
245 #endif
246
247 #if NCOM > 0
248 if (bootinfo->bi_cnuse & BI_CNUSE_SERIAL) {
249 /* Serial console */
250 mb_bus_space_init(); /* At this time, not initialized yet */
251 if(com_vrip_cnattach(system_bus_iot, 0x0c000000, CONSPEED,
252 VRCOM_FREQ,
253 (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8)) {
254 printf("%s(%d): can't init serial console", __FILE__, __LINE__);
255 } else {
256 return;
257 }
258 }
259 #endif
260
261 #if NFB > 0
262 mb_bus_space_init(); /* At this time, not initialized yet */
263 if(fb_cnattach(system_bus_iot, 0x0c000000, 0, 0)) {
264 printf("%s(%d): can't init fb console", __FILE__, __LINE__);
265 } else {
266 goto find_keyboard;
267 }
268 #endif
269
270 find_keyboard:
271 #if NVRKIU > 0
272 if (vrkiu_cnattach(system_bus_iot, VRIP_KIU_ADDR)) {
273 printf("%s(%d): can't init vrkiu as console",
274 __FILE__, __LINE__);
275 } else {
276 return;
277 }
278 #endif
279 }
280
281 void
282 vr_device_register(dev, aux)
283 struct device *dev;
284 void *aux;
285 {
286 printf("%s(%d): vr_device_register() not implemented.\n",
287 __FILE__, __LINE__);
288 panic("abort");
289 }
290
291 void
292 vr_reboot(howto, bootstr)
293 int howto;
294 char *bootstr;
295 {
296 /*
297 * power down
298 */
299 if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
300 printf("fake powerdown\n");
301 __asm(__CONCAT(".word ",___STRING(VR_OPCODE_HIBERNATE)));
302 __asm("nop");
303 __asm("nop");
304 __asm("nop");
305 __asm("nop");
306 __asm("nop");
307 __asm(".set reorder");
308 /* not reach */
309 vr_reboot(howto&~RB_HALT, bootstr);
310 }
311 /*
312 * halt
313 */
314 if (howto & RB_HALT) {
315 #if NVRIP > 0
316 _spllower(~MIPS_INT_MASK_0);
317 vrip_intr_suspend();
318 #else
319 splhigh();
320 #endif
321 __asm(".set noreorder");
322 __asm(__CONCAT(".word ",___STRING(VR_OPCODE_SUSPEND)));
323 __asm("nop");
324 __asm("nop");
325 __asm("nop");
326 __asm("nop");
327 __asm("nop");
328 __asm(".set reorder");
329 #if NVRIP > 0
330 vrip_intr_resume();
331 #endif
332 }
333 /*
334 * reset
335 */
336 #if NVRDSU
337 vrdsu_reset();
338 #else
339 printf("%s(%d): There is no DSU.", __FILE__, __LINE__);
340 #endif
341 }
342
343 void *
344 vr_intr_establish(line, ih_fun, ih_arg)
345 int line;
346 int (*ih_fun) __P((void*, u_int32_t, u_int32_t));
347 void *ih_arg;
348 {
349 if (intr_handler[line] != null_handler) {
350 panic("vr_intr_establish: can't establish duplicated intr handler.");
351 }
352 intr_handler[line] = ih_fun;
353 intr_arg[line] = ih_arg;
354
355 return (void*)line;
356 }
357
358
359 void
360 vr_intr_disestablish(ih)
361 void *ih;
362 {
363 int line = (int)ih;
364 intr_handler[line] = null_handler;
365 intr_arg[line] = NULL;
366 }
367
368 int
369 null_handler(arg, pc, statusReg)
370 void *arg;
371 u_int32_t pc;
372 u_int32_t statusReg;
373 {
374 printf("null_handler\n");
375 return 0;
376 }
377
378 /*
379 * Handle interrupts.
380 */
381 int
382 vr_intr(mask, pc, status, cause)
383 u_int32_t mask;
384 u_int32_t pc;
385 u_int32_t status;
386 u_int32_t cause;
387 {
388 int hwintr;
389
390 hwintr = (ffs(mask >> 10) -1) & 0x3;
391 (*intr_handler[hwintr])(intr_arg[hwintr], pc, status);
392 return (MIPS_SR_INT_IE | (status & ~cause & MIPS_HARD_INT_MASK));
393 }
394