machdep.c revision 1.66
11.66Sdsl/*	$NetBSD: machdep.c,v 1.66 2009/03/14 21:04:09 dsl 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 *
201.1Sitojun * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
211.1Sitojun * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
221.1Sitojun * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
231.1Sitojun * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
241.1Sitojun * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
251.1Sitojun * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
261.1Sitojun * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
271.1Sitojun * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
281.1Sitojun * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
291.1Sitojun * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
301.1Sitojun * POSSIBILITY OF SUCH DAMAGE.
311.1Sitojun */
321.1Sitojun
331.1Sitojun/*-
341.1Sitojun * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
351.1Sitojun * All rights reserved.
361.1Sitojun *
371.1Sitojun * This code is derived from software contributed to Berkeley by
381.1Sitojun * William Jolitz.
391.1Sitojun *
401.1Sitojun * Redistribution and use in source and binary forms, with or without
411.1Sitojun * modification, are permitted provided that the following conditions
421.1Sitojun * are met:
431.1Sitojun * 1. Redistributions of source code must retain the above copyright
441.1Sitojun *    notice, this list of conditions and the following disclaimer.
451.1Sitojun * 2. Redistributions in binary form must reproduce the above copyright
461.1Sitojun *    notice, this list of conditions and the following disclaimer in the
471.1Sitojun *    documentation and/or other materials provided with the distribution.
481.48Sagc * 3. Neither the name of the University nor the names of its contributors
491.1Sitojun *    may be used to endorse or promote products derived from this software
501.1Sitojun *    without specific prior written permission.
511.1Sitojun *
521.1Sitojun * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
531.1Sitojun * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
541.1Sitojun * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
551.1Sitojun * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
561.1Sitojun * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
571.1Sitojun * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
581.1Sitojun * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
591.1Sitojun * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
601.1Sitojun * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
611.1Sitojun * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
621.1Sitojun * SUCH DAMAGE.
631.1Sitojun *
641.1Sitojun *	@(#)machdep.c	7.4 (Berkeley) 6/3/91
651.1Sitojun */
661.47Slukem
671.47Slukem#include <sys/cdefs.h>
681.66Sdsl__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.66 2009/03/14 21:04:09 dsl Exp $");
691.1Sitojun
701.1Sitojun#include "opt_ddb.h"
711.26Slukem#include "opt_kgdb.h"
721.1Sitojun#include "opt_memsize.h"
731.1Sitojun#include "opt_initbsc.h"
741.1Sitojun
751.1Sitojun#include <sys/param.h>
761.1Sitojun#include <sys/systm.h>
771.1Sitojun#include <sys/kernel.h>
781.1Sitojun#include <sys/user.h>
791.37Such#include <sys/mount.h>
801.1Sitojun#include <sys/reboot.h>
811.37Such#include <sys/sysctl.h>
821.46Sragge#include <sys/ksyms.h>
831.61Sdyoung#include <sys/device.h>
841.1Sitojun
851.37Such#include <uvm/uvm_extern.h>
861.1Sitojun
871.1Sitojun#include <dev/cons.h>
881.40Such
891.37Such#include <sh3/bscreg.h>
901.33Such#include <sh3/cpgreg.h>
911.33Such#include <sh3/cache_sh3.h>
921.40Such#include <sh3/cache_sh4.h>
931.40Such#include <sh3/exception.h>
941.40Such
951.40Such#include <machine/bus.h>
961.40Such#include <machine/intr.h>
971.40Such
981.40Such#ifdef DDB
991.40Such#include <machine/db_machdep.h>
1001.40Such#include <ddb/db_extern.h>
1011.40Such#endif
1021.1Sitojun
1031.46Sragge#include "ksyms.h"
1041.46Sragge
1051.1Sitojun/* the following is used externally (sysctl_hw) */
1061.37Suchchar machine[] = MACHINE;		/* evbsh3 */
1071.37Suchchar machine_arch[] = MACHINE_ARCH;	/* sh3eb or sh3el */
1081.1Sitojun
1091.64Sdslvoid initSH3(void *);
1101.64Sdslvoid LoadAndReset(const char *);
1111.64Sdslvoid XLoadAndReset(char *);
1121.1Sitojun
1131.1Sitojun/*
1141.1Sitojun * Machine-dependent startup code
1151.1Sitojun *
1161.1Sitojun * This is called from main() in kern/main.c.
1171.1Sitojun */
1181.1Sitojunvoid
1191.1Sitojuncpu_startup()
1201.1Sitojun{
1211.1Sitojun
1221.39Such	sh_startup();
1231.1Sitojun}
1241.1Sitojun
1251.1Sitojun/*
1261.1Sitojun * machine dependent system variables.
1271.1Sitojun */
1281.49Satatatstatic int
1291.49Satatatsysctl_machdep_loadandreset(SYSCTLFN_ARGS)
1301.1Sitojun{
1311.54She	const char *osimage;
1321.49Satatat	int error;
1331.1Sitojun
1341.54She	error = sysctl_lookup(SYSCTLFN_CALL(__UNCONST(rnode)));
1351.49Satatat	if (error || newp == NULL)
1361.49Satatat		return (error);
1371.49Satatat
1381.54She	osimage = (const char *)(*(const u_long *)newp);
1391.49Satatat	LoadAndReset(osimage);
1401.49Satatat	/* not reach here */
1411.49Satatat	return (0);
1421.49Satatat}
1431.49Satatat
1441.49SatatatSYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
1451.49Satatat{
1461.49Satatat
1471.51Satatat	sysctl_createv(clog, 0, NULL, NULL,
1481.51Satatat		       CTLFLAG_PERMANENT,
1491.49Satatat		       CTLTYPE_NODE, "machdep", NULL,
1501.49Satatat		       NULL, 0, NULL, 0,
1511.49Satatat		       CTL_MACHDEP, CTL_EOL);
1521.49Satatat
1531.51Satatat	sysctl_createv(clog, 0, NULL, NULL,
1541.51Satatat		       CTLFLAG_PERMANENT,
1551.49Satatat		       CTLTYPE_STRUCT, "console_device", NULL,
1561.49Satatat		       sysctl_consdev, 0, NULL, sizeof(dev_t),
1571.49Satatat		       CTL_MACHDEP, CPU_CONSDEV, CTL_EOL);
1581.49Satatat/*
1591.49Satatat<atatat> okay...your turn to play.
1601.49Satatat<atatat> pick a number.
1611.49Satatat<kjk> 98752.
1621.49Satatat*/
1631.51Satatat	sysctl_createv(clog, 0, NULL, NULL,
1641.51Satatat		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
1651.49Satatat		       CTLTYPE_INT, "load_and_reset", NULL,
1661.49Satatat		       sysctl_machdep_loadandreset, 98752, NULL, 0,
1671.49Satatat		       CTL_MACHDEP, CPU_LOADANDRESET, CTL_EOL);
1681.1Sitojun}
1691.1Sitojun
1701.1Sitojunvoid
1711.65Sdslcpu_reboot(int howto, char *bootstr)
1721.1Sitojun{
1731.37Such	static int waittime = -1;
1741.1Sitojun
1751.1Sitojun	if (cold) {
1761.1Sitojun		howto |= RB_HALT;
1771.1Sitojun		goto haltsys;
1781.1Sitojun	}
1791.1Sitojun
1801.1Sitojun	boothowto = howto;
1811.1Sitojun	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
1821.1Sitojun		waittime = 0;
1831.1Sitojun		vfs_shutdown();
1841.1Sitojun		/*
1851.1Sitojun		 * If we've been adjusting the clock, the todr
1861.1Sitojun		 * will be out of synch; adjust it now.
1871.1Sitojun		 */
1881.1Sitojun		/* resettodr(); */
1891.1Sitojun	}
1901.1Sitojun
1911.1Sitojun	/* Disable interrupts. */
1921.1Sitojun	splhigh();
1931.1Sitojun
1941.1Sitojun	/* Do a dump if requested. */
1951.1Sitojun	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
1961.1Sitojun		dumpsys();
1971.1Sitojun
1981.1Sitojunhaltsys:
1991.1Sitojun	doshutdownhooks();
2001.1Sitojun
2011.61Sdyoung	pmf_system_shutdown(boothowto);
2021.61Sdyoung
2031.1Sitojun	if (howto & RB_HALT) {
2041.1Sitojun		printf("\n");
2051.1Sitojun		printf("The operating system has halted.\n");
2061.1Sitojun		printf("Please press any key to reboot.\n\n");
2071.1Sitojun		cngetc();
2081.1Sitojun	}
2091.1Sitojun
2101.1Sitojun	printf("rebooting...\n");
2111.1Sitojun	cpu_reset();
2121.1Sitojun	for(;;)
2131.1Sitojun		;
2141.1Sitojun	/*NOTREACHED*/
2151.1Sitojun}
2161.1Sitojun
2171.1Sitojunvoid
2181.37SuchinitSH3(void *pc)	/* XXX return address */
2191.1Sitojun{
2201.57Suebayasi	extern char edata[], end[];
2211.37Such	vaddr_t kernend;
2221.3Smsaitoh
2231.37Such	/* Clear bss */
2241.57Suebayasi	memset(edata, 0, end - edata);
2251.3Smsaitoh
2261.37Such	/* Initilize CPU ops. */
2271.30Such#if defined(SH3) && defined(SH4)
2281.30Such#error "don't define both SH3 and SH4"
2291.30Such#elif defined(SH3)
2301.40Such#if defined(SH7708)
2311.40Such	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708);
2321.40Such#elif defined(SH7708S)
2331.40Such	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708S);
2341.40Such#elif defined(SH7708R)
2351.40Such	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708R);
2361.40Such#elif defined(SH7709)
2371.40Such	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7709);
2381.40Such#elif defined(SH7709A)
2391.40Such	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7709A);
2401.40Such#else
2411.40Such#error "unsupported SH3 variants"
2421.40Such#endif
2431.30Such#elif defined(SH4)
2441.40Such#if defined(SH7750)
2451.40Such	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7750);
2461.40Such#elif defined(SH7750S)
2471.40Such	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7750S);
2481.40Such#else
2491.40Such#error "unsupported SH4 variants"
2501.40Such#endif
2511.30Such#else
2521.30Such#error "define SH3 or SH4"
2531.30Such#endif
2541.41Such	/* Console */
2551.41Such	consinit();
2561.41Such
2571.41Such	/* Load memory to UVM */
2581.57Suebayasi	kernend = atop(round_page(SH3_P1SEG_TO_PHYS(end)));
2591.41Such	physmem = atop(IOM_RAM_SIZE);
2601.41Such	uvm_page_physload(
2611.41Such		kernend, atop(IOM_RAM_BEGIN + IOM_RAM_SIZE),
2621.41Such		kernend, atop(IOM_RAM_BEGIN + IOM_RAM_SIZE),
2631.41Such		VM_FREELIST_DEFAULT);
2641.40Such
2651.41Such	/* Initialize proc0 u-area */
2661.41Such	sh_proc0_init();
2671.41Such
2681.41Such	/* Initialize pmap and start to address translation */
2691.41Such	pmap_bootstrap();
2701.1Sitojun
2711.63Smartin#	/*
2721.3Smsaitoh	 * XXX We can't return here, because we change stack pointer.
2731.3Smsaitoh	 *     So jump to return address directly.
2741.3Smsaitoh	 */
2751.56Sperry	__asm volatile (
2761.37Such		"jmp	@%0;"
2771.41Such		"mov	%1, r15"
2781.44Sthorpej		:: "r"(pc),"r"(lwp0.l_md.md_pcb->pcb_sf.sf_r7_bank));
2791.1Sitojun}
2801.1Sitojun
2811.1Sitojun/*
2821.1Sitojun * consinit:
2831.1Sitojun * initialize the system console.
2841.1Sitojun * XXX - shouldn't deal with this initted thing, but then,
2851.1Sitojun * it shouldn't be called from init386 either.
2861.1Sitojun */
2871.1Sitojunvoid
2881.1Sitojunconsinit()
2891.1Sitojun{
2901.1Sitojun	static int initted;
2911.1Sitojun
2921.1Sitojun	if (initted)
2931.1Sitojun		return;
2941.1Sitojun	initted = 1;
2951.1Sitojun
2961.1Sitojun	cninit();
2971.1Sitojun}
2981.1Sitojun
2991.1Sitojunint
3001.66Sdslbus_space_map (bus_space_tag_t t, bus_addr_t addr, bus_size_t size, int flags, bus_space_handle_t *bshp)
3011.1Sitojun{
3021.1Sitojun
3031.1Sitojun	*bshp = (bus_space_handle_t)addr;
3041.1Sitojun
3051.1Sitojun	return 0;
3061.1Sitojun}
3071.1Sitojun
3081.1Sitojunint
3091.66Sdslsh_memio_subregion(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
3101.1Sitojun{
3111.1Sitojun
3121.1Sitojun	*nbshp = bsh + offset;
3131.1Sitojun	return (0);
3141.1Sitojun}
3151.1Sitojun
3161.1Sitojunint
3171.1Sitojunsh_memio_alloc(t, rstart, rend, size, alignment, boundary, flags,
3181.1Sitojun	       bpap, bshp)
3191.1Sitojun	bus_space_tag_t t;
3201.1Sitojun	bus_addr_t rstart, rend;
3211.1Sitojun	bus_size_t size, alignment, boundary;
3221.1Sitojun	int flags;
3231.1Sitojun	bus_addr_t *bpap;
3241.1Sitojun	bus_space_handle_t *bshp;
3251.1Sitojun{
3261.1Sitojun	*bshp = *bpap = rstart;
3271.1Sitojun
3281.1Sitojun	return (0);
3291.1Sitojun}
3301.1Sitojun
3311.1Sitojunvoid
3321.65Sdslsh_memio_free(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
3331.1Sitojun{
3341.1Sitojun
3351.1Sitojun}
3361.1Sitojun
3371.1Sitojunvoid
3381.65Sdslsh_memio_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
3391.1Sitojun{
3401.1Sitojun	return;
3411.1Sitojun}
3421.20Smsaitoh
3431.20Smsaitoh#ifdef SH4_PCMCIA
3441.20Smsaitoh
3451.20Smsaitohint
3461.65Sdslshpcmcia_memio_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags, bus_space_handle_t *bshp)
3471.20Smsaitoh{
3481.20Smsaitoh	int error;
3491.20Smsaitoh	struct extent *ex;
3501.20Smsaitoh	bus_space_tag_t pt = t & ~SH3_BUS_SPACE_PCMCIA_8BIT;
3511.20Smsaitoh
3521.20Smsaitoh	if (pt != SH3_BUS_SPACE_PCMCIA_IO &&
3531.20Smsaitoh	    pt != SH3_BUS_SPACE_PCMCIA_MEM &&
3541.20Smsaitoh	    pt != SH3_BUS_SPACE_PCMCIA_ATT) {
3551.20Smsaitoh		*bshp = (bus_space_handle_t)bpa;
3561.20Smsaitoh
3571.20Smsaitoh		return 0;
3581.20Smsaitoh	}
3591.20Smsaitoh
3601.20Smsaitoh	ex = iomem_ex;
3611.20Smsaitoh
3621.20Smsaitoh#if 0
3631.20Smsaitoh	/*
3641.20Smsaitoh	 * Before we go any further, let's make sure that this
3651.20Smsaitoh	 * region is available.
3661.20Smsaitoh	 */
3671.20Smsaitoh	error = extent_alloc_region(ex, bpa, size,
3681.20Smsaitoh				    EX_NOWAIT | EX_MALLOCOK );
3691.20Smsaitoh	if (error){
3701.20Smsaitoh		printf("sh3_pcmcia_memio_map:extent_alloc_region error\n");
3711.20Smsaitoh		return (error);
3721.20Smsaitoh	}
3731.20Smsaitoh#endif
3741.20Smsaitoh
3751.20Smsaitoh	/*
3761.20Smsaitoh	 * For memory space, map the bus physical address to
3771.20Smsaitoh	 * a kernel virtual address.
3781.20Smsaitoh	 */
3791.20Smsaitoh	error = shpcmcia_mem_add_mapping(bpa, size, (int)t, bshp );
3801.20Smsaitoh#if 0
3811.20Smsaitoh	if (error) {
3821.20Smsaitoh		if (extent_free(ex, bpa, size, EX_NOWAIT | EX_MALLOCOK )) {
3831.20Smsaitoh			printf("sh3_pcmcia_memio_map: pa 0x%lx, size 0x%lx\n",
3841.20Smsaitoh			       bpa, size);
3851.20Smsaitoh			printf("sh3_pcmcia_memio_map: can't free region\n");
3861.20Smsaitoh		}
3871.20Smsaitoh	}
3881.20Smsaitoh#endif
3891.20Smsaitoh
3901.20Smsaitoh	return (error);
3911.20Smsaitoh}
3921.20Smsaitoh
3931.20Smsaitohint
3941.65Sdslshpcmcia_mem_add_mapping(bus_addr_t bpa, bus_size_t size, int type, bus_space_handle_t *bshp)
3951.20Smsaitoh{
3961.20Smsaitoh	u_long pa, endpa;
3971.20Smsaitoh	vaddr_t va;
3981.20Smsaitoh	pt_entry_t *pte;
3991.20Smsaitoh	unsigned int m = 0;
4001.20Smsaitoh	int io_type = type & ~SH3_BUS_SPACE_PCMCIA_8BIT;
4011.20Smsaitoh
4021.20Smsaitoh	pa = sh3_trunc_page(bpa);
4031.20Smsaitoh	endpa = sh3_round_page(bpa + size);
4041.20Smsaitoh
4051.20Smsaitoh#ifdef DIAGNOSTIC
4061.20Smsaitoh	if (endpa <= pa)
4071.20Smsaitoh		panic("sh3_pcmcia_mem_add_mapping: overflow");
4081.20Smsaitoh#endif
4091.20Smsaitoh
4101.55Syamt	va = uvm_km_alloc(kernel_map, endpa - pa, 0,
4111.55Syamt	    UVM_KMF_VAONLY | UVM_KMF_NOWAIT);
4121.20Smsaitoh	if (va == 0){
4131.20Smsaitoh		printf("shpcmcia_add_mapping: nomem \n");
4141.20Smsaitoh		return (ENOMEM);
4151.20Smsaitoh	}
4161.20Smsaitoh
4171.20Smsaitoh	*bshp = (bus_space_handle_t)(va + (bpa & PGOFSET));
4181.20Smsaitoh
4191.29Such#define MODE(t, s)							\
4201.29Such	(t) & SH3_BUS_SPACE_PCMCIA_8BIT ?				\
4211.29Such		_PG_PCMCIA_ ## s ## 8 :					\
4221.29Such		_PG_PCMCIA_ ## s ## 16
4231.29Such	switch (io_type) {
4241.29Such	default:
4251.29Such		panic("unknown pcmcia space.");
4261.29Such		/* NOTREACHED */
4271.29Such	case SH3_BUS_SPACE_PCMCIA_IO:
4281.29Such		m = MODE(type, IO);
4291.29Such		break;
4301.29Such	case SH3_BUS_SPACE_PCMCIA_MEM:
4311.29Such		m = MODE(type, MEM);
4321.29Such		break;
4331.29Such	case SH3_BUS_SPACE_PCMCIA_ATT:
4341.29Such		m = MODE(type, ATTR);
4351.29Such		break;
4361.20Smsaitoh	}
4371.29Such#undef MODE
4381.20Smsaitoh
4391.45Sthorpej	for (; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) {
4401.41Such		pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE);
4411.41Such		pte = __pmap_kpte_lookup(va);
4421.41Such		KDASSERT(pte);
4431.41Such		*pte |= m;  /* PTEA PCMCIA assistant bit */
4441.41Such		sh_tlb_update(0, va, *pte);
4451.41Such	}
4461.20Smsaitoh
4471.20Smsaitoh	return 0;
4481.20Smsaitoh}
4491.20Smsaitoh
4501.20Smsaitohvoid
4511.65Sdslshpcmcia_memio_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
4521.20Smsaitoh{
4531.20Smsaitoh	struct extent *ex;
4541.20Smsaitoh	u_long va, endva;
4551.20Smsaitoh	bus_addr_t bpa;
4561.20Smsaitoh	bus_space_tag_t pt = t & ~SH3_BUS_SPACE_PCMCIA_8BIT;
4571.20Smsaitoh
4581.20Smsaitoh	if (pt != SH3_BUS_SPACE_PCMCIA_IO &&
4591.20Smsaitoh	    pt != SH3_BUS_SPACE_PCMCIA_MEM &&
4601.20Smsaitoh	    pt != SH3_BUS_SPACE_PCMCIA_ATT) {
4611.20Smsaitoh		return ;
4621.20Smsaitoh	}
4631.20Smsaitoh
4641.20Smsaitoh	ex = iomem_ex;
4651.20Smsaitoh
4661.20Smsaitoh	va = sh3_trunc_page(bsh);
4671.20Smsaitoh	endva = sh3_round_page(bsh + size);
4681.20Smsaitoh
4691.20Smsaitoh#ifdef DIAGNOSTIC
4701.20Smsaitoh	if (endva <= va)
4711.20Smsaitoh		panic("sh3_pcmcia_memio_unmap: overflow");
4721.20Smsaitoh#endif
4731.20Smsaitoh
4741.22Smsaitoh	pmap_extract(pmap_kernel(), va, &bpa);
4751.24Sichiro	bpa += bsh & PGOFSET;
4761.20Smsaitoh
4771.20Smsaitoh	/*
4781.20Smsaitoh	 * Free the kernel virtual mapping.
4791.20Smsaitoh	 */
4801.53Syamt	pmap_kremove(va, endva - va);
4811.53Syamt	pmap_update(pmap_kernel());
4821.53Syamt	uvm_km_free(kernel_map, va, endva - va, UVM_KMF_VAONLY);
4831.20Smsaitoh
4841.20Smsaitoh#if 0
4851.20Smsaitoh	if (extent_free(ex, bpa, size,
4861.20Smsaitoh			EX_NOWAIT | EX_MALLOCOK)) {
4871.20Smsaitoh		printf("sh3_pcmcia_memio_unmap: %s 0x%lx, size 0x%lx\n",
4881.20Smsaitoh		       "pa", bpa, size);
4891.20Smsaitoh		printf("sh3_pcmcia_memio_unmap: can't free region\n");
4901.20Smsaitoh	}
4911.20Smsaitoh#endif
4921.20Smsaitoh}
4931.20Smsaitoh
4941.20Smsaitohvoid
4951.65Sdslshpcmcia_memio_free(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
4961.20Smsaitoh{
4971.20Smsaitoh
4981.20Smsaitoh	/* sh3_pcmcia_memio_unmap() does all that we need to do. */
4991.20Smsaitoh	shpcmcia_memio_unmap(t, bsh, size);
5001.20Smsaitoh}
5011.20Smsaitoh
5021.20Smsaitohint
5031.66Sdslshpcmcia_memio_subregion(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
5041.20Smsaitoh{
5051.20Smsaitoh
5061.20Smsaitoh	*nbshp = bsh + offset;
5071.20Smsaitoh	return (0);
5081.20Smsaitoh}
5091.20Smsaitoh
5101.20Smsaitoh#endif /* SH4_PCMCIA */
5111.1Sitojun
5121.18Smsaitoh#if !defined(DONT_INIT_BSC)
5131.1Sitojun/*
5141.1Sitojun * InitializeBsc
5151.50Swiz * : BSC(Bus State Controller)
5161.1Sitojun */
5171.64Sdslvoid InitializeBsc(void);
5181.1Sitojun
5191.1Sitojunvoid
5201.1SitojunInitializeBsc()
5211.1Sitojun{
5221.1Sitojun
5231.1Sitojun	/*
5241.1Sitojun	 * Drive RAS,CAS in stand by mode and bus release mode
5251.1Sitojun	 * Area0 = Normal memory, Area5,6=Normal(no burst)
5261.1Sitojun	 * Area2 = Normal memory, Area3 = SDRAM, Area5 = Normal memory
5271.1Sitojun	 * Area4 = Normal Memory
5281.1Sitojun	 * Area6 = Normal memory
5291.1Sitojun	 */
5301.33Such#if defined(SH3)
5311.33Such	_reg_write_2(SH3_BCR1, BSC_BCR1_VAL);
5321.33Such#elif defined(SH4)
5331.33Such	_reg_write_4(SH4_BCR1, BSC_BCR1_VAL);
5341.33Such#endif
5351.1Sitojun
5361.1Sitojun	/*
5371.1Sitojun	 * Bus Width
5381.1Sitojun	 * Area4: Bus width = 16bit
5391.1Sitojun	 * Area6,5 = 16bit
5401.1Sitojun	 * Area1 = 8bit
5411.1Sitojun	 * Area2,3: Bus width = 32bit
5421.1Sitojun	 */
5431.33Such	_reg_write_2(SH_(BCR2), BSC_BCR2_VAL);
5441.1Sitojun
5451.1Sitojun	/*
5461.1Sitojun	 * Idle cycle number in transition area and read to write
5471.1Sitojun	 * Area6 = 3, Area5 = 3, Area4 = 3, Area3 = 3, Area2 = 3
5481.1Sitojun	 * Area1 = 3, Area0 = 3
5491.1Sitojun	 */
5501.33Such#if defined(SH3)
5511.33Such	_reg_write_2(SH3_WCR1, BSC_WCR1_VAL);
5521.33Such#elif defined(SH4)
5531.33Such	_reg_write_4(SH4_WCR1, BSC_WCR1_VAL);
5541.33Such#endif
5551.1Sitojun
5561.1Sitojun	/*
5571.1Sitojun	 * Wait cycle
5581.1Sitojun	 * Area 6 = 6
5591.1Sitojun	 * Area 5 = 2
5601.1Sitojun	 * Area 4 = 10
5611.1Sitojun	 * Area 3 = 3
5621.1Sitojun	 * Area 2,1 = 3
5631.1Sitojun	 * Area 0 = 6
5641.1Sitojun	 */
5651.33Such#if defined(SH3)
5661.33Such	_reg_write_2(SH3_WCR2, BSC_WCR2_VAL);
5671.33Such#elif defined(SH4)
5681.33Such	_reg_write_4(SH4_WCR2, BSC_WCR2_VAL);
5691.33Such#endif
5701.1Sitojun
5711.13Smsaitoh#if defined(SH4) && defined(BSC_WCR3_VAL)
5721.33Such	_reg_write_4(SH4_WCR3, BSC_WCR3_VAL);
5731.1Sitojun#endif
5741.1Sitojun
5751.1Sitojun	/*
5761.1Sitojun	 * RAS pre-charge = 2cycle, RAS-CAS delay = 3 cycle,
5771.1Sitojun	 * write pre-charge=1cycle
5781.1Sitojun	 * CAS before RAS refresh RAS assert time = 3 cycle
5791.1Sitojun	 * Disable burst, Bus size=32bit, Column Address=10bit, Refresh ON
5801.1Sitojun	 * CAS before RAS refresh ON, EDO DRAM
5811.1Sitojun	 */
5821.33Such#if defined(SH3)
5831.33Such	_reg_write_2(SH3_MCR, BSC_MCR_VAL);
5841.33Such#elif defined(SH4)
5851.33Such	_reg_write_4(SH4_MCR, BSC_MCR_VAL);
5861.33Such#endif
5871.1Sitojun
5881.11Smsaitoh#if defined(BSC_SDMR2_VAL)
5891.33Such	_reg_write_1(BSC_SDMR2_VAL, 0);
5901.11Smsaitoh#endif
5911.11Smsaitoh
5921.11Smsaitoh#if defined(BSC_SDMR3_VAL)
5931.19Smsaitoh#if !(defined(COMPUTEXEVB) && defined(SH7709A))
5941.33Such	_reg_write_1(BSC_SDMR3_VAL, 0);
5951.1Sitojun#else
5961.33Such	_reg_write_2(0x1a000000, 0);	/* ADDSET */
5971.33Such	_reg_write_1(BSC_SDMR3_VAL, 0);
5981.33Such	_reg_write_2(0x18000000, 0);	/* ADDRST */
5991.33Such#endif /* !(COMPUTEXEVB && SH7709A) */
6001.33Such#endif /* BSC_SDMR3_VAL */
6011.1Sitojun
6021.1Sitojun	/*
6031.1Sitojun	 * PCMCIA Control Register
6041.1Sitojun	 * OE/WE assert delay 3.5 cycle
6051.1Sitojun	 * OE/WE negate-address delay 3.5 cycle
6061.1Sitojun	 */
6071.1Sitojun#ifdef BSC_PCR_VAL
6081.33Such	_reg_write_2(SH_(PCR), BSC_PCR_VAL);
6091.1Sitojun#endif
6101.1Sitojun
6111.1Sitojun	/*
6121.1Sitojun	 * Refresh Timer Control/Status Register
6131.1Sitojun	 * Disable interrupt by CMF, closk 1/16, Disable OVF interrupt
6141.1Sitojun	 * Count Limit = 1024
6151.1Sitojun	 * In following statement, the reason why high byte = 0xa5(a4 in RFCR)
6161.1Sitojun	 * is the rule of SH3 in writing these register.
6171.1Sitojun	 */
6181.33Such	_reg_write_2(SH_(RTCSR), BSC_RTCSR_VAL);
6191.1Sitojun
6201.1Sitojun	/*
6211.1Sitojun	 * Refresh Timer Counter
6221.1Sitojun	 * Initialize to 0
6231.1Sitojun	 */
6241.9Smsaitoh#ifdef BSC_RTCNT_VAL
6251.33Such	_reg_write_2(SH_(RTCNT), BSC_RTCNT_VAL);
6261.9Smsaitoh#endif
6271.1Sitojun
6281.1Sitojun	/* set Refresh Time Constant Register */
6291.33Such	_reg_write_2(SH_(RTCOR), BSC_RTCOR_VAL);
6301.1Sitojun
6311.1Sitojun	/* init Refresh Count Register */
6321.1Sitojun#ifdef BSC_RFCR_VAL
6331.33Such	_reg_write_2(SH_(RFCR), BSC_RFCR_VAL);
6341.1Sitojun#endif
6351.1Sitojun
6361.33Such	/*
6371.33Such	 * Clock Pulse Generator
6381.33Such	 */
6391.1Sitojun	/* Set Clock mode (make internal clock double speed) */
6401.33Such	_reg_write_2(SH_(FRQCR), FRQCR_VAL);
6411.1Sitojun
6421.33Such	/*
6431.33Such	 * Cache
6441.33Such	 */
6451.33Such#ifndef CACHE_DISABLE
6461.1Sitojun	/* Cache ON */
6471.33Such	_reg_write_4(SH_(CCR), 0x1);
6481.1Sitojun#endif
6491.1Sitojun}
6501.33Such#endif /* !DONT_INIT_BSC */
6511.9Smsaitoh
6521.8Smsaitoh
6531.8Smsaitoh /* XXX This value depends on physical available memory */
6541.8Smsaitoh#define OSIMAGE_BUF_ADDR	(IOM_RAM_BEGIN + 0x00400000)
6551.8Smsaitoh
6561.1Sitojunvoid
6571.65SdslLoadAndReset(const char *osimage)
6581.1Sitojun{
6591.1Sitojun	void *buf_addr;
6601.1Sitojun	u_long size;
6611.54She	const u_long *src;
6621.1Sitojun	u_long *dest;
6631.1Sitojun	u_long csum = 0;
6641.1Sitojun	u_long csum2 = 0;
6651.1Sitojun	u_long size2;
6661.1Sitojun
6671.3Smsaitoh	printf("LoadAndReset: copy start\n");
6681.1Sitojun	buf_addr = (void *)OSIMAGE_BUF_ADDR;
6691.1Sitojun
6701.54She	size = *(const u_long *)osimage;
6711.54She	src = (const u_long *)osimage;
6721.1Sitojun	dest = buf_addr;
6731.1Sitojun
6741.3Smsaitoh	size = (size + sizeof(u_long) * 2 + 3) >> 2;
6751.1Sitojun	size2 = size;
6761.1Sitojun
6771.3Smsaitoh	while (size--) {
6781.1Sitojun		csum += *src;
6791.1Sitojun		*dest++ = *src++;
6801.1Sitojun	}
6811.1Sitojun
6821.1Sitojun	dest = buf_addr;
6831.1Sitojun	while (size2--)
6841.1Sitojun		csum2 += *dest++;
6851.1Sitojun
6861.3Smsaitoh	printf("LoadAndReset: copy end[%lx,%lx]\n", csum, csum2);
6871.1Sitojun	printf("start XLoadAndReset\n");
6881.1Sitojun
6891.1Sitojun	/* mask all externel interrupt (XXX) */
6901.1Sitojun
6911.1Sitojun	XLoadAndReset(buf_addr);
6921.40Such}
6931.40Such
6941.40Suchvoid
6951.40Suchintc_intr(int ssr, int spc, int ssp)
6961.40Such{
6971.40Such	struct intc_intrhand *ih;
6981.40Such	struct clockframe cf;
6991.40Such	int s, evtcode;
7001.40Such
7011.40Such	switch (cpu_product) {
7021.40Such	case CPU_PRODUCT_7708:
7031.40Such	case CPU_PRODUCT_7708S:
7041.40Such	case CPU_PRODUCT_7708R:
7051.40Such		evtcode = _reg_read_4(SH3_INTEVT);
7061.40Such		break;
7071.40Such	case CPU_PRODUCT_7709:
7081.40Such	case CPU_PRODUCT_7709A:
7091.40Such		evtcode = _reg_read_4(SH7709_INTEVT2);
7101.40Such		break;
7111.40Such	case CPU_PRODUCT_7750:
7121.40Such	case CPU_PRODUCT_7750S:
7131.40Such		evtcode = _reg_read_4(SH4_INTEVT);
7141.40Such		break;
7151.52Smatt	default:
7161.52Smatt#ifdef DIAGNOSTIC
7171.52Smatt		panic("intr_intc: cpu_product %d unhandled!", cpu_product);
7181.52Smatt#endif
7191.52Smatt		return;
7201.40Such	}
7211.40Such
7221.40Such	ih = EVTCODE_IH(evtcode);
7231.40Such	KDASSERT(ih->ih_func);
7241.40Such	/*
7251.40Such	 * On entry, all interrrupts are disabled,
7261.40Such	 * and exception is enabled for P3 access. (kernel stack is P3,
7271.40Such	 * SH3 may or may not cause TLB miss when access stack.)
7281.40Such	 * Enable higher level interrupt here.
7291.40Such	 */
7301.40Such	s = _cpu_intr_resume(ih->ih_level);
7311.40Such
7321.40Such	switch (evtcode) {
7331.40Such	default:
7341.40Such		(*ih->ih_func)(ih->ih_arg);
7351.40Such		break;
7361.40Such	case SH_INTEVT_TMU0_TUNI0:
7371.40Such		cf.spc = spc;
7381.40Such		cf.ssr = ssr;
7391.40Such		cf.ssp = ssp;
7401.40Such		(*ih->ih_func)(&cf);
7411.40Such		break;
7421.40Such	case SH_INTEVT_NMI:
7431.40Such		printf("NMI ignored.\n");
7441.40Such		break;
7451.40Such	}
7461.42Such}
7471.40Such
748