machdep.c revision 1.30
11.30Such/*	$NetBSD: machdep.c,v 1.30 2002/02/17 20:57:12 uch Exp $	*/
21.1Sitojun
31.1Sitojun/*-
41.1Sitojun * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
51.1Sitojun * All rights reserved.
61.1Sitojun *
71.1Sitojun * This code is derived from software contributed to The NetBSD Foundation
81.1Sitojun * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
91.1Sitojun * Simulation Facility, NASA Ames Research Center.
101.1Sitojun *
111.1Sitojun * Redistribution and use in source and binary forms, with or without
121.1Sitojun * modification, are permitted provided that the following conditions
131.1Sitojun * are met:
141.1Sitojun * 1. Redistributions of source code must retain the above copyright
151.1Sitojun *    notice, this list of conditions and the following disclaimer.
161.1Sitojun * 2. Redistributions in binary form must reproduce the above copyright
171.1Sitojun *    notice, this list of conditions and the following disclaimer in the
181.1Sitojun *    documentation and/or other materials provided with the distribution.
191.1Sitojun * 3. All advertising materials mentioning features or use of this software
201.1Sitojun *    must display the following acknowledgement:
211.1Sitojun *	This product includes software developed by the NetBSD
221.1Sitojun *	Foundation, Inc. and its contributors.
231.1Sitojun * 4. Neither the name of The NetBSD Foundation nor the names of its
241.1Sitojun *    contributors may be used to endorse or promote products derived
251.1Sitojun *    from this software without specific prior written permission.
261.1Sitojun *
271.1Sitojun * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
281.1Sitojun * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
291.1Sitojun * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
301.1Sitojun * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
311.1Sitojun * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
321.1Sitojun * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
331.1Sitojun * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
341.1Sitojun * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
351.1Sitojun * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
361.1Sitojun * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
371.1Sitojun * POSSIBILITY OF SUCH DAMAGE.
381.1Sitojun */
391.1Sitojun
401.1Sitojun/*-
411.1Sitojun * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
421.1Sitojun * All rights reserved.
431.1Sitojun *
441.1Sitojun * This code is derived from software contributed to Berkeley by
451.1Sitojun * William Jolitz.
461.1Sitojun *
471.1Sitojun * Redistribution and use in source and binary forms, with or without
481.1Sitojun * modification, are permitted provided that the following conditions
491.1Sitojun * are met:
501.1Sitojun * 1. Redistributions of source code must retain the above copyright
511.1Sitojun *    notice, this list of conditions and the following disclaimer.
521.1Sitojun * 2. Redistributions in binary form must reproduce the above copyright
531.1Sitojun *    notice, this list of conditions and the following disclaimer in the
541.1Sitojun *    documentation and/or other materials provided with the distribution.
551.1Sitojun * 3. All advertising materials mentioning features or use of this software
561.1Sitojun *    must display the following acknowledgement:
571.1Sitojun *	This product includes software developed by the University of
581.1Sitojun *	California, Berkeley and its contributors.
591.1Sitojun * 4. Neither the name of the University nor the names of its contributors
601.1Sitojun *    may be used to endorse or promote products derived from this software
611.1Sitojun *    without specific prior written permission.
621.1Sitojun *
631.1Sitojun * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
641.1Sitojun * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
651.1Sitojun * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
661.1Sitojun * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
671.1Sitojun * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
681.1Sitojun * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
691.1Sitojun * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
701.1Sitojun * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
711.1Sitojun * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
721.1Sitojun * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
731.1Sitojun * SUCH DAMAGE.
741.1Sitojun *
751.1Sitojun *	@(#)machdep.c	7.4 (Berkeley) 6/3/91
761.1Sitojun */
771.1Sitojun
781.1Sitojun#include "opt_ddb.h"
791.26Slukem#include "opt_kgdb.h"
801.15Ssoren#include "opt_syscall_debug.h"
811.1Sitojun#include "opt_memsize.h"
821.1Sitojun#include "opt_initbsc.h"
831.1Sitojun
841.1Sitojun#include <sys/param.h>
851.1Sitojun#include <sys/systm.h>
861.1Sitojun#include <sys/signalvar.h>
871.1Sitojun#include <sys/kernel.h>
881.1Sitojun#include <sys/map.h>
891.1Sitojun#include <sys/proc.h>
901.1Sitojun#include <sys/user.h>
911.1Sitojun#include <sys/exec.h>
921.1Sitojun#include <sys/buf.h>
931.1Sitojun#include <sys/reboot.h>
941.1Sitojun#include <sys/conf.h>
951.1Sitojun#include <sys/file.h>
961.1Sitojun#include <sys/malloc.h>
971.1Sitojun#include <sys/mbuf.h>
981.1Sitojun#include <sys/msgbuf.h>
991.1Sitojun#include <sys/mount.h>
1001.1Sitojun#include <sys/vnode.h>
1011.1Sitojun#include <sys/device.h>
1021.1Sitojun#include <sys/extent.h>
1031.1Sitojun#include <sys/syscallargs.h>
1041.1Sitojun
1051.1Sitojun#ifdef KGDB
1061.1Sitojun#include <sys/kgdb.h>
1071.1Sitojun#endif
1081.1Sitojun
1091.1Sitojun#include <dev/cons.h>
1101.1Sitojun
1111.1Sitojun#include <uvm/uvm_extern.h>
1121.1Sitojun
1131.1Sitojun#include <sys/sysctl.h>
1141.1Sitojun
1151.1Sitojun#include <machine/cpu.h>
1161.1Sitojun#include <machine/cpufunc.h>
1171.1Sitojun#include <machine/psl.h>
1181.1Sitojun#include <machine/bootinfo.h>
1191.1Sitojun#include <machine/bus.h>
1201.1Sitojun#include <sh3/bscreg.h>
1211.1Sitojun#include <sh3/ccrreg.h>
1221.1Sitojun#include <sh3/cpgreg.h>
1231.1Sitojun#include <sh3/intcreg.h>
1241.1Sitojun#include <sh3/pfcreg.h>
1251.1Sitojun#include <sh3/wdtreg.h>
1261.30Such#include <sh3/mmu.h>
1271.1Sitojun
1281.1Sitojun#include <sys/termios.h>
1291.1Sitojun#include "sci.h"
1301.1Sitojun
1311.1Sitojun/* the following is used externally (sysctl_hw) */
1321.1Sitojunchar machine[] = MACHINE;		/* cpu "architecture" */
1331.1Sitojunchar machine_arch[] = MACHINE_ARCH;	/* machine_arch = "sh3" */
1341.1Sitojun
1351.1Sitojun#ifdef sh3_debug
1361.1Sitojunint cpu_debug_mode = 1;
1371.1Sitojun#else
1381.1Sitojunint cpu_debug_mode = 0;
1391.1Sitojun#endif
1401.1Sitojun
1411.1Sitojunchar bootinfo[BOOTINFO_MAXSIZE];
1421.1Sitojun
1431.3Smsaitohint physmem;
1441.3Smsaitohint dumpmem_low;
1451.3Smsaitohint dumpmem_high;
1461.3Smsaitohvaddr_t atdevbase;	/* location of start of iomem in virtual */
1471.1Sitojunpaddr_t msgbuf_paddr;
1481.3Smsaitohstruct user *proc0paddr;
1491.1Sitojun
1501.3Smsaitohextern int boothowto;
1511.1Sitojunextern paddr_t avail_start, avail_end;
1521.1Sitojun
1531.1Sitojun#ifdef	SYSCALL_DEBUG
1541.1Sitojun#define	SCDEBUG_ALL 0x0004
1551.1Sitojunextern int	scdebug;
1561.1Sitojun#endif
1571.1Sitojun
1581.1Sitojun#define IOM_RAM_END	((paddr_t)IOM_RAM_BEGIN + IOM_RAM_SIZE - 1)
1591.1Sitojun
1601.1Sitojun/*
1611.1Sitojun * Extent maps to manage I/O and ISA memory hole space.  Allocate
1621.1Sitojun * storage for 8 regions in each, initially.  Later, ioport_malloc_safe
1631.1Sitojun * will indicate that it's safe to use malloc() to dynamically allocate
1641.1Sitojun * region descriptors.
1651.1Sitojun *
1661.1Sitojun * N.B. At least two regions are _always_ allocated from the iomem
1671.1Sitojun * extent map; (0 -> ISA hole) and (end of ISA hole -> end of RAM).
1681.1Sitojun *
1691.1Sitojun * The extent maps are not static!  Machine-dependent ISA and EISA
1701.1Sitojun * routines need access to them for bus address space allocation.
1711.1Sitojun */
1721.1Sitojunstatic	long iomem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)];
1731.1Sitojunstruct	extent *ioport_ex;
1741.1Sitojunstruct	extent *iomem_ex;
1751.1Sitojunstatic	int ioport_malloc_safe;
1761.1Sitojun
1771.3Smsaitohvoid setup_bootinfo __P((void));
1781.3Smsaitohvoid dumpsys __P((void));
1791.3Smsaitohvoid identifycpu __P((void));
1801.3Smsaitohvoid initSH3 __P((void *));
1811.3Smsaitohvoid InitializeSci  __P((unsigned char));
1821.3Smsaitohvoid sh3_cache_on __P((void));
1831.3Smsaitohvoid LoadAndReset __P((char *));
1841.3Smsaitohvoid XLoadAndReset __P((char *));
1851.3Smsaitohvoid Sh3Reset __P((void));
1861.9Smsaitoh#ifdef SH4
1871.9Smsaitohvoid sh4_cache_flush __P((vaddr_t));
1881.9Smsaitoh#endif
1891.1Sitojun
1901.1Sitojun#include <dev/ic/comreg.h>
1911.1Sitojun#include <dev/ic/comvar.h>
1921.1Sitojun
1931.1Sitojunvoid	consinit __P((void));
1941.1Sitojun
1951.1Sitojun/*
1961.1Sitojun * Machine-dependent startup code
1971.1Sitojun *
1981.1Sitojun * This is called from main() in kern/main.c.
1991.1Sitojun */
2001.1Sitojunvoid
2011.1Sitojuncpu_startup()
2021.1Sitojun{
2031.1Sitojun
2041.5Stsubai	sh3_startup();
2051.1Sitojun
2061.1Sitojun	/* Safe for i/o port allocation to use malloc now. */
2071.1Sitojun	ioport_malloc_safe = 1;
2081.1Sitojun
2091.1Sitojun#ifdef SYSCALL_DEBUG
2101.1Sitojun	scdebug |= SCDEBUG_ALL;
2111.1Sitojun#endif
2121.1Sitojun
2131.3Smsaitoh#ifdef FORCE_RB_SINGLE
2141.1Sitojun	boothowto |= RB_SINGLE;
2151.1Sitojun#endif
2161.1Sitojun}
2171.1Sitojun
2181.1Sitojun#define CPUDEBUG
2191.1Sitojun
2201.1Sitojun/*
2211.1Sitojun * machine dependent system variables.
2221.1Sitojun */
2231.1Sitojunint
2241.1Sitojuncpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
2251.1Sitojun	int *name;
2261.1Sitojun	u_int namelen;
2271.1Sitojun	void *oldp;
2281.1Sitojun	size_t *oldlenp;
2291.1Sitojun	void *newp;
2301.1Sitojun	size_t newlen;
2311.1Sitojun	struct proc *p;
2321.1Sitojun{
2331.1Sitojun	dev_t consdev;
2341.1Sitojun	struct btinfo_bootpath *bibp;
2351.1Sitojun	struct trapframe *tf;
2361.1Sitojun	char *osimage;
2371.1Sitojun
2381.1Sitojun	/* all sysctl names at this level are terminal */
2391.1Sitojun	if (namelen != 1)
2401.1Sitojun		return (ENOTDIR);		/* overloaded */
2411.1Sitojun
2421.1Sitojun	switch (name[0]) {
2431.1Sitojun	case CPU_CONSDEV:
2441.1Sitojun		if (cn_tab != NULL)
2451.1Sitojun			consdev = cn_tab->cn_dev;
2461.1Sitojun		else
2471.1Sitojun			consdev = NODEV;
2481.1Sitojun		return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
2491.1Sitojun		    sizeof consdev));
2501.1Sitojun
2511.1Sitojun	case CPU_NKPDE:
2521.1Sitojun		return (sysctl_rdint(oldp, oldlenp, newp, nkpde));
2531.1Sitojun
2541.1Sitojun	case CPU_BOOTED_KERNEL:
2551.1Sitojun	        bibp = lookup_bootinfo(BTINFO_BOOTPATH);
2561.1Sitojun	        if (!bibp)
2571.1Sitojun			return (ENOENT); /* ??? */
2581.1Sitojun		return (sysctl_rdstring(oldp, oldlenp, newp, bibp->bootpath));
2591.1Sitojun
2601.1Sitojun	case CPU_SETPRIVPROC:
2611.1Sitojun		if (newp == NULL)
2621.1Sitojun			return (0);
2631.1Sitojun
2641.1Sitojun		/* set current process to priviledged process */
2651.1Sitojun		tf = p->p_md.md_regs;
2661.1Sitojun		tf->tf_ssr |= PSL_MD;
2671.1Sitojun		return (0);
2681.1Sitojun
2691.1Sitojun	case CPU_DEBUGMODE:
2701.1Sitojun		return (sysctl_int(oldp, oldlenp, newp, newlen,
2711.1Sitojun				   &cpu_debug_mode));
2721.1Sitojun
2731.1Sitojun	case CPU_LOADANDRESET:
2741.1Sitojun		if (newp != NULL) {
2751.1Sitojun			osimage = (char *)(*(u_long *)newp);
2761.1Sitojun
2771.1Sitojun			LoadAndReset(osimage);
2781.1Sitojun			/* not reach here */
2791.1Sitojun		}
2801.1Sitojun		return (0);
2811.1Sitojun
2821.1Sitojun	default:
2831.1Sitojun		return (EOPNOTSUPP);
2841.1Sitojun	}
2851.1Sitojun	/* NOTREACHED */
2861.1Sitojun}
2871.1Sitojun
2881.3Smsaitohint waittime = -1;
2891.1Sitojunstruct pcb dumppcb;
2901.1Sitojun
2911.1Sitojunvoid
2921.1Sitojuncpu_reboot(howto, bootstr)
2931.1Sitojun	int howto;
2941.1Sitojun	char *bootstr;
2951.1Sitojun{
2961.1Sitojun
2971.1Sitojun	if (cold) {
2981.1Sitojun		howto |= RB_HALT;
2991.1Sitojun		goto haltsys;
3001.1Sitojun	}
3011.1Sitojun
3021.1Sitojun	boothowto = howto;
3031.1Sitojun	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
3041.1Sitojun		waittime = 0;
3051.1Sitojun		vfs_shutdown();
3061.1Sitojun		/*
3071.1Sitojun		 * If we've been adjusting the clock, the todr
3081.1Sitojun		 * will be out of synch; adjust it now.
3091.1Sitojun		 */
3101.1Sitojun		/* resettodr(); */
3111.1Sitojun	}
3121.1Sitojun
3131.1Sitojun	/* Disable interrupts. */
3141.1Sitojun	splhigh();
3151.1Sitojun
3161.1Sitojun	/* Do a dump if requested. */
3171.1Sitojun	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
3181.1Sitojun		dumpsys();
3191.1Sitojun
3201.1Sitojunhaltsys:
3211.1Sitojun	doshutdownhooks();
3221.1Sitojun
3231.1Sitojun	if (howto & RB_HALT) {
3241.1Sitojun		printf("\n");
3251.1Sitojun		printf("The operating system has halted.\n");
3261.1Sitojun		printf("Please press any key to reboot.\n\n");
3271.1Sitojun		cngetc();
3281.1Sitojun	}
3291.1Sitojun
3301.1Sitojun	printf("rebooting...\n");
3311.1Sitojun	cpu_reset();
3321.1Sitojun	for(;;)
3331.1Sitojun		;
3341.1Sitojun	/*NOTREACHED*/
3351.1Sitojun}
3361.1Sitojun
3371.1Sitojun/*
3381.1Sitojun * These variables are needed by /sbin/savecore
3391.1Sitojun */
3401.1Sitojunu_long	dumpmag = 0x8fca0101;	/* magic number */
3411.1Sitojunint 	dumpsize = 0;		/* pages */
3421.1Sitojunlong	dumplo = 0; 		/* blocks */
3431.1Sitojun
3441.1Sitojun/*
3451.1Sitojun * This is called by main to set dumplo and dumpsize.
3461.1Sitojun * Dumps always skip the first CLBYTES of disk space
3471.1Sitojun * in case there might be a disk label stored there.
3481.1Sitojun * If there is extra space, put dump at the end to
3491.1Sitojun * reduce the chance that swapping trashes it.
3501.1Sitojun */
3511.1Sitojunvoid
3521.1Sitojuncpu_dumpconf()
3531.1Sitojun{
3541.1Sitojun#ifdef	TODO
3551.1Sitojun	int nblks;	/* size of dump area */
3561.1Sitojun	int maj;
3571.1Sitojun
3581.1Sitojun	if (dumpdev == NODEV)
3591.1Sitojun		return;
3601.1Sitojun	maj = major(dumpdev);
3611.1Sitojun	if (maj < 0 || maj >= nblkdev)
3621.1Sitojun		panic("dumpconf: bad dumpdev=0x%x", dumpdev);
3631.1Sitojun	if (bdevsw[maj].d_psize == NULL)
3641.1Sitojun		return;
3651.1Sitojun	nblks = (*bdevsw[maj].d_psize)(dumpdev);
3661.1Sitojun	if (nblks <= ctod(1))
3671.1Sitojun		return;
3681.1Sitojun
3691.1Sitojun	dumpsize = btoc(IOM_END + ctob(dumpmem_high));
3701.1Sitojun
3711.1Sitojun	/* Always skip the first CLBYTES, in case there is a label there. */
3721.1Sitojun	if (dumplo < ctod(1))
3731.1Sitojun		dumplo = ctod(1);
3741.1Sitojun
3751.1Sitojun	/* Put dump at end of partition, and make it fit. */
3761.1Sitojun	if (dumpsize > dtoc(nblks - dumplo))
3771.1Sitojun		dumpsize = dtoc(nblks - dumplo);
3781.1Sitojun	if (dumplo < nblks - ctod(dumpsize))
3791.1Sitojun		dumplo = nblks - ctod(dumpsize);
3801.1Sitojun#endif
3811.1Sitojun}
3821.1Sitojun
3831.1Sitojun/*
3841.1Sitojun * Doadump comes here after turning off memory management and
3851.1Sitojun * getting on the dump stack, either when called above, or by
3861.1Sitojun * the auto-restart code.
3871.1Sitojun */
3881.1Sitojun#define BYTES_PER_DUMP  NBPG	/* must be a multiple of pagesize XXX small */
3891.1Sitojunstatic vaddr_t dumpspace;
3901.1Sitojun
3911.1Sitojunvaddr_t
3921.1Sitojunreserve_dumppages(p)
3931.1Sitojun	vaddr_t p;
3941.1Sitojun{
3951.1Sitojun
3961.1Sitojun	dumpspace = p;
3971.1Sitojun	return (p + BYTES_PER_DUMP);
3981.1Sitojun}
3991.1Sitojun
4001.1Sitojunvoid
4011.1Sitojundumpsys()
4021.1Sitojun{
4031.1Sitojun#ifdef	TODO
4041.1Sitojun	unsigned bytes, i, n;
4051.1Sitojun	int maddr, psize;
4061.1Sitojun	daddr_t blkno;
4071.1Sitojun	int (*dump) __P((dev_t, daddr_t, caddr_t, size_t));
4081.1Sitojun	int error;
4091.1Sitojun
4101.1Sitojun	/* Save registers. */
4111.1Sitojun	savectx(&dumppcb);
4121.1Sitojun
4131.1Sitojun	msgbufmapped = 0;	/* don't record dump msgs in msgbuf */
4141.1Sitojun	if (dumpdev == NODEV)
4151.1Sitojun		return;
4161.1Sitojun
4171.1Sitojun	/*
4181.1Sitojun	 * For dumps during autoconfiguration,
4191.1Sitojun	 * if dump device has already configured...
4201.1Sitojun	 */
4211.1Sitojun	if (dumpsize == 0)
4221.1Sitojun		cpu_dumpconf();
4231.1Sitojun	if (dumplo < 0)
4241.1Sitojun		return;
4251.1Sitojun	printf("\ndumping to dev %x, offset %ld\n", dumpdev, dumplo);
4261.1Sitojun
4271.1Sitojun	psize = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
4281.1Sitojun	printf("dump ");
4291.1Sitojun	if (psize == -1) {
4301.1Sitojun		printf("area unavailable\n");
4311.1Sitojun		return;
4321.1Sitojun	}
4331.1Sitojun
4341.1Sitojun#if 0	/* XXX this doesn't work.  grr. */
4351.1Sitojun        /* toss any characters present prior to dump */
4361.13Smsaitoh	while (sget() != NULL); /* syscons and pccons differ */
4371.1Sitojun#endif
4381.1Sitojun
4391.1Sitojun	bytes = ctob(dumpmem_high) + IOM_END;
4401.1Sitojun	maddr = 0;
4411.1Sitojun	blkno = dumplo;
4421.1Sitojun	dump = bdevsw[major(dumpdev)].d_dump;
4431.1Sitojun	error = 0;
4441.1Sitojun	for (i = 0; i < bytes; i += n) {
4451.1Sitojun		/*
4461.1Sitojun		 * Avoid dumping the ISA memory hole, and areas that
4471.1Sitojun		 * BIOS claims aren't in low memory.
4481.1Sitojun		 */
4491.1Sitojun		if (i >= ctob(dumpmem_low) && i < IOM_END) {
4501.1Sitojun			n = IOM_END - i;
4511.1Sitojun			maddr += n;
4521.1Sitojun			blkno += btodb(n);
4531.1Sitojun			continue;
4541.1Sitojun		}
4551.1Sitojun
4561.1Sitojun		/* Print out how many MBs we to go. */
4571.1Sitojun		n = bytes - i;
4581.1Sitojun		if (n && (n % (1024*1024)) == 0)
4591.1Sitojun			printf("%d ", n / (1024 * 1024));
4601.1Sitojun
4611.1Sitojun		/* Limit size for next transfer. */
4621.1Sitojun		if (n > BYTES_PER_DUMP)
4631.1Sitojun			n =  BYTES_PER_DUMP;
4641.1Sitojun
4651.1Sitojun		(void) pmap_map(dumpspace, maddr, maddr + n, VM_PROT_READ);
4661.1Sitojun		error = (*dump)(dumpdev, blkno, (caddr_t)dumpspace, n);
4671.1Sitojun		if (error)
4681.1Sitojun			break;
4691.1Sitojun		maddr += n;
4701.1Sitojun		blkno += btodb(n);			/* XXX? */
4711.1Sitojun
4721.1Sitojun#if 0	/* XXX this doesn't work.  grr. */
4731.1Sitojun		/* operator aborting dump? */
4741.1Sitojun		if (sget() != NULL) {
4751.1Sitojun			error = EINTR;
4761.1Sitojun			break;
4771.1Sitojun		}
4781.1Sitojun#endif
4791.1Sitojun	}
4801.1Sitojun
4811.1Sitojun	switch (error) {
4821.1Sitojun
4831.1Sitojun	case ENXIO:
4841.1Sitojun		printf("device bad\n");
4851.1Sitojun		break;
4861.1Sitojun
4871.1Sitojun	case EFAULT:
4881.1Sitojun		printf("device not ready\n");
4891.1Sitojun		break;
4901.1Sitojun
4911.1Sitojun	case EINVAL:
4921.1Sitojun		printf("area improper\n");
4931.1Sitojun		break;
4941.1Sitojun
4951.1Sitojun	case EIO:
4961.1Sitojun		printf("i/o error\n");
4971.1Sitojun		break;
4981.1Sitojun
4991.1Sitojun	case EINTR:
5001.1Sitojun		printf("aborted from console\n");
5011.1Sitojun		break;
5021.1Sitojun
5031.1Sitojun	case 0:
5041.1Sitojun		printf("succeeded\n");
5051.1Sitojun		break;
5061.1Sitojun
5071.1Sitojun	default:
5081.1Sitojun		printf("error %d\n", error);
5091.1Sitojun		break;
5101.1Sitojun	}
5111.1Sitojun	printf("\n\n");
5121.1Sitojun	delay(5000000);		/* 5 seconds */
5131.1Sitojun#endif	/* TODO */
5141.1Sitojun}
5151.1Sitojun
5161.1Sitojun/*
5171.1Sitojun * Initialize segments and descriptor tables
5181.1Sitojun */
5191.8Smsaitoh#define VBRINIT		((char *)IOM_RAM_BEGIN)
5201.3Smsaitoh#define Trap100Vec	(VBRINIT + 0x100)
5211.3Smsaitoh#define Trap600Vec	(VBRINIT + 0x600)
5221.3Smsaitoh#define TLBVECTOR	(VBRINIT + 0x400)
5231.3Smsaitoh#define VADDRSTART	VM_MIN_KERNEL_ADDRESS
5241.3Smsaitoh
5251.3Smsaitohextern int nkpde;
5261.3Smsaitohextern char MonTrap100[], MonTrap100_end[];
5271.3Smsaitohextern char MonTrap600[], MonTrap600_end[];
5281.3Smsaitohextern char _start[], etext[], edata[], end[];
5291.3Smsaitohextern char tlbmisshandler_stub[], tlbmisshandler_stub_end[];
5301.1Sitojun
5311.1Sitojunvoid
5321.3SmsaitohinitSH3(pc)
5331.3Smsaitoh	void *pc;	/* XXX return address */
5341.1Sitojun{
5351.3Smsaitoh	paddr_t avail;
5361.3Smsaitoh	pd_entry_t *pagedir;
5371.3Smsaitoh	pt_entry_t *pagetab, pte;
5381.3Smsaitoh	u_int sp;
5391.3Smsaitoh	int x;
5401.3Smsaitoh	char *p;
5411.3Smsaitoh
5421.3Smsaitoh	avail = sh3_round_page(end);
5431.3Smsaitoh
5441.4Smsaitoh	/* XXX nkpde = kernel page dir area (IOM_RAM_SIZE*2 Mbyte (why?)) */
5451.4Smsaitoh	nkpde = IOM_RAM_SIZE >> (PDSHIFT - 1);
5461.4Smsaitoh
5471.3Smsaitoh	/*
5481.3Smsaitoh	 * clear .bss, .common area, page dir area,
5491.3Smsaitoh	 *	process0 stack, page table area
5501.3Smsaitoh	 */
5511.4Smsaitoh	p = (char *)avail + (1 + UPAGES) * NBPG + NBPG * (1 + nkpde); /* XXX */
5521.27Sichiro	memset(edata, 0, p - edata);
5531.3Smsaitoh
5541.30Such#if defined(SH3) && defined(SH4)
5551.30Such#error "don't define both SH3 and SH4"
5561.30Such#elif defined(SH3)
5571.30Such	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_UNKNOWN);
5581.30Such#elif defined(SH4)
5591.30Such	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_UNKNOWN);
5601.30Such#else
5611.30Such#error "define SH3 or SH4"
5621.30Such#endif
5631.3Smsaitoh	/*
5641.3Smsaitoh	 * install trap handler
5651.3Smsaitoh	 */
5661.27Sichiro	memcpy(Trap100Vec, MonTrap100, MonTrap100_end - MonTrap100);
5671.27Sichiro	memcpy(Trap600Vec, MonTrap600, MonTrap600_end - MonTrap600);
5681.3Smsaitoh	__asm ("ldc %0, vbr" :: "r"(VBRINIT));
5691.3Smsaitoh
5701.3Smsaitoh/*
5711.3Smsaitoh *                          edata  end
5721.3Smsaitoh *	+-------------+------+-----+----------+-------------+------------+
5731.3Smsaitoh *	| kernel text | data | bss | Page Dir | Proc0 Stack | Page Table |
5741.3Smsaitoh *	+-------------+------+-----+----------+-------------+------------+
5751.4Smsaitoh *                                     NBPG       USPACE    (1+nkpde)*NBPG
5761.3Smsaitoh *                                                (= 4*NBPG)
5771.3Smsaitoh *	Build initial page tables
5781.3Smsaitoh */
5791.3Smsaitoh	pagedir = (void *)avail;
5801.3Smsaitoh	pagetab = (void *)(avail + SYSMAP);
5811.3Smsaitoh
5821.3Smsaitoh	/*
5831.13Smsaitoh	 * Construct a page table directory
5841.13Smsaitoh	 * In SH3 H/W does not support PTD,
5851.13Smsaitoh	 * these structures are used by S/W.
5861.3Smsaitoh	 */
5871.3Smsaitoh	pte = (pt_entry_t)pagetab;
5881.3Smsaitoh	pte |= PG_KW | PG_V | PG_4K | PG_M | PG_N;
5891.3Smsaitoh	pagedir[KERNTEXTOFF >> PDSHIFT] = pte;
5901.3Smsaitoh
5911.3Smsaitoh	/* make pde for 0xd0000000, 0xd0400000, 0xd0800000,0xd0c00000,
5921.3Smsaitoh		0xd1000000, 0xd1400000, 0xd1800000, 0xd1c00000 */
5931.3Smsaitoh	pte += NBPG;
5941.3Smsaitoh	for (x = 0; x < nkpde; x++) {
5951.3Smsaitoh		pagedir[(VADDRSTART >> PDSHIFT) + x] = pte;
5961.3Smsaitoh		pte += NBPG;
5971.3Smsaitoh	}
5981.3Smsaitoh
5991.3Smsaitoh	/* Install a PDE recursively mapping page directory as a page table! */
6001.3Smsaitoh	pte = (u_int)pagedir;
6011.3Smsaitoh	pte |= PG_V | PG_4K | PG_KW | PG_M | PG_N;
6021.3Smsaitoh	pagedir[PDSLOT_PTE] = pte;
6031.3Smsaitoh
6041.3Smsaitoh	/* set PageDirReg */
6051.30Such	SH_MMU_TTB_WRITE((u_int32_t)pagedir);
6061.3Smsaitoh
6071.3Smsaitoh	/* Set TLB miss handler */
6081.3Smsaitoh	p = tlbmisshandler_stub;
6091.3Smsaitoh	x = tlbmisshandler_stub_end - p;
6101.27Sichiro	memcpy(TLBVECTOR, p, x);
6111.3Smsaitoh
6121.3Smsaitoh	/*
6131.3Smsaitoh	 * Activate MMU
6141.3Smsaitoh	 */
6151.30Such	sh_mmu_start();
6161.3Smsaitoh
6171.3Smsaitoh	/*
6181.3Smsaitoh	 * Now here is virtual address
6191.3Smsaitoh	 */
6201.3Smsaitoh
6211.3Smsaitoh	/* Set proc0paddr */
6221.3Smsaitoh	proc0paddr = (void *)(avail + NBPG);
6231.3Smsaitoh
6241.3Smsaitoh	/* Set pcb->PageDirReg of proc0 */
6251.3Smsaitoh	proc0paddr->u_pcb.pageDirReg = (int)pagedir;
6261.3Smsaitoh
6271.3Smsaitoh	/* avail_start is first available physical memory address */
6281.3Smsaitoh	avail_start = avail + NBPG + USPACE + NBPG + NBPG * nkpde;
6291.3Smsaitoh
6301.3Smsaitoh	/* atdevbase is first available logical memory address */
6311.3Smsaitoh	atdevbase = VADDRSTART;
6321.1Sitojun
6331.1Sitojun	proc0.p_addr = proc0paddr; /* page dir address */
6341.1Sitojun
6351.3Smsaitoh	/* XXX: PMAP_NEW requires valid curpcb.   also init'd in cpu_startup */
6361.3Smsaitoh	curpcb = &proc0.p_addr->u_pcb;
6371.3Smsaitoh
6381.1Sitojun	/*
6391.1Sitojun	 * Initialize the I/O port and I/O mem extent maps.
6401.1Sitojun	 * Note: we don't have to check the return value since
6411.1Sitojun	 * creation of a fixed extent map will never fail (since
6421.1Sitojun	 * descriptor storage has already been allocated).
6431.1Sitojun	 *
6441.1Sitojun	 * N.B. The iomem extent manages _all_ physical addresses
6451.1Sitojun	 * on the machine.  When the amount of RAM is found, the two
6461.1Sitojun	 * extents of RAM are allocated from the map (0 -> ISA hole
6471.1Sitojun	 * and end of ISA hole -> end of RAM).
6481.1Sitojun	 */
6491.1Sitojun	iomem_ex = extent_create("iomem", 0x0, 0xffffffff, M_DEVBUF,
6501.1Sitojun	    (caddr_t)iomem_ex_storage, sizeof(iomem_ex_storage),
6511.1Sitojun	    EX_NOCOALESCE|EX_NOWAIT);
6521.1Sitojun
6531.3Smsaitoh#if 0
6541.1Sitojun	consinit();	/* XXX SHOULD NOT BE DONE HERE */
6551.1Sitojun#endif
6561.1Sitojun
6571.1Sitojun	splraise(-1);
6581.1Sitojun	enable_intr();
6591.1Sitojun
6601.1Sitojun	avail_end = sh3_trunc_page(IOM_RAM_END + 1);
6611.1Sitojun
6621.1Sitojun	printf("initSH3\r\n");
6631.1Sitojun
6641.1Sitojun	/*
6651.1Sitojun	 * Calculate check sum
6661.1Sitojun	 */
6671.3Smsaitoh    {
6681.3Smsaitoh	u_short *p, sum;
6691.3Smsaitoh	int size;
6701.3Smsaitoh
6711.3Smsaitoh	size = etext - _start;
6721.3Smsaitoh	p = (u_short *)_start;
6731.1Sitojun	sum = 0;
6741.1Sitojun	size >>= 1;
6751.1Sitojun	while (size--)
6761.1Sitojun		sum += *p++;
6771.3Smsaitoh	printf("Check Sum = 0x%x\r\n", sum);
6781.3Smsaitoh    }
6791.1Sitojun	/*
6801.1Sitojun	 * Allocate the physical addresses used by RAM from the iomem
6811.1Sitojun	 * extent map.  This is done before the addresses are
6821.1Sitojun	 * page rounded just to make sure we get them all.
6831.1Sitojun	 */
6841.1Sitojun	if (extent_alloc_region(iomem_ex, IOM_RAM_BEGIN,
6851.3Smsaitoh				(IOM_RAM_END-IOM_RAM_BEGIN) + 1,
6861.1Sitojun				EX_NOWAIT)) {
6871.1Sitojun		/* XXX What should we do? */
6881.1Sitojun		printf("WARNING: CAN'T ALLOCATE RAM MEMORY FROM IOMEM EXTENT MAP!\n");
6891.1Sitojun	}
6901.1Sitojun
6911.1Sitojun	/* number of pages of physmem addr space */
6921.3Smsaitoh	physmem = btoc(IOM_RAM_END - IOM_RAM_BEGIN +1);
6931.1Sitojun#ifdef	TODO
6941.1Sitojun	dumpmem = physmem;
6951.1Sitojun#endif
6961.1Sitojun
6971.1Sitojun	/*
6981.1Sitojun	 * Initialize for pmap_free_pages and pmap_next_page.
6991.1Sitojun	 * These guys should be page-aligned.
7001.1Sitojun	 */
7011.1Sitojun	if (physmem < btoc(2 * 1024 * 1024)) {
7021.1Sitojun		printf("warning: too little memory available; "
7031.1Sitojun		       "have %d bytes, want %d bytes\n"
7041.1Sitojun		       "running in degraded mode\n"
7051.1Sitojun		       "press a key to confirm\n\n",
7061.1Sitojun		       ctob(physmem), 2*1024*1024);
7071.1Sitojun		cngetc();
7081.1Sitojun	}
7091.1Sitojun
7101.1Sitojun	/* Call pmap initialization to make new kernel address space */
7111.3Smsaitoh	pmap_bootstrap(atdevbase);
7121.1Sitojun
7131.1Sitojun	/*
7141.1Sitojun	 * Initialize error message buffer (at end of core).
7151.1Sitojun	 */
7161.1Sitojun	initmsgbuf((caddr_t)msgbuf_paddr, round_page(MSGBUFSIZE));
7171.1Sitojun
7181.1Sitojun	/*
7191.1Sitojun	 * set boot device information
7201.1Sitojun	 */
7211.1Sitojun	setup_bootinfo();
7221.1Sitojun
7231.1Sitojun#if 0
7241.1Sitojun	sh3_cache_on();
7251.1Sitojun#endif
7261.1Sitojun
7271.3Smsaitoh	/* setup proc0 stack */
7281.3Smsaitoh	sp = avail + NBPG + USPACE - 16 - sizeof(struct trapframe);
7291.3Smsaitoh
7301.3Smsaitoh	/*
7311.3Smsaitoh	 * XXX We can't return here, because we change stack pointer.
7321.3Smsaitoh	 *     So jump to return address directly.
7331.3Smsaitoh	 */
7341.3Smsaitoh	__asm __volatile ("jmp @%0; mov %1, r15" :: "r"(pc), "r"(sp));
7351.1Sitojun}
7361.1Sitojun
7371.1Sitojunvoid
7381.1Sitojunsetup_bootinfo(void)
7391.1Sitojun{
7401.1Sitojun	struct btinfo_bootdisk *help;
7411.1Sitojun
7421.1Sitojun	*(int *)bootinfo = 1;
7431.1Sitojun	help = (struct btinfo_bootdisk *)(bootinfo + sizeof(int));
7441.1Sitojun	help->biosdev = 0;
7451.1Sitojun	help->partition = 0;
7461.1Sitojun	((struct btinfo_common *)help)->len = sizeof(struct btinfo_bootdisk);
7471.1Sitojun	((struct btinfo_common *)help)->type = BTINFO_BOOTDISK;
7481.1Sitojun}
7491.1Sitojun
7501.1Sitojunvoid *
7511.1Sitojunlookup_bootinfo(type)
7521.1Sitojun	int type;
7531.1Sitojun{
7541.1Sitojun	struct btinfo_common *help;
7551.1Sitojun	int n = *(int*)bootinfo;
7561.1Sitojun	help = (struct btinfo_common *)(bootinfo + sizeof(int));
7571.1Sitojun	while (n--) {
7581.1Sitojun		if (help->type == type)
7591.1Sitojun			return (help);
7601.1Sitojun		help = (struct btinfo_common *)((char*)help + help->len);
7611.1Sitojun	}
7621.1Sitojun	return (0);
7631.1Sitojun}
7641.1Sitojun
7651.1Sitojun
7661.1Sitojun/*
7671.1Sitojun * consinit:
7681.1Sitojun * initialize the system console.
7691.1Sitojun * XXX - shouldn't deal with this initted thing, but then,
7701.1Sitojun * it shouldn't be called from init386 either.
7711.1Sitojun */
7721.1Sitojunvoid
7731.1Sitojunconsinit()
7741.1Sitojun{
7751.1Sitojun	static int initted;
7761.1Sitojun
7771.1Sitojun	if (initted)
7781.1Sitojun		return;
7791.1Sitojun	initted = 1;
7801.1Sitojun
7811.1Sitojun	cninit();
7821.1Sitojun
7831.1Sitojun#ifdef DDB
7841.1Sitojun	ddb_init();
7851.1Sitojun#endif
7861.1Sitojun}
7871.1Sitojun
7881.1Sitojunvoid
7891.1Sitojuncpu_reset()
7901.1Sitojun{
7911.1Sitojun
7921.1Sitojun	disable_intr();
7931.1Sitojun
7941.1Sitojun	Sh3Reset();
7951.1Sitojun	for (;;)
7961.1Sitojun		;
7971.1Sitojun}
7981.1Sitojun
7991.1Sitojunint
8001.1Sitojunbus_space_map (t, addr, size, flags, bshp)
8011.1Sitojun	bus_space_tag_t t;
8021.1Sitojun	bus_addr_t addr;
8031.1Sitojun	bus_size_t size;
8041.1Sitojun	int flags;
8051.1Sitojun	bus_space_handle_t *bshp;
8061.1Sitojun{
8071.1Sitojun
8081.1Sitojun	*bshp = (bus_space_handle_t)addr;
8091.1Sitojun
8101.1Sitojun	return 0;
8111.1Sitojun}
8121.1Sitojun
8131.1Sitojunint
8141.1Sitojunsh_memio_subregion(t, bsh, offset, size, nbshp)
8151.1Sitojun	bus_space_tag_t t;
8161.1Sitojun	bus_space_handle_t bsh;
8171.1Sitojun	bus_size_t offset, size;
8181.1Sitojun	bus_space_handle_t *nbshp;
8191.1Sitojun{
8201.1Sitojun
8211.1Sitojun	*nbshp = bsh + offset;
8221.1Sitojun	return (0);
8231.1Sitojun}
8241.1Sitojun
8251.1Sitojunint
8261.1Sitojunsh_memio_alloc(t, rstart, rend, size, alignment, boundary, flags,
8271.1Sitojun	       bpap, bshp)
8281.1Sitojun	bus_space_tag_t t;
8291.1Sitojun	bus_addr_t rstart, rend;
8301.1Sitojun	bus_size_t size, alignment, boundary;
8311.1Sitojun	int flags;
8321.1Sitojun	bus_addr_t *bpap;
8331.1Sitojun	bus_space_handle_t *bshp;
8341.1Sitojun{
8351.1Sitojun	*bshp = *bpap = rstart;
8361.1Sitojun
8371.1Sitojun	return (0);
8381.1Sitojun}
8391.1Sitojun
8401.1Sitojunvoid
8411.1Sitojunsh_memio_free(t, bsh, size)
8421.1Sitojun	bus_space_tag_t t;
8431.1Sitojun	bus_space_handle_t bsh;
8441.1Sitojun	bus_size_t size;
8451.1Sitojun{
8461.1Sitojun
8471.1Sitojun}
8481.1Sitojun
8491.1Sitojunvoid
8501.1Sitojunsh_memio_unmap(t, bsh, size)
8511.1Sitojun	bus_space_tag_t t;
8521.1Sitojun	bus_space_handle_t bsh;
8531.1Sitojun	bus_size_t size;
8541.1Sitojun{
8551.1Sitojun	return;
8561.1Sitojun}
8571.20Smsaitoh
8581.20Smsaitoh#ifdef SH4_PCMCIA
8591.20Smsaitoh
8601.20Smsaitohint
8611.20Smsaitohshpcmcia_memio_map(t, bpa, size, flags, bshp)
8621.20Smsaitoh	bus_space_tag_t t;
8631.20Smsaitoh	bus_addr_t bpa;
8641.20Smsaitoh	bus_size_t size;
8651.20Smsaitoh	int flags;
8661.20Smsaitoh	bus_space_handle_t *bshp;
8671.20Smsaitoh{
8681.20Smsaitoh	int error;
8691.20Smsaitoh	struct extent *ex;
8701.20Smsaitoh	bus_space_tag_t pt = t & ~SH3_BUS_SPACE_PCMCIA_8BIT;
8711.20Smsaitoh
8721.20Smsaitoh	if (pt != SH3_BUS_SPACE_PCMCIA_IO &&
8731.20Smsaitoh	    pt != SH3_BUS_SPACE_PCMCIA_MEM &&
8741.20Smsaitoh	    pt != SH3_BUS_SPACE_PCMCIA_ATT) {
8751.20Smsaitoh		*bshp = (bus_space_handle_t)bpa;
8761.20Smsaitoh
8771.20Smsaitoh		return 0;
8781.20Smsaitoh	}
8791.20Smsaitoh
8801.20Smsaitoh	ex = iomem_ex;
8811.20Smsaitoh
8821.20Smsaitoh#if 0
8831.20Smsaitoh	/*
8841.20Smsaitoh	 * Before we go any further, let's make sure that this
8851.20Smsaitoh	 * region is available.
8861.20Smsaitoh	 */
8871.20Smsaitoh	error = extent_alloc_region(ex, bpa, size,
8881.20Smsaitoh				    EX_NOWAIT | EX_MALLOCOK );
8891.20Smsaitoh	if (error){
8901.20Smsaitoh		printf("sh3_pcmcia_memio_map:extent_alloc_region error\n");
8911.20Smsaitoh		return (error);
8921.20Smsaitoh	}
8931.20Smsaitoh#endif
8941.20Smsaitoh
8951.20Smsaitoh	/*
8961.20Smsaitoh	 * For memory space, map the bus physical address to
8971.20Smsaitoh	 * a kernel virtual address.
8981.20Smsaitoh	 */
8991.20Smsaitoh	error = shpcmcia_mem_add_mapping(bpa, size, (int)t, bshp );
9001.20Smsaitoh#if 0
9011.20Smsaitoh	if (error) {
9021.20Smsaitoh		if (extent_free(ex, bpa, size, EX_NOWAIT | EX_MALLOCOK )) {
9031.20Smsaitoh			printf("sh3_pcmcia_memio_map: pa 0x%lx, size 0x%lx\n",
9041.20Smsaitoh			       bpa, size);
9051.20Smsaitoh			printf("sh3_pcmcia_memio_map: can't free region\n");
9061.20Smsaitoh		}
9071.20Smsaitoh	}
9081.20Smsaitoh#endif
9091.20Smsaitoh
9101.20Smsaitoh	return (error);
9111.20Smsaitoh}
9121.20Smsaitoh
9131.20Smsaitohint
9141.20Smsaitohshpcmcia_mem_add_mapping(bpa, size, type, bshp)
9151.20Smsaitoh	bus_addr_t bpa;
9161.20Smsaitoh	bus_size_t size;
9171.20Smsaitoh	int type;
9181.20Smsaitoh	bus_space_handle_t *bshp;
9191.20Smsaitoh{
9201.20Smsaitoh	u_long pa, endpa;
9211.20Smsaitoh	vaddr_t va;
9221.20Smsaitoh	pt_entry_t *pte;
9231.20Smsaitoh	unsigned int m = 0;
9241.20Smsaitoh	int io_type = type & ~SH3_BUS_SPACE_PCMCIA_8BIT;
9251.20Smsaitoh
9261.20Smsaitoh	pa = sh3_trunc_page(bpa);
9271.20Smsaitoh	endpa = sh3_round_page(bpa + size);
9281.20Smsaitoh
9291.20Smsaitoh#ifdef DIAGNOSTIC
9301.20Smsaitoh	if (endpa <= pa)
9311.20Smsaitoh		panic("sh3_pcmcia_mem_add_mapping: overflow");
9321.20Smsaitoh#endif
9331.20Smsaitoh
9341.20Smsaitoh	va = uvm_km_valloc(kernel_map, endpa - pa);
9351.20Smsaitoh	if (va == 0){
9361.20Smsaitoh		printf("shpcmcia_add_mapping: nomem \n");
9371.20Smsaitoh		return (ENOMEM);
9381.20Smsaitoh	}
9391.20Smsaitoh
9401.20Smsaitoh	*bshp = (bus_space_handle_t)(va + (bpa & PGOFSET));
9411.20Smsaitoh
9421.29Such#define MODE(t, s)							\
9431.29Such	(t) & SH3_BUS_SPACE_PCMCIA_8BIT ?				\
9441.29Such		_PG_PCMCIA_ ## s ## 8 :					\
9451.29Such		_PG_PCMCIA_ ## s ## 16
9461.29Such	switch (io_type) {
9471.29Such	default:
9481.29Such		panic("unknown pcmcia space.");
9491.29Such		/* NOTREACHED */
9501.29Such	case SH3_BUS_SPACE_PCMCIA_IO:
9511.29Such		m = MODE(type, IO);
9521.29Such		break;
9531.29Such	case SH3_BUS_SPACE_PCMCIA_MEM:
9541.29Such		m = MODE(type, MEM);
9551.29Such		break;
9561.29Such	case SH3_BUS_SPACE_PCMCIA_ATT:
9571.29Such		m = MODE(type, ATTR);
9581.29Such		break;
9591.20Smsaitoh	}
9601.29Such#undef MODE
9611.20Smsaitoh
9621.20Smsaitoh	for (; pa < endpa; pa += NBPG, va += NBPG) {
9631.20Smsaitoh		pmap_enter(pmap_kernel(), va, pa,
9641.22Smsaitoh		    VM_PROT_READ | VM_PROT_WRITE, PMAP_WIRED);
9651.20Smsaitoh
9661.20Smsaitoh		pte = kvtopte(va);
9671.20Smsaitoh		*pte &= ~PG_N;
9681.20Smsaitoh		*pte |= m;
9691.20Smsaitoh		pmap_update_pg(va);
9701.20Smsaitoh	}
9711.28Schris	pmap_update(pmap_kernel());
9721.20Smsaitoh
9731.20Smsaitoh	return 0;
9741.20Smsaitoh}
9751.20Smsaitoh
9761.20Smsaitohvoid
9771.20Smsaitohshpcmcia_memio_unmap(t, bsh, size)
9781.20Smsaitoh	bus_space_tag_t t;
9791.20Smsaitoh	bus_space_handle_t bsh;
9801.20Smsaitoh	bus_size_t size;
9811.20Smsaitoh{
9821.20Smsaitoh	struct extent *ex;
9831.20Smsaitoh	u_long va, endva;
9841.20Smsaitoh	bus_addr_t bpa;
9851.20Smsaitoh	bus_space_tag_t pt = t & ~SH3_BUS_SPACE_PCMCIA_8BIT;
9861.20Smsaitoh
9871.20Smsaitoh	if (pt != SH3_BUS_SPACE_PCMCIA_IO &&
9881.20Smsaitoh	    pt != SH3_BUS_SPACE_PCMCIA_MEM &&
9891.20Smsaitoh	    pt != SH3_BUS_SPACE_PCMCIA_ATT) {
9901.20Smsaitoh		return ;
9911.20Smsaitoh	}
9921.20Smsaitoh
9931.20Smsaitoh	ex = iomem_ex;
9941.20Smsaitoh
9951.20Smsaitoh	va = sh3_trunc_page(bsh);
9961.20Smsaitoh	endva = sh3_round_page(bsh + size);
9971.20Smsaitoh
9981.20Smsaitoh#ifdef DIAGNOSTIC
9991.20Smsaitoh	if (endva <= va)
10001.20Smsaitoh		panic("sh3_pcmcia_memio_unmap: overflow");
10011.20Smsaitoh#endif
10021.20Smsaitoh
10031.22Smsaitoh	pmap_extract(pmap_kernel(), va, &bpa);
10041.24Sichiro	bpa += bsh & PGOFSET;
10051.20Smsaitoh
10061.20Smsaitoh	/*
10071.20Smsaitoh	 * Free the kernel virtual mapping.
10081.20Smsaitoh	 */
10091.20Smsaitoh	uvm_km_free(kernel_map, va, endva - va);
10101.20Smsaitoh
10111.20Smsaitoh#if 0
10121.20Smsaitoh	if (extent_free(ex, bpa, size,
10131.20Smsaitoh			EX_NOWAIT | EX_MALLOCOK)) {
10141.20Smsaitoh		printf("sh3_pcmcia_memio_unmap: %s 0x%lx, size 0x%lx\n",
10151.20Smsaitoh		       "pa", bpa, size);
10161.20Smsaitoh		printf("sh3_pcmcia_memio_unmap: can't free region\n");
10171.20Smsaitoh	}
10181.20Smsaitoh#endif
10191.20Smsaitoh}
10201.20Smsaitoh
10211.20Smsaitohvoid
10221.20Smsaitohshpcmcia_memio_free(t, bsh, size)
10231.20Smsaitoh	bus_space_tag_t t;
10241.20Smsaitoh	bus_space_handle_t bsh;
10251.20Smsaitoh	bus_size_t size;
10261.20Smsaitoh{
10271.20Smsaitoh
10281.20Smsaitoh	/* sh3_pcmcia_memio_unmap() does all that we need to do. */
10291.20Smsaitoh	shpcmcia_memio_unmap(t, bsh, size);
10301.20Smsaitoh}
10311.20Smsaitoh
10321.20Smsaitohint
10331.20Smsaitohshpcmcia_memio_subregion(t, bsh, offset, size, nbshp)
10341.20Smsaitoh	bus_space_tag_t t;
10351.20Smsaitoh	bus_space_handle_t bsh;
10361.20Smsaitoh	bus_size_t offset, size;
10371.20Smsaitoh	bus_space_handle_t *nbshp;
10381.20Smsaitoh{
10391.20Smsaitoh
10401.20Smsaitoh	*nbshp = bsh + offset;
10411.20Smsaitoh	return (0);
10421.20Smsaitoh}
10431.20Smsaitoh
10441.20Smsaitoh#endif /* SH4_PCMCIA */
10451.1Sitojun
10461.18Smsaitoh#if !defined(DONT_INIT_BSC)
10471.1Sitojun/*
10481.1Sitojun * InitializeBsc
10491.1Sitojun * : BSC(Bus State Controler)
10501.1Sitojun */
10511.1Sitojunvoid InitializeBsc __P((void));
10521.1Sitojun
10531.1Sitojunvoid
10541.1SitojunInitializeBsc()
10551.1Sitojun{
10561.1Sitojun
10571.1Sitojun	/*
10581.1Sitojun	 * Drive RAS,CAS in stand by mode and bus release mode
10591.1Sitojun	 * Area0 = Normal memory, Area5,6=Normal(no burst)
10601.1Sitojun	 * Area2 = Normal memory, Area3 = SDRAM, Area5 = Normal memory
10611.1Sitojun	 * Area4 = Normal Memory
10621.1Sitojun	 * Area6 = Normal memory
10631.1Sitojun	 */
10641.3Smsaitoh	SHREG_BCR1 = BSC_BCR1_VAL;
10651.1Sitojun
10661.1Sitojun	/*
10671.1Sitojun	 * Bus Width
10681.1Sitojun	 * Area4: Bus width = 16bit
10691.1Sitojun	 * Area6,5 = 16bit
10701.1Sitojun	 * Area1 = 8bit
10711.1Sitojun	 * Area2,3: Bus width = 32bit
10721.1Sitojun	 */
10731.13Smsaitoh	SHREG_BCR2 = BSC_BCR2_VAL;
10741.1Sitojun
10751.1Sitojun	/*
10761.1Sitojun	 * Idle cycle number in transition area and read to write
10771.1Sitojun	 * Area6 = 3, Area5 = 3, Area4 = 3, Area3 = 3, Area2 = 3
10781.1Sitojun	 * Area1 = 3, Area0 = 3
10791.1Sitojun	 */
10801.3Smsaitoh	SHREG_WCR1 = BSC_WCR1_VAL;
10811.1Sitojun
10821.1Sitojun	/*
10831.1Sitojun	 * Wait cycle
10841.1Sitojun	 * Area 6 = 6
10851.1Sitojun	 * Area 5 = 2
10861.1Sitojun	 * Area 4 = 10
10871.1Sitojun	 * Area 3 = 3
10881.1Sitojun	 * Area 2,1 = 3
10891.1Sitojun	 * Area 0 = 6
10901.1Sitojun	 */
10911.3Smsaitoh	SHREG_WCR2 = BSC_WCR2_VAL;
10921.1Sitojun
10931.13Smsaitoh#if defined(SH4) && defined(BSC_WCR3_VAL)
10941.3Smsaitoh	SHREG_WCR3 = BSC_WCR3_VAL;
10951.1Sitojun#endif
10961.1Sitojun
10971.1Sitojun	/*
10981.1Sitojun	 * RAS pre-charge = 2cycle, RAS-CAS delay = 3 cycle,
10991.1Sitojun	 * write pre-charge=1cycle
11001.1Sitojun	 * CAS before RAS refresh RAS assert time = 3 cycle
11011.1Sitojun	 * Disable burst, Bus size=32bit, Column Address=10bit, Refresh ON
11021.1Sitojun	 * CAS before RAS refresh ON, EDO DRAM
11031.1Sitojun	 */
11041.3Smsaitoh	SHREG_MCR = BSC_MCR_VAL;
11051.1Sitojun
11061.11Smsaitoh#if defined(BSC_SDMR2_VAL)
11071.11Smsaitoh#define SDMR2	(*(volatile unsigned char  *)BSC_SDMR2_VAL)
11081.1Sitojun
11091.11Smsaitoh	SDMR2 = 0;
11101.11Smsaitoh#endif
11111.11Smsaitoh
11121.11Smsaitoh#if defined(BSC_SDMR3_VAL)
11131.19Smsaitoh#if !(defined(COMPUTEXEVB) && defined(SH7709A))
11141.11Smsaitoh#define SDMR3	(*(volatile unsigned char  *)BSC_SDMR3_VAL)
11151.11Smsaitoh
11161.11Smsaitoh	SDMR3 = 0;
11171.1Sitojun#else
11181.1Sitojun#define ADDSET	(*(volatile unsigned short *)0x1A000000)
11191.1Sitojun#define ADDRST	(*(volatile unsigned short *)0x18000000)
11201.11Smsaitoh#define SDMR3	(*(volatile unsigned char  *)BSC_SDMR3_VAL)
11211.1Sitojun
11221.1Sitojun	ADDSET = 0;
11231.11Smsaitoh	SDMR3 = 0;
11241.1Sitojun	ADDRST = 0;
11251.1Sitojun#endif
11261.1Sitojun#endif
11271.1Sitojun
11281.1Sitojun	/*
11291.1Sitojun	 * PCMCIA Control Register
11301.1Sitojun	 * OE/WE assert delay 3.5 cycle
11311.1Sitojun	 * OE/WE negate-address delay 3.5 cycle
11321.1Sitojun	 */
11331.1Sitojun#ifdef BSC_PCR_VAL
11341.12Smsaitoh	SHREG_PCR = BSC_PCR_VAL;
11351.1Sitojun#endif
11361.1Sitojun
11371.1Sitojun	/*
11381.1Sitojun	 * Refresh Timer Control/Status Register
11391.1Sitojun	 * Disable interrupt by CMF, closk 1/16, Disable OVF interrupt
11401.1Sitojun	 * Count Limit = 1024
11411.1Sitojun	 * In following statement, the reason why high byte = 0xa5(a4 in RFCR)
11421.1Sitojun	 * is the rule of SH3 in writing these register.
11431.1Sitojun	 */
11441.3Smsaitoh	SHREG_RTCSR = BSC_RTCSR_VAL;
11451.1Sitojun
11461.1Sitojun
11471.1Sitojun	/*
11481.1Sitojun	 * Refresh Timer Counter
11491.1Sitojun	 * Initialize to 0
11501.1Sitojun	 */
11511.9Smsaitoh#ifdef BSC_RTCNT_VAL
11521.3Smsaitoh	SHREG_RTCNT = BSC_RTCNT_VAL;
11531.9Smsaitoh#endif
11541.1Sitojun
11551.1Sitojun	/* set Refresh Time Constant Register */
11561.3Smsaitoh	SHREG_RTCOR = BSC_RTCOR_VAL;
11571.1Sitojun
11581.1Sitojun	/* init Refresh Count Register */
11591.1Sitojun#ifdef BSC_RFCR_VAL
11601.3Smsaitoh	SHREG_RFCR = BSC_RFCR_VAL;
11611.1Sitojun#endif
11621.1Sitojun
11631.1Sitojun	/* Set Clock mode (make internal clock double speed) */
11641.1Sitojun
11651.1Sitojun	SHREG_FRQCR = FRQCR_VAL;
11661.1Sitojun
11671.1Sitojun#ifndef MMEYE_NO_CACHE
11681.1Sitojun	/* Cache ON */
11691.6Smsaitoh	SHREG_CCR = CCR_CE;
11701.1Sitojun#endif
11711.1Sitojun}
11721.18Smsaitoh#endif
11731.1Sitojun
11741.1Sitojunvoid
11751.1Sitojunsh3_cache_on(void)
11761.1Sitojun{
11771.1Sitojun#ifndef MMEYE_NO_CACHE
11781.1Sitojun	/* Cache ON */
11791.6Smsaitoh	SHREG_CCR = CCR_CE;
11801.6Smsaitoh	SHREG_CCR = CCR_CF | CCR_CE;	/* cache clear */
11811.6Smsaitoh	SHREG_CCR = CCR_CE;		/* cache on */
11821.1Sitojun#endif
11831.1Sitojun}
11841.9Smsaitoh
11851.9Smsaitoh#ifdef SH4
11861.9Smsaitohvoid
11871.9Smsaitohsh4_cache_flush(addr)
11881.9Smsaitoh	vaddr_t addr;
11891.9Smsaitoh{
11901.9Smsaitoh#if 1
11911.9Smsaitoh#define SH_ADDR_ARRAY_BASE_ADDR 0xf4000000
11921.9Smsaitoh#define WRITE_ADDR_ARRAY( entry ) \
11931.9Smsaitoh	(*(volatile u_int32_t *)(SH_ADDR_ARRAY_BASE_ADDR|(entry)|0x00))
11941.9Smsaitoh
11951.9Smsaitoh	int entry;
11961.9Smsaitoh
11971.9Smsaitoh	entry = ((u_int32_t)addr) & 0x3fe0;
11981.9Smsaitoh
11991.9Smsaitoh	WRITE_ADDR_ARRAY(entry) = 0;
12001.9Smsaitoh#else
12011.9Smsaitoh	volatile int *p = (int *)IOM_RAM_BEGIN;
12021.9Smsaitoh	int i;
12031.9Smsaitoh	/* volatile */int d;
12041.9Smsaitoh
12051.9Smsaitoh	for(i = 0; i < 512; i++){
12061.9Smsaitoh		d = *p;
12071.9Smsaitoh		p += 8;
12081.9Smsaitoh	}
12091.9Smsaitoh#endif
12101.9Smsaitoh}
12111.9Smsaitoh#endif
12121.8Smsaitoh
12131.8Smsaitoh /* XXX This value depends on physical available memory */
12141.8Smsaitoh#define OSIMAGE_BUF_ADDR	(IOM_RAM_BEGIN + 0x00400000)
12151.8Smsaitoh
12161.1Sitojunvoid
12171.3SmsaitohLoadAndReset(osimage)
12181.3Smsaitoh	char *osimage;
12191.1Sitojun{
12201.1Sitojun	void *buf_addr;
12211.1Sitojun	u_long size;
12221.1Sitojun	u_long *src;
12231.1Sitojun	u_long *dest;
12241.1Sitojun	u_long csum = 0;
12251.1Sitojun	u_long csum2 = 0;
12261.1Sitojun	u_long size2;
12271.1Sitojun
12281.3Smsaitoh	printf("LoadAndReset: copy start\n");
12291.1Sitojun	buf_addr = (void *)OSIMAGE_BUF_ADDR;
12301.1Sitojun
12311.1Sitojun	size = *(u_long *)osimage;
12321.1Sitojun	src = (u_long *)osimage;
12331.1Sitojun	dest = buf_addr;
12341.1Sitojun
12351.3Smsaitoh	size = (size + sizeof(u_long) * 2 + 3) >> 2;
12361.1Sitojun	size2 = size;
12371.1Sitojun
12381.3Smsaitoh	while (size--) {
12391.1Sitojun		csum += *src;
12401.1Sitojun		*dest++ = *src++;
12411.1Sitojun	}
12421.1Sitojun
12431.1Sitojun	dest = buf_addr;
12441.1Sitojun	while (size2--)
12451.1Sitojun		csum2 += *dest++;
12461.1Sitojun
12471.3Smsaitoh	printf("LoadAndReset: copy end[%lx,%lx]\n", csum, csum2);
12481.1Sitojun	printf("start XLoadAndReset\n");
12491.1Sitojun
12501.1Sitojun	/* mask all externel interrupt (XXX) */
12511.1Sitojun
12521.1Sitojun	XLoadAndReset(buf_addr);
12531.1Sitojun}
1254