Home | History | Annotate | Line # | Download | only in vr
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