Home | History | Annotate | Line # | Download | only in vr
vr.c revision 1.29
      1 /*	$NetBSD: vr.c,v 1.29 2001/09/16 15:45:45 uch 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 
     37 #include "opt_vr41xx.h"
     38 #include "opt_kgdb.h"
     39 
     40 #include <sys/param.h>
     41 #include <sys/types.h>
     42 #include <sys/systm.h>
     43 #include <sys/device.h>
     44 #include <sys/reboot.h>
     45 #include <sys/kcore.h>
     46 
     47 #include <machine/cpu.h>
     48 #include <machine/intr.h>
     49 #include <machine/reg.h>
     50 #include <machine/psl.h>
     51 #include <machine/locore.h>
     52 #include <machine/sysconf.h>
     53 #include <machine/bus.h>
     54 #include <machine/autoconf.h>
     55 
     56 #include <dev/hpc/hpckbdvar.h>
     57 
     58 #include <hpcmips/vr/vr.h>
     59 #include <hpcmips/vr/vr_asm.h>
     60 #include <hpcmips/vr/vrcpudef.h>
     61 #include <hpcmips/vr/vripreg.h>
     62 #include <hpcmips/vr/rtcreg.h>
     63 #include <hpcmips/hpcmips/machdep.h>	/* cpu_name */
     64 #include <machine/bootinfo.h>
     65 
     66 #include "vrip.h"
     67 #if NVRIP > 0
     68 #include <hpcmips/vr/vripvar.h>
     69 #endif
     70 
     71 #include "vrbcu.h"
     72 #if NVRBCU > 0
     73 #include <hpcmips/vr/bcuvar.h>
     74 #endif
     75 
     76 #include "vrdsu.h"
     77 #if NVRDSU > 0
     78 #include <hpcmips/vr/vrdsuvar.h>
     79 #endif
     80 
     81 #include "com.h"
     82 #if NCOM > 0
     83 #include <sys/termios.h>
     84 #include <sys/ttydefaults.h>
     85 #include <dev/ic/comreg.h>
     86 #include <dev/ic/comvar.h>
     87 #include <hpcmips/vr/siureg.h>
     88 #include <hpcmips/vr/com_vripvar.h>
     89 #ifndef CONSPEED
     90 #define CONSPEED TTYDEF_SPEED
     91 #endif
     92 #endif
     93 
     94 #include "hpcfb.h"
     95 #include "vrkiu.h"
     96 #if (NVRKIU > 0) || (NHPCFB > 0)
     97 #include <dev/wscons/wsdisplayvar.h>
     98 #include <dev/rasops/rasops.h>
     99 #endif
    100 
    101 #if NHPCFB > 0
    102 #include <dev/hpc/hpcfbvar.h>
    103 #endif
    104 
    105 #if NVRKIU > 0
    106 #include <arch/hpcmips/vr/vrkiureg.h>
    107 #include <arch/hpcmips/vr/vrkiuvar.h>
    108 #endif
    109 
    110 void	vr_init(void);
    111 int	vr_intr(u_int32_t, u_int32_t, u_int32_t, u_int32_t);
    112 void	vr_cons_init(void);
    113 void    vr_fb_init(caddr_t *);
    114 void    vr_mem_init(paddr_t);
    115 void	vr_find_dram(paddr_t, paddr_t);
    116 void	vr_reboot(int, char *);
    117 void	vr_idle(void);
    118 
    119 /*
    120  * CPU interrupt dispatch table (HwInt[0:3])
    121  */
    122 int null_handler(void *, u_int32_t, u_int32_t);
    123 static int (*intr_handler[4])(void*, u_int32_t, u_int32_t) =
    124 {
    125 	null_handler,
    126 	null_handler,
    127 	null_handler,
    128 	null_handler
    129 };
    130 static void *intr_arg[4];
    131 
    132 extern phys_ram_seg_t mem_clusters[];
    133 extern int mem_cluster_cnt;
    134 
    135 void
    136 vr_init()
    137 {
    138 	/*
    139 	 * Platform Specific Function Hooks
    140 	 */
    141 	platform.cpu_idle	= vr_idle;
    142 	platform.iointr		= vr_intr;
    143 	platform.cons_init	= vr_cons_init;
    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 void
    161 vr_mem_init(paddr_t kernend)
    162 {
    163 
    164 	mem_clusters[0].start = 0;
    165 	mem_clusters[0].size = kernend;
    166 	mem_cluster_cnt = 1;
    167 
    168 	vr_find_dram(kernend, 0x02000000);
    169 	vr_find_dram(0x02000000, 0x04000000);
    170 	vr_find_dram(0x04000000, 0x06000000);
    171 	vr_find_dram(0x06000000, 0x08000000);
    172 
    173 	/* Clear currently unused D-RAM area (For reboot Windows CE clearly)*/
    174 	memset((void *)(KERNBASE + 0x400), 0, KERNTEXTOFF - (KERNBASE + 0x800));
    175 }
    176 
    177 void
    178 vr_find_dram(paddr_t addr, paddr_t end)
    179 {
    180 	int n;
    181 	caddr_t page;
    182 #ifdef NARLY_MEMORY_PROBE
    183 	int x, i;
    184 #endif
    185 
    186 #ifdef VR_FIND_DRAMLIM
    187 	if (VR_FIND_DRAMLIM < end)
    188 		end = VR_FIND_DRAMLIM;
    189 #endif
    190 	n = mem_cluster_cnt;
    191 	for (; addr < end; addr += NBPG) {
    192 
    193 		page = (void *)MIPS_PHYS_TO_KSEG1(addr);
    194 		if (badaddr(page, 4))
    195 			goto bad;
    196 
    197 		/* stop memory probing at first memory image */
    198 		if (bcmp(page, (void *)MIPS_PHYS_TO_KSEG0(0), 128) == 0)
    199 			return;
    200 
    201 		*(volatile int *)(page+0) = 0xa5a5a5a5;
    202 		*(volatile int *)(page+4) = 0x5a5a5a5a;
    203 		wbflush();
    204 		if (*(volatile int *)(page+0) != 0xa5a5a5a5)
    205 			goto bad;
    206 
    207 		*(volatile int *)(page+0) = 0x5a5a5a5a;
    208 		*(volatile int *)(page+4) = 0xa5a5a5a5;
    209 		wbflush();
    210 		if (*(volatile int *)(page+0) != 0x5a5a5a5a)
    211 			goto bad;
    212 
    213 #ifdef NARLY_MEMORY_PROBE
    214 		x = random();
    215 		for (i = 0; i < NBPG; i += 4)
    216 			*(volatile int *)(page+i) = (x ^ i);
    217 		wbflush();
    218 		for (i = 0; i < NBPG; i += 4)
    219 			if (*(volatile int *)(page+i) != (x ^ i))
    220 				goto bad;
    221 
    222 		x = random();
    223 		for (i = 0; i < NBPG; i += 4)
    224 			*(volatile int *)(page+i) = (x ^ i);
    225 		wbflush();
    226 		for (i = 0; i < NBPG; i += 4)
    227 			if (*(volatile int *)(page+i) != (x ^ i))
    228 				goto bad;
    229 #endif
    230 
    231 		if (!mem_clusters[n].size)
    232 			mem_clusters[n].start = addr;
    233 		mem_clusters[n].size += NBPG;
    234 		continue;
    235 
    236 	bad:
    237 		if (mem_clusters[n].size)
    238 			++n;
    239 		continue;
    240 	}
    241 	if (mem_clusters[n].size)
    242 		++n;
    243 	mem_cluster_cnt = n;
    244 }
    245 
    246 void
    247 vr_fb_init(caddr_t *kernend)
    248 {
    249 	/* Nothing to do */
    250 }
    251 
    252 void
    253 vr_cons_init()
    254 {
    255 #if NCOM > 0 || NHPCFB > 0 || NVRKIU > 0
    256 	extern bus_space_tag_t system_bus_iot;
    257 	extern bus_space_tag_t mb_bus_space_init(void);
    258 
    259 	/*
    260 	 * At this time, system_bus_iot is not initialized yet.
    261 	 * Just initialize it here.
    262 	 */
    263 	mb_bus_space_init();
    264 #endif
    265 
    266 #if NCOM > 0
    267 #ifdef KGDB
    268 	/* if KGDB is defined, always use the serial port for KGDB */
    269 	if (com_vrip_cndb_attach(system_bus_iot, VRIP_SIU_ADDR, 9600,
    270 	    VRCOM_FREQ, (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8, 1)) {
    271 		printf("%s(%d): can't init kgdb's serial port",
    272 		    __FILE__, __LINE__);
    273 	}
    274 #else
    275 	if (bootinfo->bi_cnuse & BI_CNUSE_SERIAL) {
    276 		/* Serial console */
    277 		if (com_vrip_cndb_attach(system_bus_iot,
    278 		    VRIP_SIU_ADDR, CONSPEED, VRCOM_FREQ,
    279 		    (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8, 0)) {
    280 			printf("%s(%d): can't init serial console",
    281 			    __FILE__, __LINE__);
    282 		} else {
    283 			return;
    284 		}
    285 	}
    286 #endif
    287 #endif
    288 
    289 #if NHPCFB > 0
    290 	if (hpcfb_cnattach(NULL)) {
    291 		printf("%s(%d): can't init fb console", __FILE__, __LINE__);
    292 	} else {
    293 		goto find_keyboard;
    294 	}
    295  find_keyboard:
    296 #endif
    297 
    298 #if NVRKIU > 0 && VRIP_KIU_ADDR != VRIP_NO_ADDR
    299 	if (vrkiu_cnattach(system_bus_iot, VRIP_KIU_ADDR)) {
    300 		printf("%s(%d): can't init vrkiu as console",
    301 		       __FILE__, __LINE__);
    302 	} else {
    303 		return;
    304 	}
    305 #endif
    306 }
    307 
    308 void
    309 vr_reboot(int howto, char *bootstr)
    310 {
    311 	/*
    312 	 * power down
    313 	 */
    314 	if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
    315 		printf("fake powerdown\n");
    316 		__asm(__CONCAT(".word	",___STRING(VR_OPCODE_HIBERNATE)));
    317 		__asm("nop");
    318 		__asm("nop");
    319 		__asm("nop");
    320 		__asm("nop");
    321 		__asm("nop");
    322 		__asm(".set reorder");
    323 		/* not reach */
    324 		vr_reboot(howto&~RB_HALT, bootstr);
    325 	}
    326 	/*
    327 	 * halt
    328 	 */
    329 	if (howto & RB_HALT) {
    330 #if NVRIP > 0
    331 		_spllower(~MIPS_INT_MASK_0);
    332 		vrip_intr_suspend();
    333 #else
    334 		splhigh();
    335 #endif
    336 		__asm(".set noreorder");
    337 		__asm(__CONCAT(".word	",___STRING(VR_OPCODE_SUSPEND)));
    338 		__asm("nop");
    339 		__asm("nop");
    340 		__asm("nop");
    341 		__asm("nop");
    342 		__asm("nop");
    343 		__asm(".set reorder");
    344 #if NVRIP > 0
    345 		vrip_intr_resume();
    346 #endif
    347 	}
    348 	/*
    349 	 * reset
    350 	 */
    351 #if NVRDSU
    352 	vrdsu_reset();
    353 #else
    354 	printf("%s(%d): There is no DSU.", __FILE__, __LINE__);
    355 #endif
    356 }
    357 
    358 void *
    359 vr_intr_establish(int line, int (*ih_fun)(void*, u_int32_t, u_int32_t),
    360     void *ih_arg)
    361 {
    362 
    363 	if (intr_handler[line] != null_handler) {
    364 		panic("vr_intr_establish: can't establish duplicated intr handler.");
    365 	}
    366 	intr_handler[line] = ih_fun;
    367 	intr_arg[line] = ih_arg;
    368 
    369 	return (void*)line;
    370 }
    371 
    372 
    373 void
    374 vr_intr_disestablish(void *ih)
    375 {
    376 	int line = (int)ih;
    377 
    378 	intr_handler[line] = null_handler;
    379 	intr_arg[line] = NULL;
    380 }
    381 
    382 int
    383 null_handler(void *arg, u_int32_t pc, u_int32_t statusReg)
    384 {
    385 	printf("null_handler\n");
    386 
    387 	return (0);
    388 }
    389 
    390 /*
    391  * Handle interrupts.
    392  */
    393 int
    394 vr_intr(u_int32_t status, u_int32_t cause, u_int32_t pc, u_int32_t ipending)
    395 {
    396 	int hwintr;
    397 
    398 	hwintr = (ffs(ipending >> 10) -1) & 0x3;
    399 	(*intr_handler[hwintr])(intr_arg[hwintr], pc, status);
    400 
    401 	return (MIPS_SR_INT_IE | (status & ~cause & MIPS_HARD_INT_MASK));
    402 }
    403 
    404 
    405 /*
    406 int x4181 = VR4181;
    407 int x4101 = VR4101;
    408 int x4102 = VR4102;
    409 int x4111 = VR4111;
    410 int x4121 = VR4121;
    411 int x4122 = VR4122;
    412 int xo4181 = ONLY_VR4181;
    413 int xo4101 = ONLY_VR4101;
    414 int xo4102 = ONLY_VR4102;
    415 int xo4111_4121 = ONLY_VR4111_4121;
    416 int g4101=VRGROUP_4101;
    417 int g4102=VRGROUP_4102;
    418 int g4181=VRGROUP_4181;
    419 int g4102_4121=VRGROUP_4102_4121;
    420 int g4111_4121=VRGROUP_4111_4121;
    421 int g4102_4122=VRGROUP_4102_4122;
    422 int g4111_4122=VRGROUP_4111_4122;
    423 int single_vrip_base=SINGLE_VRIP_BASE;
    424 int vrip_base_addr=VRIP_BASE_ADDR;
    425 */
    426