vr.c revision 1.6 1 /* $NetBSD: vr.c,v 1.6 1999/11/28 10:59:06 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/vripreg.h>
56 #include <hpcmips/vr/rtcreg.h>
57 #include <hpcmips/hpcmips/machdep.h> /* XXXjrs replace with vectors */
58 #include <machine/bootinfo.h>
59
60 #include "vrdsu.h"
61 #if NVRDSU > 0
62 #include <hpcmips/vr/vrdsuvar.h>
63 #endif
64
65 #include "com.h"
66 #if NCOM > 0
67 #include <sys/termios.h>
68 #include <sys/ttydefaults.h>
69 #include <dev/ic/comreg.h>
70 #include <dev/ic/comvar.h>
71 #include <hpcmips/vr/siureg.h>
72 #include <hpcmips/vr/com_vripvar.h>
73 #ifndef CONSPEED
74 #define CONSPEED TTYDEF_SPEED
75 #endif
76 #endif
77
78 #include "fb.h"
79 #include "vrkiu.h"
80 #if NFB > 0 || NVRKIU > 0
81 #include <dev/rcons/raster.h>
82 #include <dev/wscons/wsdisplayvar.h>
83 #endif
84
85 #if NFB > 0
86 #include <arch/hpcmips/dev/fbvar.h>
87 #endif
88
89 #if NFB > 0
90 #include <arch/hpcmips/vr/vrkiuvar.h>
91 #endif
92
93 void vr_init __P((void));
94 void vr_os_init __P((void));
95 void vr_bus_reset __P((void));
96 int vr_intr __P((u_int32_t mask, u_int32_t pc, u_int32_t statusReg, u_int32_t causeReg));
97 void vr_cons_init __P((void));
98 void vr_device_register __P((struct device *, void *));
99 void vr_fb_init __P((caddr_t*));
100 int vr_mem_init __P((caddr_t));
101 void vr_reboot __P((int howto, char *bootstr));
102 void vr_powerdown __P((int howto, char *bootstr));
103
104 char *vrbcu_vrip_getcpuname __P((void));
105 int vrbcu_vrip_getcpumajor __P((void));
106 int vrbcu_vrip_getcpuminor __P((void));
107
108 extern unsigned nullclkread __P((void));
109 extern unsigned (*clkread) __P((void));
110
111 /*
112 * CPU interrupt dispatch table (HwInt[0:3])
113 */
114 int null_handler __P((void*, u_int32_t, u_int32_t));
115 static int (*intr_handler[4]) __P((void*, u_int32_t, u_int32_t)) =
116 {
117 null_handler,
118 null_handler,
119 null_handler,
120 null_handler
121 };
122 static void *intr_arg[4];
123
124 void
125 vr_init()
126 {
127 /*
128 * Platform Information.
129 */
130
131 /*
132 * Platform Specific Function Hooks
133 */
134 platform.os_init = vr_os_init;
135 platform.bus_reset = vr_bus_reset;
136 platform.cons_init = vr_cons_init;
137 platform.device_register = vr_device_register;
138 platform.fb_init = vr_fb_init;
139 platform.mem_init = vr_mem_init;
140 platform.reboot = vr_reboot;
141 platform.powerdown = vr_powerdown;
142
143 sprintf(cpu_model, "NEC %s rev%d.%d",
144 vrbcu_vrip_getcpuname(),
145 vrbcu_vrip_getcpumajor(),
146 vrbcu_vrip_getcpuminor());
147 }
148
149 int
150 vr_mem_init(kernend)
151 caddr_t kernend; /* kseg0 */
152 {
153 u_int32_t startaddr, endaddr, page;
154 int npage;
155 #define VR41_SYSADDR_DRAMSTART 0x0
156 #define VR41_SYSADDR_DRAM_LEN 0x04000000
157 startaddr = MIPS_PHYS_TO_KSEG1(
158 (btoc((u_int32_t)kernend - MIPS_KSEG0_START)) << PGSHIFT);
159 endaddr = MIPS_PHYS_TO_KSEG1(VR41_SYSADDR_DRAMSTART +
160 VR41_SYSADDR_DRAM_LEN);
161 for(page = startaddr, npage = 0; page < endaddr;
162 page+= NBPG, npage++) {
163 if (badaddr((char*)page, 4))
164 break;
165 ((volatile int *)page)[0] = 0xa5a5a5a5;
166 ((volatile int *)page)[4] = 0x5a5a5a5a;
167 wbflush();
168 if (*(volatile int *)page != 0xa5a5a5a5)
169 break;
170 }
171 /* Clear currently unused D-RAM area (For reboot Windows CE clearly)*/
172 memset((void*)startaddr, 0, npage * NBPG);
173 memset((void*)(KERNBASE + 0x400), 0, KERNTEXTOFF - KERNBASE - 0x800);
174
175 return npage;
176 }
177
178 void
179 vr_fb_init(kernend)
180 caddr_t *kernend;
181 {
182 /* Nothing to do */
183 }
184
185 void
186 vr_os_init()
187 {
188 /*
189 * Set up interrupt handling and I/O addresses.
190 */
191 mips_hardware_intr = vr_intr;
192
193 splvec.splbio = MIPS_SPL0;
194 splvec.splnet = MIPS_SPL0;
195 splvec.spltty = MIPS_SPL0;
196 splvec.splimp = MIPS_SPL0;
197 splvec.splclock = MIPS_SPL_0_1;
198 splvec.splstatclock = MIPS_SPL_0_1;
199
200 /* no high resolution timer circuit; possibly never called */
201 clkread = nullclkread;
202
203 #ifdef NOT_YET
204 mcclock_addr = (volatile struct chiptime *)
205 MIPS_PHYS_TO_KSEG1(Vr_SYS_CLOCK);
206 mc_cpuspeed(mcclock_addr, MIPS_INT_MASK_1);
207 #else
208 printf("%s(%d): cpuspeed estimation is notimplemented\n",
209 __FILE__, __LINE__);
210 #endif
211 #ifdef HPCMIPS_L1CACHE_DISABLE
212 cpuspeed = 1; /* XXX, CPU is very very slow because L1 cache is */
213 /* disabled. */
214 #endif /* HPCMIPS_L1CAHCE_DISABLE */
215 }
216
217
218 /*
219 * Initalize the memory system and I/O buses.
220 */
221 void
222 vr_bus_reset()
223 {
224 printf("%s(%d): vr_bus_reset() not implemented.\n",
225 __FILE__, __LINE__);
226 }
227
228 void
229 vr_cons_init()
230 {
231 #if NCOM > 0 || NFB > 0 || NVRKIU > 0
232 extern bus_space_tag_t system_bus_iot;
233 extern bus_space_tag_t mb_bus_space_init __P((void));
234 #endif
235
236 #if NCOM > 0
237 if (bootinfo->bi_cnuse & BI_CNUSE_SERIAL) {
238 /* Serial console */
239 mb_bus_space_init(); /* At this time, not initialized yet */
240 if(com_vrip_cnattach(system_bus_iot, 0x0c000000, CONSPEED,
241 VRCOM_FREQ,
242 (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8)) {
243 printf("%s(%d): can't init serial console", __FILE__, __LINE__);
244 } else {
245 return;
246 }
247 }
248 #endif
249
250 #if NFB > 0
251 mb_bus_space_init(); /* At this time, not initialized yet */
252 if(fb_cnattach(system_bus_iot, 0x0c000000, 0, 0)) {
253 printf("%s(%d): can't init fb console", __FILE__, __LINE__);
254 } else {
255 goto find_keyboard;
256 }
257 #endif
258
259 find_keyboard:
260 #if NVRKIU > 0
261 if (vrkiu_cnattach(system_bus_iot, VRIP_KIU_ADDR)) {
262 printf("%s(%d): can't init vrkiu as console",
263 __FILE__, __LINE__);
264 } else {
265 return;
266 }
267 #endif
268 }
269
270 void
271 vr_device_register(dev, aux)
272 struct device *dev;
273 void *aux;
274 {
275 printf("%s(%d): vr_device_register() not implemented.\n",
276 __FILE__, __LINE__);
277 panic("abort");
278 }
279
280 void
281 vr_reboot(howto, bootstr)
282 int howto;
283 char *bootstr;
284 {
285 splhigh();
286 if ( !(howto & RB_HALT)) {
287 #if NVRDSU
288 vrdsu_reset();
289 #else
290 printf("%s(%d): There is no DSU.", __FILE__, __LINE__);
291 #endif
292 }
293 while (1) {
294 __asm(".word 0x42000021");/* STANDBY */
295 __asm("nop");
296 __asm("nop");
297 __asm("nop");
298 __asm("nop");
299 __asm("nop");
300 }
301 }
302
303 void
304 vr_powerdown(howto, bootstr)
305 int howto;
306 char *bootstr;
307 {
308 printf("fake powerdown\n");
309 __asm(".word 0x42000023");/* HIBERNATE */
310 __asm("nop");
311 __asm("nop");
312 __asm("nop");
313 __asm("nop");
314 __asm("nop");
315 vr_reboot(howto&~RB_HALT, bootstr);
316 }
317
318 void *
319 vr_intr_establish(line, ih_fun, ih_arg)
320 int line;
321 int (*ih_fun) __P((void*, u_int32_t, u_int32_t));
322 void *ih_arg;
323 {
324 if (intr_handler[line] != null_handler) {
325 panic("vr_intr_establish: can't establish duplicated intr handler.");
326 }
327 intr_handler[line] = ih_fun;
328 intr_arg[line] = ih_arg;
329
330 return (void*)line;
331 }
332
333
334 void
335 vr_intr_disestablish(ih)
336 void *ih;
337 {
338 int line = (int)ih;
339 intr_handler[line] = null_handler;
340 intr_arg[line] = NULL;
341 }
342
343 int
344 null_handler(arg, pc, statusReg)
345 void *arg;
346 u_int32_t pc;
347 u_int32_t statusReg;
348 {
349 printf("null_handler\n");
350 return 0;
351 }
352
353 /*
354 * Handle interrupts.
355 */
356 int
357 vr_intr(mask, pc, status, cause)
358 u_int32_t mask;
359 u_int32_t pc;
360 u_int32_t status;
361 u_int32_t cause;
362 {
363 int hwintr;
364
365 hwintr = (ffs(mask >> 10) -1) & 0x3;
366 (*intr_handler[hwintr])(intr_arg[hwintr], pc, status);
367 return (MIPS_SR_INT_IE | (status & ~cause & MIPS_HARD_INT_MASK));
368 }
369