1*42391ab5Schristos /* $NetBSD: vr.c,v 1.65 2014/03/26 17:53:36 christos Exp $ */
2db2b0adeStakemura
3db2b0adeStakemura /*-
401b846e2Stakemura * Copyright (c) 1999-2002
5db2b0adeStakemura * Shin Takemura and PocketBSD Project. All rights reserved.
6db2b0adeStakemura *
7db2b0adeStakemura * Redistribution and use in source and binary forms, with or without
8db2b0adeStakemura * modification, are permitted provided that the following conditions
9db2b0adeStakemura * are met:
10db2b0adeStakemura * 1. Redistributions of source code must retain the above copyright
11db2b0adeStakemura * notice, this list of conditions and the following disclaimer.
12db2b0adeStakemura * 2. Redistributions in binary form must reproduce the above copyright
13db2b0adeStakemura * notice, this list of conditions and the following disclaimer in the
14db2b0adeStakemura * documentation and/or other materials provided with the distribution.
15db2b0adeStakemura * 3. All advertising materials mentioning features or use of this software
16db2b0adeStakemura * must display the following acknowledgement:
17db2b0adeStakemura * This product includes software developed by the PocketBSD project
18db2b0adeStakemura * and its contributors.
19db2b0adeStakemura * 4. Neither the name of the project nor the names of its contributors
20db2b0adeStakemura * may be used to endorse or promote products derived from this software
21db2b0adeStakemura * without specific prior written permission.
22db2b0adeStakemura *
23db2b0adeStakemura * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24db2b0adeStakemura * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25db2b0adeStakemura * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26db2b0adeStakemura * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27db2b0adeStakemura * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28db2b0adeStakemura * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29db2b0adeStakemura * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30db2b0adeStakemura * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31db2b0adeStakemura * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32db2b0adeStakemura * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33db2b0adeStakemura * SUCH DAMAGE.
34db2b0adeStakemura *
35db2b0adeStakemura */
366a9bbffcSuch
370c82163cSlukem #include <sys/cdefs.h>
38*42391ab5Schristos __KERNEL_RCSID(0, "$NetBSD: vr.c,v 1.65 2014/03/26 17:53:36 christos Exp $");
390c82163cSlukem
406a9bbffcSuch #include "opt_vr41xx.h"
416c1c0affSuch #include "opt_tx39xx.h"
42d84d2c6cSlukem #include "opt_kgdb.h"
43d84d2c6cSlukem
440351e901Smatt #define __INTR_PRIVATE
450351e901Smatt
46db2b0adeStakemura #include <sys/param.h>
47db2b0adeStakemura #include <sys/systm.h>
4862009df2Stakemura #include <sys/reboot.h>
49fb1e16b4Sad #include <sys/device.h>
50fb1e16b4Sad #include <sys/bus.h>
51bb929f4dSuebayasi #include <sys/cpu.h>
52db2b0adeStakemura
536c1c0affSuch #include <uvm/uvm_extern.h>
546c1c0affSuch
5569d0ae1dStsutsui #include <mips/cache.h>
5669d0ae1dStsutsui #include <mips/locore.h>
5769d0ae1dStsutsui
58db2b0adeStakemura #include <machine/sysconf.h>
5987a75cecSuch #include <machine/bootinfo.h>
601d1d5c87Stakemura #include <machine/bus_space_hpcmips.h>
6101b846e2Stakemura #include <machine/platid.h>
6201b846e2Stakemura #include <machine/platid_mask.h>
63db2b0adeStakemura
641c426d53Senami #include <dev/hpc/hpckbdvar.h>
651c426d53Senami
66db2b0adeStakemura #include <hpcmips/vr/vr.h>
67ae6160e2Stakemura #include <hpcmips/vr/vr_asm.h>
6812a0a0a5Ssato #include <hpcmips/vr/vrcpudef.h>
695a30c207Stakemura #include <hpcmips/vr/vripreg.h>
70db2b0adeStakemura #include <hpcmips/vr/rtcreg.h>
71db2b0adeStakemura
7238e50940Stakemura #include "vrip_common.h"
7338e50940Stakemura #if NVRIP_COMMON > 0
7421574acbStakemura #include <hpcmips/vr/vripvar.h>
7521574acbStakemura #endif
7621574acbStakemura
774765859dSsato #include "vrbcu.h"
784765859dSsato #if NVRBCU > 0
794765859dSsato #include <hpcmips/vr/bcuvar.h>
804765859dSsato #endif
814765859dSsato
8262009df2Stakemura #include "vrdsu.h"
8362009df2Stakemura #if NVRDSU > 0
8462009df2Stakemura #include <hpcmips/vr/vrdsuvar.h>
8562009df2Stakemura #endif
8662009df2Stakemura
87db2b0adeStakemura #include "com.h"
8801b846e2Stakemura #include "com_vrip.h"
8901b846e2Stakemura #include "com_hpcio.h"
9001b846e2Stakemura #if NCOM > 0
91db2b0adeStakemura #include <sys/termios.h>
92db2b0adeStakemura #include <sys/ttydefaults.h>
93db2b0adeStakemura #include <dev/ic/comreg.h>
94db2b0adeStakemura #include <dev/ic/comvar.h>
9501b846e2Stakemura #if NCOM_VRIP > 0
96db2b0adeStakemura #include <hpcmips/vr/siureg.h>
97db2b0adeStakemura #include <hpcmips/vr/com_vripvar.h>
98dce583bdStakemura #endif
9901b846e2Stakemura #if NCOM_HPCIO > 0
10001b846e2Stakemura #include <hpcmips/dev/com_hpciovar.h>
101dce583bdStakemura #endif
102db2b0adeStakemura #ifndef CONSPEED
103db2b0adeStakemura #define CONSPEED TTYDEF_SPEED
104db2b0adeStakemura #endif
105db2b0adeStakemura #endif
106db2b0adeStakemura
107e9619d5dStakemura #include "hpcfb.h"
1085a30c207Stakemura #include "vrkiu.h"
1091898d1dcSenami #if (NVRKIU > 0) || (NHPCFB > 0)
1105a30c207Stakemura #include <dev/wscons/wsdisplayvar.h>
111e9619d5dStakemura #include <dev/rasops/rasops.h>
1125a30c207Stakemura #endif
1135a30c207Stakemura
114e9619d5dStakemura #if NHPCFB > 0
115659f65e0Such #include <dev/hpc/hpcfbvar.h>
1165a30c207Stakemura #endif
1175a30c207Stakemura
118e9619d5dStakemura #if NVRKIU > 0
1191c426d53Senami #include <arch/hpcmips/vr/vrkiureg.h>
1205a30c207Stakemura #include <arch/hpcmips/vr/vrkiuvar.h>
1215a30c207Stakemura #endif
1225a30c207Stakemura
1236c1c0affSuch #ifdef DEBUG
1246c1c0affSuch #define STATIC
1256c1c0affSuch #else
1266c1c0affSuch #define STATIC static
1276c1c0affSuch #endif
1286c1c0affSuch
1296c1c0affSuch /*
1306c1c0affSuch * This is a mask of bits to clear in the SR when we go to a
1316c1c0affSuch * given interrupt priority level.
1326c1c0affSuch */
1330351e901Smatt const struct ipl_sr_map __ipl_sr_map_vr = {
1340351e901Smatt .sr_bits = {
1350351e901Smatt [IPL_NONE] = 0,
1360351e901Smatt [IPL_SOFTCLOCK] = MIPS_SOFT_INT_MASK_0,
1370351e901Smatt [IPL_SOFTNET] = MIPS_SOFT_INT_MASK,
1380351e901Smatt [IPL_VM] = MIPS_SOFT_INT_MASK
1390351e901Smatt | MIPS_INT_MASK_0,
1400351e901Smatt [IPL_SCHED] = MIPS_SOFT_INT_MASK
1410351e901Smatt | MIPS_INT_MASK_0
1420351e901Smatt | MIPS_INT_MASK_1,
1430351e901Smatt [IPL_DDB] = MIPS_INT_MASK,
144dbcedb79Stsutsui [IPL_HIGH] = MIPS_INT_MASK,
1450351e901Smatt },
1466c1c0affSuch };
1476c1c0affSuch
1486c1c0affSuch #if defined(VR41XX) && defined(TX39XX)
1496c1c0affSuch #define VR_INTR vr_intr
1506c1c0affSuch #else
1516c1c0affSuch #define VR_INTR cpu_intr /* locore_mips3 directly call this */
1526c1c0affSuch #endif
1536c1c0affSuch
154961880b5Such void vr_init(void);
1550351e901Smatt void VR_INTR(int, vaddr_t, uint32_t);
1566c1c0affSuch extern void vr_idle(void);
1576c1c0affSuch STATIC void vr_cons_init(void);
15853524e44Schristos STATIC void vr_fb_init(void **);
1596c1c0affSuch STATIC void vr_mem_init(paddr_t);
1606c1c0affSuch STATIC void vr_find_dram(paddr_t, paddr_t);
1616c1c0affSuch STATIC void vr_reboot(int, char *);
162db2b0adeStakemura
163db2b0adeStakemura /*
164db2b0adeStakemura * CPU interrupt dispatch table (HwInt[0:3])
165db2b0adeStakemura */
1660351e901Smatt STATIC int vr_null_handler(void *, uint32_t, uint32_t);
16784116228Stsutsui STATIC int (*vr_intr_handler[4])(void *, vaddr_t, uint32_t) =
168db2b0adeStakemura {
1696c1c0affSuch vr_null_handler,
1706c1c0affSuch vr_null_handler,
1716c1c0affSuch vr_null_handler,
1726c1c0affSuch vr_null_handler
173db2b0adeStakemura };
1746c1c0affSuch STATIC void *vr_intr_arg[4];
175db2b0adeStakemura
17601b846e2Stakemura #if NCOM > 0
17701b846e2Stakemura /*
17801b846e2Stakemura * machine dependent serial console info
17901b846e2Stakemura */
18001b846e2Stakemura static struct vr_com_platdep {
18101b846e2Stakemura platid_mask_t *platidmask;
18201b846e2Stakemura int (*attach)(bus_space_tag_t, int, int, int, tcflag_t, int);
18301b846e2Stakemura int addr;
18401b846e2Stakemura int freq;
18501b846e2Stakemura } platdep_com_table[] = {
18601b846e2Stakemura #if NCOM_HPCIO > 0
18701b846e2Stakemura {
18801b846e2Stakemura &platid_mask_MACH_NEC_MCR_SIGMARION2,
18901b846e2Stakemura com_hpcio_cndb_attach, /* attach proc */
19001b846e2Stakemura 0x0b600000, /* base address */
19101b846e2Stakemura COM_FREQ, /* frequency */
19201b846e2Stakemura },
19301b846e2Stakemura #endif
19401b846e2Stakemura #if NCOM_VRIP > 0
195b38c9632Stakemura #ifdef VR4102
196b38c9632Stakemura {
197b38c9632Stakemura &platid_mask_CPU_MIPS_VR_4102,
198b38c9632Stakemura com_vrip_cndb_attach, /* attach proc */
199b38c9632Stakemura VR4102_SIU_ADDR, /* base address */
200b38c9632Stakemura VRCOM_FREQ, /* frequency */
201b38c9632Stakemura },
202b38c9632Stakemura #endif /* VR4102 */
203b38c9632Stakemura #ifdef VR4111
204b38c9632Stakemura {
205b38c9632Stakemura &platid_mask_CPU_MIPS_VR_4111,
206b38c9632Stakemura com_vrip_cndb_attach, /* attach proc */
207b38c9632Stakemura VR4102_SIU_ADDR, /* base address */
208b38c9632Stakemura VRCOM_FREQ, /* frequency */
209b38c9632Stakemura },
210b38c9632Stakemura #endif /* VR4111 */
211b38c9632Stakemura #ifdef VR4121
212b38c9632Stakemura {
213b38c9632Stakemura &platid_mask_CPU_MIPS_VR_4121,
214b38c9632Stakemura com_vrip_cndb_attach, /* attach proc */
215b38c9632Stakemura VR4102_SIU_ADDR, /* base address */
216b38c9632Stakemura VRCOM_FREQ, /* frequency */
217b38c9632Stakemura },
218b38c9632Stakemura #endif /* VR4121 */
219b38c9632Stakemura #ifdef VR4122
220b38c9632Stakemura {
221b38c9632Stakemura &platid_mask_CPU_MIPS_VR_4122,
222b38c9632Stakemura com_vrip_cndb_attach, /* attach proc */
223b38c9632Stakemura VR4122_SIU_ADDR, /* base address */
224b38c9632Stakemura VRCOM_FREQ, /* frequency */
225b38c9632Stakemura },
226b38c9632Stakemura #endif /* VR4122 */
227b38c9632Stakemura #ifdef VR4131
228b38c9632Stakemura {
229b38c9632Stakemura &platid_mask_CPU_MIPS_VR_4122,
230b38c9632Stakemura com_vrip_cndb_attach, /* attach proc */
231b38c9632Stakemura VR4122_SIU_ADDR, /* base address */
232b38c9632Stakemura VRCOM_FREQ, /* frequency */
233b38c9632Stakemura },
234b38c9632Stakemura #endif /* VR4131 */
235b38c9632Stakemura #ifdef SINGLE_VRIP_BASE
23601b846e2Stakemura {
23701b846e2Stakemura &platid_wild,
23801b846e2Stakemura com_vrip_cndb_attach, /* attach proc */
23901b846e2Stakemura VRIP_SIU_ADDR, /* base address */
24001b846e2Stakemura VRCOM_FREQ, /* frequency */
24101b846e2Stakemura },
242b38c9632Stakemura #endif /* SINGLE_VRIP_BASE */
243b38c9632Stakemura #else /* NCOM_VRIP > 0 */
24401b846e2Stakemura /* dummy */
24501b846e2Stakemura {
24601b846e2Stakemura &platid_wild,
24701b846e2Stakemura NULL, /* attach proc */
24801b846e2Stakemura 0, /* base address */
24901b846e2Stakemura 0, /* frequency */
25001b846e2Stakemura },
251b38c9632Stakemura #endif /* NCOM_VRIP > 0 */
25201b846e2Stakemura };
25301b846e2Stakemura #endif /* NCOM > 0 */
25401b846e2Stakemura
25547c249a1Stakemura #if NVRKIU > 0
25647c249a1Stakemura /*
25747c249a1Stakemura * machine dependent keyboard info
25847c249a1Stakemura */
25947c249a1Stakemura static struct vr_kiu_platdep {
26047c249a1Stakemura platid_mask_t *platidmask;
26147c249a1Stakemura int addr;
26247c249a1Stakemura } platdep_kiu_table[] = {
26347c249a1Stakemura #ifdef VR4102
26447c249a1Stakemura {
26547c249a1Stakemura &platid_mask_CPU_MIPS_VR_4102,
26647c249a1Stakemura VR4102_KIU_ADDR, /* base address */
26747c249a1Stakemura },
26847c249a1Stakemura #endif /* VR4102 */
26947c249a1Stakemura #ifdef VR4111
27047c249a1Stakemura {
27147c249a1Stakemura &platid_mask_CPU_MIPS_VR_4111,
27247c249a1Stakemura VR4102_KIU_ADDR, /* base address */
27347c249a1Stakemura },
27447c249a1Stakemura #endif /* VR4111 */
27547c249a1Stakemura #ifdef VR4121
27647c249a1Stakemura {
27747c249a1Stakemura &platid_mask_CPU_MIPS_VR_4121,
27847c249a1Stakemura VR4102_KIU_ADDR, /* base address */
27947c249a1Stakemura },
28047c249a1Stakemura #endif /* VR4121 */
28147c249a1Stakemura {
28247c249a1Stakemura &platid_wild,
28347c249a1Stakemura #ifdef SINGLE_VRIP_BASE
28447c249a1Stakemura VRIP_KIU_ADDR, /* base address */
28547c249a1Stakemura #else
28647c249a1Stakemura VRIP_NO_ADDR, /* base address */
28747c249a1Stakemura #endif /* SINGLE_VRIP_BASE */
28847c249a1Stakemura },
28947c249a1Stakemura };
29047c249a1Stakemura #endif /* NVRKIU > 0 */
29147c249a1Stakemura
292db2b0adeStakemura void
vr_init(void)293df7f595eScegger vr_init(void)
294db2b0adeStakemura {
295db2b0adeStakemura /*
296db2b0adeStakemura * Platform Specific Function Hooks
297db2b0adeStakemura */
2986a9bbffcSuch platform.cpu_idle = vr_idle;
2996c1c0affSuch platform.cpu_intr = VR_INTR;
300db2b0adeStakemura platform.cons_init = vr_cons_init;
301fe6ca23bSuch platform.fb_init = vr_fb_init;
302fe6ca23bSuch platform.mem_init = vr_mem_init;
30362009df2Stakemura platform.reboot = vr_reboot;
304db2b0adeStakemura
3054765859dSsato #if NVRBCU > 0
306*42391ab5Schristos cpuname_printf("NEC %s rev%d.%d %d.%03dMHz",
307db2b0adeStakemura vrbcu_vrip_getcpuname(),
308db2b0adeStakemura vrbcu_vrip_getcpumajor(),
30979adf0a6Sshin vrbcu_vrip_getcpuminor(),
31079adf0a6Sshin vrbcu_vrip_getcpuclock() / 1000000,
31179adf0a6Sshin (vrbcu_vrip_getcpuclock() % 1000000) / 1000);
3124765859dSsato #else
313*42391ab5Schristos cpuname_printf("NEC VR41xx");
3144765859dSsato #endif
315db2b0adeStakemura }
316db2b0adeStakemura
31726f41e8fSshin void
vr_mem_init(paddr_t kernend)318961880b5Such vr_mem_init(paddr_t kernend)
319fe6ca23bSuch {
3201898d1dcSenami
32126f41e8fSshin mem_clusters[0].start = 0;
32226f41e8fSshin mem_clusters[0].size = kernend;
32326f41e8fSshin mem_cluster_cnt = 1;
3241898d1dcSenami
32526f41e8fSshin vr_find_dram(kernend, 0x02000000);
32626f41e8fSshin vr_find_dram(0x02000000, 0x04000000);
32726f41e8fSshin vr_find_dram(0x04000000, 0x06000000);
32826f41e8fSshin vr_find_dram(0x06000000, 0x08000000);
32926f41e8fSshin }
33026f41e8fSshin
33126f41e8fSshin void
vr_find_dram(paddr_t addr,paddr_t end)332961880b5Such vr_find_dram(paddr_t addr, paddr_t end)
33326f41e8fSshin {
33426f41e8fSshin int n;
3353b196667She char *page;
33626f41e8fSshin #ifdef NARLY_MEMORY_PROBE
33726f41e8fSshin int x, i;
33826f41e8fSshin #endif
33926f41e8fSshin
3401898d1dcSenami #ifdef VR_FIND_DRAMLIM
3411898d1dcSenami if (VR_FIND_DRAMLIM < end)
3421898d1dcSenami end = VR_FIND_DRAMLIM;
3436c1c0affSuch #endif /* VR_FIND_DRAMLIM */
34426f41e8fSshin n = mem_cluster_cnt;
345fd53a1c3Sthorpej for (; addr < end; addr += PAGE_SIZE) {
34626f41e8fSshin
3473b196667She page = (char *)MIPS_PHYS_TO_KSEG1(addr);
3480870d105Sjun /*
3490870d105Sjun XXX see port-hpcmips/42934
35026f41e8fSshin if (badaddr(page, 4))
35126f41e8fSshin goto bad;
3520870d105Sjun */
35326f41e8fSshin
3542d3ab1efSshin /* stop memory probing at first memory image */
35535fb6474Scegger if (memcmp(page, (void *)MIPS_PHYS_TO_KSEG0(0), 128) == 0)
3562d3ab1efSshin return;
3572d3ab1efSshin
35826f41e8fSshin *(volatile int *)(page+0) = 0xa5a5a5a5;
35926f41e8fSshin *(volatile int *)(page+4) = 0x5a5a5a5a;
36026f41e8fSshin wbflush();
36126f41e8fSshin if (*(volatile int *)(page+0) != 0xa5a5a5a5)
36226f41e8fSshin goto bad;
36326f41e8fSshin
36426f41e8fSshin *(volatile int *)(page+0) = 0x5a5a5a5a;
36526f41e8fSshin *(volatile int *)(page+4) = 0xa5a5a5a5;
36626f41e8fSshin wbflush();
36726f41e8fSshin if (*(volatile int *)(page+0) != 0x5a5a5a5a)
36826f41e8fSshin goto bad;
36926f41e8fSshin
37026f41e8fSshin #ifdef NARLY_MEMORY_PROBE
37126f41e8fSshin x = random();
372fd53a1c3Sthorpej for (i = 0; i < PAGE_SIZE; i += 4)
37326f41e8fSshin *(volatile int *)(page+i) = (x ^ i);
37426f41e8fSshin wbflush();
375fd53a1c3Sthorpej for (i = 0; i < PAGE_SIZE; i += 4)
37626f41e8fSshin if (*(volatile int *)(page+i) != (x ^ i))
37726f41e8fSshin goto bad;
37826f41e8fSshin
37926f41e8fSshin x = random();
380fd53a1c3Sthorpej for (i = 0; i < PAGE_SIZE; i += 4)
38126f41e8fSshin *(volatile int *)(page+i) = (x ^ i);
38226f41e8fSshin wbflush();
383fd53a1c3Sthorpej for (i = 0; i < PAGE_SIZE; i += 4)
38426f41e8fSshin if (*(volatile int *)(page+i) != (x ^ i))
38526f41e8fSshin goto bad;
3866c1c0affSuch #endif /* NARLY_MEMORY_PROBE */
38726f41e8fSshin
38826f41e8fSshin if (!mem_clusters[n].size)
38926f41e8fSshin mem_clusters[n].start = addr;
390fd53a1c3Sthorpej mem_clusters[n].size += PAGE_SIZE;
39126f41e8fSshin continue;
39226f41e8fSshin
39326f41e8fSshin bad:
39426f41e8fSshin if (mem_clusters[n].size)
39526f41e8fSshin ++n;
39626f41e8fSshin continue;
39726f41e8fSshin }
39826f41e8fSshin if (mem_clusters[n].size)
39926f41e8fSshin ++n;
40026f41e8fSshin mem_cluster_cnt = n;
401fe6ca23bSuch }
402fe6ca23bSuch
403fe6ca23bSuch void
vr_fb_init(void ** kernend)40453524e44Schristos vr_fb_init(void **kernend)
405fe6ca23bSuch {
406fe6ca23bSuch /* Nothing to do */
407fe6ca23bSuch }
408fe6ca23bSuch
409db2b0adeStakemura void
vr_cons_init(void)410df7f595eScegger vr_cons_init(void)
411db2b0adeStakemura {
41201b846e2Stakemura #if NCOM > 0 || NHPCFB > 0 || NVRKIU > 0
41387a75cecSuch bus_space_tag_t iot = hpcmips_system_bus_space();
414db2b0adeStakemura #endif
41501b846e2Stakemura #if NCOM > 0
41601b846e2Stakemura static struct vr_com_platdep *com_info;
41701b846e2Stakemura #endif
41847c249a1Stakemura #if NVRKIU > 0
41947c249a1Stakemura static struct vr_kiu_platdep *kiu_info;
42047c249a1Stakemura #endif
421db2b0adeStakemura
422db2b0adeStakemura #if NCOM > 0
42301b846e2Stakemura com_info = platid_search(&platid, platdep_com_table,
42401b846e2Stakemura sizeof(platdep_com_table)/sizeof(*platdep_com_table),
42501b846e2Stakemura sizeof(*platdep_com_table));
4260e306bacSjeffs #ifdef KGDB
42701b846e2Stakemura if (com_info->attach != NULL) {
4280e306bacSjeffs /* if KGDB is defined, always use the serial port for KGDB */
42901b846e2Stakemura if ((*com_info->attach)(iot, com_info->addr, 9600,
43001b846e2Stakemura com_info->freq,
43187a75cecSuch (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8, 1)) {
4320e306bacSjeffs printf("%s(%d): can't init kgdb's serial port",
4330e306bacSjeffs __FILE__, __LINE__);
4340e306bacSjeffs }
435a9393c26Sjun }
43687a75cecSuch #else /* KGDB */
43701b846e2Stakemura if (com_info->attach != NULL && (bootinfo->bi_cnuse&BI_CNUSE_SERIAL)) {
438db2b0adeStakemura /* Serial console */
43901b846e2Stakemura if ((*com_info->attach)(iot, com_info->addr, CONSPEED,
44001b846e2Stakemura com_info->freq,
44101b846e2Stakemura (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8, 0)) {
442c74dc481Senami printf("%s(%d): can't init serial console",
443c74dc481Senami __FILE__, __LINE__);
444db2b0adeStakemura } else {
445db2b0adeStakemura return;
446db2b0adeStakemura }
447db2b0adeStakemura }
44887a75cecSuch #endif /* KGDB */
44987a75cecSuch #endif /* NCOM > 0 */
450db2b0adeStakemura
451e9619d5dStakemura #if NHPCFB > 0
4529dccb575Such if (hpcfb_cnattach(NULL)) {
4535a30c207Stakemura printf("%s(%d): can't init fb console", __FILE__, __LINE__);
4545a30c207Stakemura } else {
4555a30c207Stakemura goto find_keyboard;
4565a30c207Stakemura }
4571898d1dcSenami find_keyboard:
45887a75cecSuch #endif /* NHPCFB > 0 */
4595a30c207Stakemura
46047c249a1Stakemura #if NVRKIU > 0
46147c249a1Stakemura kiu_info = platid_search(&platid, platdep_kiu_table,
46247c249a1Stakemura sizeof(platdep_kiu_table)/sizeof(*platdep_kiu_table),
46347c249a1Stakemura sizeof(*platdep_kiu_table));
46447c249a1Stakemura if (kiu_info->addr != VRIP_NO_ADDR) {
46547c249a1Stakemura if (vrkiu_cnattach(iot, kiu_info->addr)) {
4665a30c207Stakemura printf("%s(%d): can't init vrkiu as console",
4675a30c207Stakemura __FILE__, __LINE__);
4685a30c207Stakemura } else {
4695a30c207Stakemura return;
4705a30c207Stakemura }
47147c249a1Stakemura }
47247c249a1Stakemura #endif /* NVRKIU > 0 */
473db2b0adeStakemura }
474db2b0adeStakemura
47579606e01Sshin extern char vr_hibernate[];
47679606e01Sshin extern char evr_hibernate[];
47779606e01Sshin
478db2b0adeStakemura void
vr_reboot(int howto,char * bootstr)479961880b5Such vr_reboot(int howto, char *bootstr)
48062009df2Stakemura {
481b5c8739bStakemura /*
482b5c8739bStakemura * power down
483b5c8739bStakemura */
484b5c8739bStakemura if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
485b5c8739bStakemura printf("fake powerdown\n");
48679606e01Sshin /*
48779606e01Sshin * copy vr_hibernate() to top of physical memory.
48879606e01Sshin */
48979606e01Sshin memcpy((void *)MIPS_KSEG0_START, vr_hibernate,
49079606e01Sshin evr_hibernate - (char *)vr_hibernate);
49179606e01Sshin /* sync I&D cache */
49279606e01Sshin mips_dcache_wbinv_all();
49379606e01Sshin mips_icache_sync_all();
49479606e01Sshin /*
49579606e01Sshin * call vr_hibernate() at MIPS_KSEG0_START.
49679606e01Sshin */
49779606e01Sshin ((void (*)(void *,int))MIPS_KSEG0_START)(
49879606e01Sshin (void *)MIPS_KSEG0_START, ptoa(physmem));
499b5c8739bStakemura /* not reach */
500b5c8739bStakemura vr_reboot(howto&~RB_HALT, bootstr);
501b5c8739bStakemura }
502b5c8739bStakemura /*
503b5c8739bStakemura * halt
504b5c8739bStakemura */
50521574acbStakemura if (howto & RB_HALT) {
50638e50940Stakemura #if NVRIP_COMMON > 0
5077c1de38aStsutsui vrip_splpiu();
50821574acbStakemura vrip_intr_suspend();
50921574acbStakemura #else
510b5c8739bStakemura splhigh();
51121574acbStakemura #endif
512b5c8739bStakemura __asm(".set noreorder");
513ac20c30bSmycroft __asm(".word " ___STRING(VR_OPCODE_SUSPEND));
514943c0836Ssato __asm("nop");
515943c0836Ssato __asm("nop");
516943c0836Ssato __asm("nop");
517943c0836Ssato __asm("nop");
518943c0836Ssato __asm("nop");
519b5c8739bStakemura __asm(".set reorder");
52038e50940Stakemura #if NVRIP_COMMON > 0
52121574acbStakemura vrip_intr_resume();
52221574acbStakemura #endif
523943c0836Ssato }
52421574acbStakemura /*
52521574acbStakemura * reset
52621574acbStakemura */
52721574acbStakemura #if NVRDSU
52821574acbStakemura vrdsu_reset();
52921574acbStakemura #else
53021574acbStakemura printf("%s(%d): There is no DSU.", __FILE__, __LINE__);
53121574acbStakemura #endif
532943c0836Ssato }
533943c0836Ssato
53487a75cecSuch /*
53587a75cecSuch * Handle interrupts.
53687a75cecSuch */
5376c1c0affSuch void
VR_INTR(int ppl,vaddr_t pc,uint32_t status)5380351e901Smatt VR_INTR(int ppl, vaddr_t pc, uint32_t status)
53987a75cecSuch {
5400351e901Smatt uint32_t ipending;
5410351e901Smatt int ipl;
542229f1dedStsutsui
5430351e901Smatt while (ppl < (ipl = splintr(&ipending))) {
5440351e901Smatt /* Deal with unneded compare interrupts occasionally so that
5450351e901Smatt * we can keep spllowersoftclock. */
5466c1c0affSuch if (ipending & MIPS_INT_MASK_5) {
5471daa6c52Shamajima mips3_cp0_compare_write(0);
5486c1c0affSuch }
54987a75cecSuch
5506c1c0affSuch if (ipending & MIPS_INT_MASK_1) {
551a59ce072Stsutsui (*vr_intr_handler[1])(vr_intr_arg[1], pc, status);
5526c1c0affSuch }
5536c1c0affSuch
5546c1c0affSuch if (ipending & MIPS_INT_MASK_0) {
5556c1c0affSuch (*vr_intr_handler[0])(vr_intr_arg[0], pc, status);
5566c1c0affSuch }
5571daa6c52Shamajima }
55887a75cecSuch }
55987a75cecSuch
560db2b0adeStakemura void *
vr_intr_establish(int line,int (* ih_fun)(void *,vaddr_t,uint32_t),void * ih_arg)56184116228Stsutsui vr_intr_establish(int line, int (*ih_fun)(void *, vaddr_t, uint32_t),
562961880b5Such void *ih_arg)
563db2b0adeStakemura {
564961880b5Such
5656c1c0affSuch KDASSERT(vr_intr_handler[line] == vr_null_handler);
5666c1c0affSuch
5676c1c0affSuch vr_intr_handler[line] = ih_fun;
5686c1c0affSuch vr_intr_arg[line] = ih_arg;
569db2b0adeStakemura
57087a75cecSuch return ((void *)line);
571db2b0adeStakemura }
572db2b0adeStakemura
573db2b0adeStakemura void
vr_intr_disestablish(void * ih)574961880b5Such vr_intr_disestablish(void *ih)
575db2b0adeStakemura {
576db2b0adeStakemura int line = (int)ih;
577961880b5Such
5786c1c0affSuch vr_intr_handler[line] = vr_null_handler;
5796c1c0affSuch vr_intr_arg[line] = NULL;
580db2b0adeStakemura }
581db2b0adeStakemura
582db2b0adeStakemura int
vr_null_handler(void * arg,vaddr_t pc,uint32_t status)58384116228Stsutsui vr_null_handler(void *arg, vaddr_t pc, uint32_t status)
584db2b0adeStakemura {
5856c1c0affSuch
5866c1c0affSuch printf("vr_null_handler\n");
587961880b5Such
588961880b5Such return (0);
589db2b0adeStakemura }
590db2b0adeStakemura
591db2b0adeStakemura /*
59212a0a0a5Ssato int x4181 = VR4181;
59312a0a0a5Ssato int x4101 = VR4101;
59412a0a0a5Ssato int x4102 = VR4102;
59512a0a0a5Ssato int x4111 = VR4111;
59612a0a0a5Ssato int x4121 = VR4121;
59712a0a0a5Ssato int x4122 = VR4122;
59812a0a0a5Ssato int xo4181 = ONLY_VR4181;
59912a0a0a5Ssato int xo4101 = ONLY_VR4101;
60012a0a0a5Ssato int xo4102 = ONLY_VR4102;
60112a0a0a5Ssato int xo4111_4121 = ONLY_VR4111_4121;
60212a0a0a5Ssato int g4101=VRGROUP_4101;
60312a0a0a5Ssato int g4102=VRGROUP_4102;
60412a0a0a5Ssato int g4181=VRGROUP_4181;
60512a0a0a5Ssato int g4102_4121=VRGROUP_4102_4121;
60612a0a0a5Ssato int g4111_4121=VRGROUP_4111_4121;
60712a0a0a5Ssato int g4102_4122=VRGROUP_4102_4122;
60812a0a0a5Ssato int g4111_4122=VRGROUP_4111_4122;
60912a0a0a5Ssato int single_vrip_base=SINGLE_VRIP_BASE;
61012a0a0a5Ssato int vrip_base_addr=VRIP_BASE_ADDR;
61112a0a0a5Ssato */
612