machdep.c revision 1.39
11.39Such/*	$NetBSD: machdep.c,v 1.39 2002/03/17 17:55:23 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/kernel.h>
871.1Sitojun#include <sys/user.h>
881.37Such#include <sys/mount.h>
891.1Sitojun#include <sys/reboot.h>
901.37Such#include <sys/sysctl.h>
911.1Sitojun#include <sys/msgbuf.h>
921.1Sitojun
931.37Such#include <uvm/uvm_extern.h>
941.1Sitojun
951.1Sitojun#include <dev/cons.h>
961.1Sitojun#include <machine/bus.h>
971.37Such#include <sh3/bscreg.h>
981.33Such#include <sh3/cpgreg.h>
991.33Such#include <sh3/cache_sh3.h>
1001.1Sitojun
1011.1Sitojun/* the following is used externally (sysctl_hw) */
1021.37Suchchar machine[] = MACHINE;		/* evbsh3 */
1031.37Suchchar machine_arch[] = MACHINE_ARCH;	/* sh3eb or sh3el */
1041.1Sitojun
1051.1Sitojunpaddr_t msgbuf_paddr;
1061.1Sitojunextern paddr_t avail_start, avail_end;
1071.1Sitojun
1081.1Sitojun#define IOM_RAM_END	((paddr_t)IOM_RAM_BEGIN + IOM_RAM_SIZE - 1)
1091.1Sitojun
1101.3Smsaitohvoid initSH3 __P((void *));
1111.3Smsaitohvoid LoadAndReset __P((char *));
1121.3Smsaitohvoid XLoadAndReset __P((char *));
1131.37Suchvoid consinit __P((void));
1141.37Such
1151.37Suchextern char start[], etext[], edata[], end[];
1161.1Sitojun
1171.1Sitojun/*
1181.1Sitojun * Machine-dependent startup code
1191.1Sitojun *
1201.1Sitojun * This is called from main() in kern/main.c.
1211.1Sitojun */
1221.1Sitojunvoid
1231.1Sitojuncpu_startup()
1241.1Sitojun{
1251.1Sitojun
1261.39Such	sh_startup();
1271.1Sitojun}
1281.1Sitojun
1291.1Sitojun/*
1301.1Sitojun * machine dependent system variables.
1311.1Sitojun */
1321.1Sitojunint
1331.1Sitojuncpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
1341.1Sitojun	int *name;
1351.1Sitojun	u_int namelen;
1361.1Sitojun	void *oldp;
1371.1Sitojun	size_t *oldlenp;
1381.1Sitojun	void *newp;
1391.1Sitojun	size_t newlen;
1401.1Sitojun	struct proc *p;
1411.1Sitojun{
1421.1Sitojun	dev_t consdev;
1431.1Sitojun	char *osimage;
1441.1Sitojun
1451.1Sitojun	/* all sysctl names at this level are terminal */
1461.1Sitojun	if (namelen != 1)
1471.1Sitojun		return (ENOTDIR);		/* overloaded */
1481.1Sitojun
1491.1Sitojun	switch (name[0]) {
1501.1Sitojun	case CPU_CONSDEV:
1511.1Sitojun		if (cn_tab != NULL)
1521.1Sitojun			consdev = cn_tab->cn_dev;
1531.1Sitojun		else
1541.1Sitojun			consdev = NODEV;
1551.1Sitojun		return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
1561.1Sitojun		    sizeof consdev));
1571.1Sitojun
1581.1Sitojun	case CPU_LOADANDRESET:
1591.1Sitojun		if (newp != NULL) {
1601.1Sitojun			osimage = (char *)(*(u_long *)newp);
1611.1Sitojun
1621.1Sitojun			LoadAndReset(osimage);
1631.1Sitojun			/* not reach here */
1641.1Sitojun		}
1651.1Sitojun		return (0);
1661.1Sitojun
1671.1Sitojun	default:
1681.1Sitojun		return (EOPNOTSUPP);
1691.1Sitojun	}
1701.1Sitojun	/* NOTREACHED */
1711.1Sitojun}
1721.1Sitojun
1731.1Sitojunvoid
1741.1Sitojuncpu_reboot(howto, bootstr)
1751.1Sitojun	int howto;
1761.1Sitojun	char *bootstr;
1771.1Sitojun{
1781.37Such	static int waittime = -1;
1791.1Sitojun
1801.1Sitojun	if (cold) {
1811.1Sitojun		howto |= RB_HALT;
1821.1Sitojun		goto haltsys;
1831.1Sitojun	}
1841.1Sitojun
1851.1Sitojun	boothowto = howto;
1861.1Sitojun	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
1871.1Sitojun		waittime = 0;
1881.1Sitojun		vfs_shutdown();
1891.1Sitojun		/*
1901.1Sitojun		 * If we've been adjusting the clock, the todr
1911.1Sitojun		 * will be out of synch; adjust it now.
1921.1Sitojun		 */
1931.1Sitojun		/* resettodr(); */
1941.1Sitojun	}
1951.1Sitojun
1961.1Sitojun	/* Disable interrupts. */
1971.1Sitojun	splhigh();
1981.1Sitojun
1991.1Sitojun	/* Do a dump if requested. */
2001.1Sitojun	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
2011.1Sitojun		dumpsys();
2021.1Sitojun
2031.1Sitojunhaltsys:
2041.1Sitojun	doshutdownhooks();
2051.1Sitojun
2061.1Sitojun	if (howto & RB_HALT) {
2071.1Sitojun		printf("\n");
2081.1Sitojun		printf("The operating system has halted.\n");
2091.1Sitojun		printf("Please press any key to reboot.\n\n");
2101.1Sitojun		cngetc();
2111.1Sitojun	}
2121.1Sitojun
2131.1Sitojun	printf("rebooting...\n");
2141.1Sitojun	cpu_reset();
2151.1Sitojun	for(;;)
2161.1Sitojun		;
2171.1Sitojun	/*NOTREACHED*/
2181.1Sitojun}
2191.1Sitojun
2201.1Sitojunvoid
2211.37SuchinitSH3(void *pc)	/* XXX return address */
2221.1Sitojun{
2231.37Such	vaddr_t kernend;
2241.37Such	vsize_t sz;
2251.3Smsaitoh
2261.37Such	kernend = sh3_round_page(end);
2271.3Smsaitoh
2281.37Such	/* Clear bss */
2291.37Such	memset(edata, 0, end - edata);
2301.3Smsaitoh
2311.37Such	/* Initilize CPU ops. */
2321.30Such#if defined(SH3) && defined(SH4)
2331.30Such#error "don't define both SH3 and SH4"
2341.30Such#elif defined(SH3)
2351.30Such	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_UNKNOWN);
2361.30Such#elif defined(SH4)
2371.30Such	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_UNKNOWN);
2381.30Such#else
2391.30Such#error "define SH3 or SH4"
2401.30Such#endif
2411.37Such	/* Initialize proc0 and enable MMU. */
2421.37Such	sz = sh_proc0_init(kernend, IOM_RAM_BEGIN, IOM_RAM_END);
2431.3Smsaitoh
2441.37Such	/* Number of pages of physmem addr space */
2451.37Such	physmem = atop(IOM_RAM_END - IOM_RAM_BEGIN + 1);
2461.3Smsaitoh
2471.3Smsaitoh	/* avail_start is first available physical memory address */
2481.37Such	avail_start = kernend + sz;
2491.37Such	avail_end = IOM_RAM_END + 1;
2501.1Sitojun
2511.37Such	consinit();
2521.1Sitojun
2531.1Sitojun	/* Call pmap initialization to make new kernel address space */
2541.37Such	pmap_bootstrap(VM_MIN_KERNEL_ADDRESS);
2551.1Sitojun
2561.1Sitojun	/*
2571.1Sitojun	 * Initialize error message buffer (at end of core).
2581.1Sitojun	 */
2591.1Sitojun	initmsgbuf((caddr_t)msgbuf_paddr, round_page(MSGBUFSIZE));
2601.1Sitojun
2611.3Smsaitoh	/*
2621.3Smsaitoh	 * XXX We can't return here, because we change stack pointer.
2631.3Smsaitoh	 *     So jump to return address directly.
2641.3Smsaitoh	 */
2651.37Such	__asm __volatile (
2661.37Such		"jmp	@%0;"
2671.38Such		"mov	%1, r15" :: "r"(pc), "r"(proc0.p_addr->u_pcb.pcb_sp));
2681.1Sitojun}
2691.1Sitojun
2701.1Sitojun/*
2711.1Sitojun * consinit:
2721.1Sitojun * initialize the system console.
2731.1Sitojun * XXX - shouldn't deal with this initted thing, but then,
2741.1Sitojun * it shouldn't be called from init386 either.
2751.1Sitojun */
2761.1Sitojunvoid
2771.1Sitojunconsinit()
2781.1Sitojun{
2791.1Sitojun	static int initted;
2801.1Sitojun
2811.1Sitojun	if (initted)
2821.1Sitojun		return;
2831.1Sitojun	initted = 1;
2841.1Sitojun
2851.1Sitojun	cninit();
2861.1Sitojun
2871.1Sitojun#ifdef DDB
2881.1Sitojun	ddb_init();
2891.1Sitojun#endif
2901.1Sitojun}
2911.1Sitojun
2921.1Sitojunint
2931.1Sitojunbus_space_map (t, addr, size, flags, bshp)
2941.1Sitojun	bus_space_tag_t t;
2951.1Sitojun	bus_addr_t addr;
2961.1Sitojun	bus_size_t size;
2971.1Sitojun	int flags;
2981.1Sitojun	bus_space_handle_t *bshp;
2991.1Sitojun{
3001.1Sitojun
3011.1Sitojun	*bshp = (bus_space_handle_t)addr;
3021.1Sitojun
3031.1Sitojun	return 0;
3041.1Sitojun}
3051.1Sitojun
3061.1Sitojunint
3071.1Sitojunsh_memio_subregion(t, bsh, offset, size, nbshp)
3081.1Sitojun	bus_space_tag_t t;
3091.1Sitojun	bus_space_handle_t bsh;
3101.1Sitojun	bus_size_t offset, size;
3111.1Sitojun	bus_space_handle_t *nbshp;
3121.1Sitojun{
3131.1Sitojun
3141.1Sitojun	*nbshp = bsh + offset;
3151.1Sitojun	return (0);
3161.1Sitojun}
3171.1Sitojun
3181.1Sitojunint
3191.1Sitojunsh_memio_alloc(t, rstart, rend, size, alignment, boundary, flags,
3201.1Sitojun	       bpap, bshp)
3211.1Sitojun	bus_space_tag_t t;
3221.1Sitojun	bus_addr_t rstart, rend;
3231.1Sitojun	bus_size_t size, alignment, boundary;
3241.1Sitojun	int flags;
3251.1Sitojun	bus_addr_t *bpap;
3261.1Sitojun	bus_space_handle_t *bshp;
3271.1Sitojun{
3281.1Sitojun	*bshp = *bpap = rstart;
3291.1Sitojun
3301.1Sitojun	return (0);
3311.1Sitojun}
3321.1Sitojun
3331.1Sitojunvoid
3341.1Sitojunsh_memio_free(t, bsh, size)
3351.1Sitojun	bus_space_tag_t t;
3361.1Sitojun	bus_space_handle_t bsh;
3371.1Sitojun	bus_size_t size;
3381.1Sitojun{
3391.1Sitojun
3401.1Sitojun}
3411.1Sitojun
3421.1Sitojunvoid
3431.1Sitojunsh_memio_unmap(t, bsh, size)
3441.1Sitojun	bus_space_tag_t t;
3451.1Sitojun	bus_space_handle_t bsh;
3461.1Sitojun	bus_size_t size;
3471.1Sitojun{
3481.1Sitojun	return;
3491.1Sitojun}
3501.20Smsaitoh
3511.20Smsaitoh#ifdef SH4_PCMCIA
3521.20Smsaitoh
3531.20Smsaitohint
3541.20Smsaitohshpcmcia_memio_map(t, bpa, size, flags, bshp)
3551.20Smsaitoh	bus_space_tag_t t;
3561.20Smsaitoh	bus_addr_t bpa;
3571.20Smsaitoh	bus_size_t size;
3581.20Smsaitoh	int flags;
3591.20Smsaitoh	bus_space_handle_t *bshp;
3601.20Smsaitoh{
3611.20Smsaitoh	int error;
3621.20Smsaitoh	struct extent *ex;
3631.20Smsaitoh	bus_space_tag_t pt = t & ~SH3_BUS_SPACE_PCMCIA_8BIT;
3641.20Smsaitoh
3651.20Smsaitoh	if (pt != SH3_BUS_SPACE_PCMCIA_IO &&
3661.20Smsaitoh	    pt != SH3_BUS_SPACE_PCMCIA_MEM &&
3671.20Smsaitoh	    pt != SH3_BUS_SPACE_PCMCIA_ATT) {
3681.20Smsaitoh		*bshp = (bus_space_handle_t)bpa;
3691.20Smsaitoh
3701.20Smsaitoh		return 0;
3711.20Smsaitoh	}
3721.20Smsaitoh
3731.20Smsaitoh	ex = iomem_ex;
3741.20Smsaitoh
3751.20Smsaitoh#if 0
3761.20Smsaitoh	/*
3771.20Smsaitoh	 * Before we go any further, let's make sure that this
3781.20Smsaitoh	 * region is available.
3791.20Smsaitoh	 */
3801.20Smsaitoh	error = extent_alloc_region(ex, bpa, size,
3811.20Smsaitoh				    EX_NOWAIT | EX_MALLOCOK );
3821.20Smsaitoh	if (error){
3831.20Smsaitoh		printf("sh3_pcmcia_memio_map:extent_alloc_region error\n");
3841.20Smsaitoh		return (error);
3851.20Smsaitoh	}
3861.20Smsaitoh#endif
3871.20Smsaitoh
3881.20Smsaitoh	/*
3891.20Smsaitoh	 * For memory space, map the bus physical address to
3901.20Smsaitoh	 * a kernel virtual address.
3911.20Smsaitoh	 */
3921.20Smsaitoh	error = shpcmcia_mem_add_mapping(bpa, size, (int)t, bshp );
3931.20Smsaitoh#if 0
3941.20Smsaitoh	if (error) {
3951.20Smsaitoh		if (extent_free(ex, bpa, size, EX_NOWAIT | EX_MALLOCOK )) {
3961.20Smsaitoh			printf("sh3_pcmcia_memio_map: pa 0x%lx, size 0x%lx\n",
3971.20Smsaitoh			       bpa, size);
3981.20Smsaitoh			printf("sh3_pcmcia_memio_map: can't free region\n");
3991.20Smsaitoh		}
4001.20Smsaitoh	}
4011.20Smsaitoh#endif
4021.20Smsaitoh
4031.20Smsaitoh	return (error);
4041.20Smsaitoh}
4051.20Smsaitoh
4061.20Smsaitohint
4071.20Smsaitohshpcmcia_mem_add_mapping(bpa, size, type, bshp)
4081.20Smsaitoh	bus_addr_t bpa;
4091.20Smsaitoh	bus_size_t size;
4101.20Smsaitoh	int type;
4111.20Smsaitoh	bus_space_handle_t *bshp;
4121.20Smsaitoh{
4131.20Smsaitoh	u_long pa, endpa;
4141.20Smsaitoh	vaddr_t va;
4151.20Smsaitoh	pt_entry_t *pte;
4161.20Smsaitoh	unsigned int m = 0;
4171.20Smsaitoh	int io_type = type & ~SH3_BUS_SPACE_PCMCIA_8BIT;
4181.20Smsaitoh
4191.20Smsaitoh	pa = sh3_trunc_page(bpa);
4201.20Smsaitoh	endpa = sh3_round_page(bpa + size);
4211.20Smsaitoh
4221.20Smsaitoh#ifdef DIAGNOSTIC
4231.20Smsaitoh	if (endpa <= pa)
4241.20Smsaitoh		panic("sh3_pcmcia_mem_add_mapping: overflow");
4251.20Smsaitoh#endif
4261.20Smsaitoh
4271.20Smsaitoh	va = uvm_km_valloc(kernel_map, endpa - pa);
4281.20Smsaitoh	if (va == 0){
4291.20Smsaitoh		printf("shpcmcia_add_mapping: nomem \n");
4301.20Smsaitoh		return (ENOMEM);
4311.20Smsaitoh	}
4321.20Smsaitoh
4331.20Smsaitoh	*bshp = (bus_space_handle_t)(va + (bpa & PGOFSET));
4341.20Smsaitoh
4351.29Such#define MODE(t, s)							\
4361.29Such	(t) & SH3_BUS_SPACE_PCMCIA_8BIT ?				\
4371.29Such		_PG_PCMCIA_ ## s ## 8 :					\
4381.29Such		_PG_PCMCIA_ ## s ## 16
4391.29Such	switch (io_type) {
4401.29Such	default:
4411.29Such		panic("unknown pcmcia space.");
4421.29Such		/* NOTREACHED */
4431.29Such	case SH3_BUS_SPACE_PCMCIA_IO:
4441.29Such		m = MODE(type, IO);
4451.29Such		break;
4461.29Such	case SH3_BUS_SPACE_PCMCIA_MEM:
4471.29Such		m = MODE(type, MEM);
4481.29Such		break;
4491.29Such	case SH3_BUS_SPACE_PCMCIA_ATT:
4501.29Such		m = MODE(type, ATTR);
4511.29Such		break;
4521.20Smsaitoh	}
4531.29Such#undef MODE
4541.20Smsaitoh
4551.20Smsaitoh	for (; pa < endpa; pa += NBPG, va += NBPG) {
4561.20Smsaitoh		pmap_enter(pmap_kernel(), va, pa,
4571.22Smsaitoh		    VM_PROT_READ | VM_PROT_WRITE, PMAP_WIRED);
4581.20Smsaitoh
4591.20Smsaitoh		pte = kvtopte(va);
4601.20Smsaitoh		*pte &= ~PG_N;
4611.20Smsaitoh		*pte |= m;
4621.20Smsaitoh		pmap_update_pg(va);
4631.20Smsaitoh	}
4641.28Schris	pmap_update(pmap_kernel());
4651.20Smsaitoh
4661.20Smsaitoh	return 0;
4671.20Smsaitoh}
4681.20Smsaitoh
4691.20Smsaitohvoid
4701.20Smsaitohshpcmcia_memio_unmap(t, bsh, size)
4711.20Smsaitoh	bus_space_tag_t t;
4721.20Smsaitoh	bus_space_handle_t bsh;
4731.20Smsaitoh	bus_size_t size;
4741.20Smsaitoh{
4751.20Smsaitoh	struct extent *ex;
4761.20Smsaitoh	u_long va, endva;
4771.20Smsaitoh	bus_addr_t bpa;
4781.20Smsaitoh	bus_space_tag_t pt = t & ~SH3_BUS_SPACE_PCMCIA_8BIT;
4791.20Smsaitoh
4801.20Smsaitoh	if (pt != SH3_BUS_SPACE_PCMCIA_IO &&
4811.20Smsaitoh	    pt != SH3_BUS_SPACE_PCMCIA_MEM &&
4821.20Smsaitoh	    pt != SH3_BUS_SPACE_PCMCIA_ATT) {
4831.20Smsaitoh		return ;
4841.20Smsaitoh	}
4851.20Smsaitoh
4861.20Smsaitoh	ex = iomem_ex;
4871.20Smsaitoh
4881.20Smsaitoh	va = sh3_trunc_page(bsh);
4891.20Smsaitoh	endva = sh3_round_page(bsh + size);
4901.20Smsaitoh
4911.20Smsaitoh#ifdef DIAGNOSTIC
4921.20Smsaitoh	if (endva <= va)
4931.20Smsaitoh		panic("sh3_pcmcia_memio_unmap: overflow");
4941.20Smsaitoh#endif
4951.20Smsaitoh
4961.22Smsaitoh	pmap_extract(pmap_kernel(), va, &bpa);
4971.24Sichiro	bpa += bsh & PGOFSET;
4981.20Smsaitoh
4991.20Smsaitoh	/*
5001.20Smsaitoh	 * Free the kernel virtual mapping.
5011.20Smsaitoh	 */
5021.20Smsaitoh	uvm_km_free(kernel_map, va, endva - va);
5031.20Smsaitoh
5041.20Smsaitoh#if 0
5051.20Smsaitoh	if (extent_free(ex, bpa, size,
5061.20Smsaitoh			EX_NOWAIT | EX_MALLOCOK)) {
5071.20Smsaitoh		printf("sh3_pcmcia_memio_unmap: %s 0x%lx, size 0x%lx\n",
5081.20Smsaitoh		       "pa", bpa, size);
5091.20Smsaitoh		printf("sh3_pcmcia_memio_unmap: can't free region\n");
5101.20Smsaitoh	}
5111.20Smsaitoh#endif
5121.20Smsaitoh}
5131.20Smsaitoh
5141.20Smsaitohvoid
5151.20Smsaitohshpcmcia_memio_free(t, bsh, size)
5161.20Smsaitoh	bus_space_tag_t t;
5171.20Smsaitoh	bus_space_handle_t bsh;
5181.20Smsaitoh	bus_size_t size;
5191.20Smsaitoh{
5201.20Smsaitoh
5211.20Smsaitoh	/* sh3_pcmcia_memio_unmap() does all that we need to do. */
5221.20Smsaitoh	shpcmcia_memio_unmap(t, bsh, size);
5231.20Smsaitoh}
5241.20Smsaitoh
5251.20Smsaitohint
5261.20Smsaitohshpcmcia_memio_subregion(t, bsh, offset, size, nbshp)
5271.20Smsaitoh	bus_space_tag_t t;
5281.20Smsaitoh	bus_space_handle_t bsh;
5291.20Smsaitoh	bus_size_t offset, size;
5301.20Smsaitoh	bus_space_handle_t *nbshp;
5311.20Smsaitoh{
5321.20Smsaitoh
5331.20Smsaitoh	*nbshp = bsh + offset;
5341.20Smsaitoh	return (0);
5351.20Smsaitoh}
5361.20Smsaitoh
5371.20Smsaitoh#endif /* SH4_PCMCIA */
5381.1Sitojun
5391.18Smsaitoh#if !defined(DONT_INIT_BSC)
5401.1Sitojun/*
5411.1Sitojun * InitializeBsc
5421.1Sitojun * : BSC(Bus State Controler)
5431.1Sitojun */
5441.1Sitojunvoid InitializeBsc __P((void));
5451.1Sitojun
5461.1Sitojunvoid
5471.1SitojunInitializeBsc()
5481.1Sitojun{
5491.1Sitojun
5501.1Sitojun	/*
5511.1Sitojun	 * Drive RAS,CAS in stand by mode and bus release mode
5521.1Sitojun	 * Area0 = Normal memory, Area5,6=Normal(no burst)
5531.1Sitojun	 * Area2 = Normal memory, Area3 = SDRAM, Area5 = Normal memory
5541.1Sitojun	 * Area4 = Normal Memory
5551.1Sitojun	 * Area6 = Normal memory
5561.1Sitojun	 */
5571.33Such#if defined(SH3)
5581.33Such	_reg_write_2(SH3_BCR1, BSC_BCR1_VAL);
5591.33Such#elif defined(SH4)
5601.33Such	_reg_write_4(SH4_BCR1, BSC_BCR1_VAL);
5611.33Such#endif
5621.1Sitojun
5631.1Sitojun	/*
5641.1Sitojun	 * Bus Width
5651.1Sitojun	 * Area4: Bus width = 16bit
5661.1Sitojun	 * Area6,5 = 16bit
5671.1Sitojun	 * Area1 = 8bit
5681.1Sitojun	 * Area2,3: Bus width = 32bit
5691.1Sitojun	 */
5701.33Such	_reg_write_2(SH_(BCR2), BSC_BCR2_VAL);
5711.1Sitojun
5721.1Sitojun	/*
5731.1Sitojun	 * Idle cycle number in transition area and read to write
5741.1Sitojun	 * Area6 = 3, Area5 = 3, Area4 = 3, Area3 = 3, Area2 = 3
5751.1Sitojun	 * Area1 = 3, Area0 = 3
5761.1Sitojun	 */
5771.33Such#if defined(SH3)
5781.33Such	_reg_write_2(SH3_WCR1, BSC_WCR1_VAL);
5791.33Such#elif defined(SH4)
5801.33Such	_reg_write_4(SH4_WCR1, BSC_WCR1_VAL);
5811.33Such#endif
5821.1Sitojun
5831.1Sitojun	/*
5841.1Sitojun	 * Wait cycle
5851.1Sitojun	 * Area 6 = 6
5861.1Sitojun	 * Area 5 = 2
5871.1Sitojun	 * Area 4 = 10
5881.1Sitojun	 * Area 3 = 3
5891.1Sitojun	 * Area 2,1 = 3
5901.1Sitojun	 * Area 0 = 6
5911.1Sitojun	 */
5921.33Such#if defined(SH3)
5931.33Such	_reg_write_2(SH3_WCR2, BSC_WCR2_VAL);
5941.33Such#elif defined(SH4)
5951.33Such	_reg_write_4(SH4_WCR2, BSC_WCR2_VAL);
5961.33Such#endif
5971.1Sitojun
5981.13Smsaitoh#if defined(SH4) && defined(BSC_WCR3_VAL)
5991.33Such	_reg_write_4(SH4_WCR3, BSC_WCR3_VAL);
6001.1Sitojun#endif
6011.1Sitojun
6021.1Sitojun	/*
6031.1Sitojun	 * RAS pre-charge = 2cycle, RAS-CAS delay = 3 cycle,
6041.1Sitojun	 * write pre-charge=1cycle
6051.1Sitojun	 * CAS before RAS refresh RAS assert time = 3 cycle
6061.1Sitojun	 * Disable burst, Bus size=32bit, Column Address=10bit, Refresh ON
6071.1Sitojun	 * CAS before RAS refresh ON, EDO DRAM
6081.1Sitojun	 */
6091.33Such#if defined(SH3)
6101.33Such	_reg_write_2(SH3_MCR, BSC_MCR_VAL);
6111.33Such#elif defined(SH4)
6121.33Such	_reg_write_4(SH4_MCR, BSC_MCR_VAL);
6131.33Such#endif
6141.1Sitojun
6151.11Smsaitoh#if defined(BSC_SDMR2_VAL)
6161.33Such	_reg_write_1(BSC_SDMR2_VAL, 0);
6171.11Smsaitoh#endif
6181.11Smsaitoh
6191.11Smsaitoh#if defined(BSC_SDMR3_VAL)
6201.19Smsaitoh#if !(defined(COMPUTEXEVB) && defined(SH7709A))
6211.33Such	_reg_write_1(BSC_SDMR3_VAL, 0);
6221.1Sitojun#else
6231.33Such	_reg_write_2(0x1a000000, 0);	/* ADDSET */
6241.33Such	_reg_write_1(BSC_SDMR3_VAL, 0);
6251.33Such	_reg_write_2(0x18000000, 0);	/* ADDRST */
6261.33Such#endif /* !(COMPUTEXEVB && SH7709A) */
6271.33Such#endif /* BSC_SDMR3_VAL */
6281.1Sitojun
6291.1Sitojun	/*
6301.1Sitojun	 * PCMCIA Control Register
6311.1Sitojun	 * OE/WE assert delay 3.5 cycle
6321.1Sitojun	 * OE/WE negate-address delay 3.5 cycle
6331.1Sitojun	 */
6341.1Sitojun#ifdef BSC_PCR_VAL
6351.33Such	_reg_write_2(SH_(PCR), BSC_PCR_VAL);
6361.1Sitojun#endif
6371.1Sitojun
6381.1Sitojun	/*
6391.1Sitojun	 * Refresh Timer Control/Status Register
6401.1Sitojun	 * Disable interrupt by CMF, closk 1/16, Disable OVF interrupt
6411.1Sitojun	 * Count Limit = 1024
6421.1Sitojun	 * In following statement, the reason why high byte = 0xa5(a4 in RFCR)
6431.1Sitojun	 * is the rule of SH3 in writing these register.
6441.1Sitojun	 */
6451.33Such	_reg_write_2(SH_(RTCSR), BSC_RTCSR_VAL);
6461.1Sitojun
6471.1Sitojun	/*
6481.1Sitojun	 * Refresh Timer Counter
6491.1Sitojun	 * Initialize to 0
6501.1Sitojun	 */
6511.9Smsaitoh#ifdef BSC_RTCNT_VAL
6521.33Such	_reg_write_2(SH_(RTCNT), BSC_RTCNT_VAL);
6531.9Smsaitoh#endif
6541.1Sitojun
6551.1Sitojun	/* set Refresh Time Constant Register */
6561.33Such	_reg_write_2(SH_(RTCOR), BSC_RTCOR_VAL);
6571.1Sitojun
6581.1Sitojun	/* init Refresh Count Register */
6591.1Sitojun#ifdef BSC_RFCR_VAL
6601.33Such	_reg_write_2(SH_(RFCR), BSC_RFCR_VAL);
6611.1Sitojun#endif
6621.1Sitojun
6631.33Such	/*
6641.33Such	 * Clock Pulse Generator
6651.33Such	 */
6661.1Sitojun	/* Set Clock mode (make internal clock double speed) */
6671.33Such	_reg_write_2(SH_(FRQCR), FRQCR_VAL);
6681.1Sitojun
6691.33Such	/*
6701.33Such	 * Cache
6711.33Such	 */
6721.33Such#ifndef CACHE_DISABLE
6731.1Sitojun	/* Cache ON */
6741.33Such	_reg_write_4(SH_(CCR), 0x1);
6751.1Sitojun#endif
6761.1Sitojun}
6771.33Such#endif /* !DONT_INIT_BSC */
6781.9Smsaitoh
6791.8Smsaitoh
6801.8Smsaitoh /* XXX This value depends on physical available memory */
6811.8Smsaitoh#define OSIMAGE_BUF_ADDR	(IOM_RAM_BEGIN + 0x00400000)
6821.8Smsaitoh
6831.1Sitojunvoid
6841.3SmsaitohLoadAndReset(osimage)
6851.3Smsaitoh	char *osimage;
6861.1Sitojun{
6871.1Sitojun	void *buf_addr;
6881.1Sitojun	u_long size;
6891.1Sitojun	u_long *src;
6901.1Sitojun	u_long *dest;
6911.1Sitojun	u_long csum = 0;
6921.1Sitojun	u_long csum2 = 0;
6931.1Sitojun	u_long size2;
6941.1Sitojun
6951.3Smsaitoh	printf("LoadAndReset: copy start\n");
6961.1Sitojun	buf_addr = (void *)OSIMAGE_BUF_ADDR;
6971.1Sitojun
6981.1Sitojun	size = *(u_long *)osimage;
6991.1Sitojun	src = (u_long *)osimage;
7001.1Sitojun	dest = buf_addr;
7011.1Sitojun
7021.3Smsaitoh	size = (size + sizeof(u_long) * 2 + 3) >> 2;
7031.1Sitojun	size2 = size;
7041.1Sitojun
7051.3Smsaitoh	while (size--) {
7061.1Sitojun		csum += *src;
7071.1Sitojun		*dest++ = *src++;
7081.1Sitojun	}
7091.1Sitojun
7101.1Sitojun	dest = buf_addr;
7111.1Sitojun	while (size2--)
7121.1Sitojun		csum2 += *dest++;
7131.1Sitojun
7141.3Smsaitoh	printf("LoadAndReset: copy end[%lx,%lx]\n", csum, csum2);
7151.1Sitojun	printf("start XLoadAndReset\n");
7161.1Sitojun
7171.1Sitojun	/* mask all externel interrupt (XXX) */
7181.1Sitojun
7191.1Sitojun	XLoadAndReset(buf_addr);
7201.1Sitojun}
721