11.78Sandvar/*	$NetBSD: machdep.c,v 1.78 2025/07/13 21:07:04 andvar 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.78Sandvar__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.78 2025/07/13 21:07:04 andvar 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.71Snonaka#include "opt_kloader.h"
751.71Snonaka#include "opt_kloader_kernel_path.h"
761.1Sitojun
771.1Sitojun#include <sys/param.h>
781.1Sitojun#include <sys/systm.h>
791.1Sitojun#include <sys/kernel.h>
801.37Such#include <sys/mount.h>
811.1Sitojun#include <sys/reboot.h>
821.37Such#include <sys/sysctl.h>
831.46Sragge#include <sys/ksyms.h>
841.61Sdyoung#include <sys/device.h>
851.74Sdyoung#include <sys/bus.h>
861.1Sitojun
871.37Such#include <uvm/uvm_extern.h>
881.1Sitojun
891.1Sitojun#include <dev/cons.h>
901.40Such
911.37Such#include <sh3/bscreg.h>
921.33Such#include <sh3/cpgreg.h>
931.33Such#include <sh3/cache_sh3.h>
941.40Such#include <sh3/cache_sh4.h>
951.40Such#include <sh3/exception.h>
961.40Such
971.40Such#include <machine/intr.h>
981.73She#include <machine/pcb.h>
991.40Such
1001.40Such#ifdef DDB
1011.40Such#include <machine/db_machdep.h>
1021.40Such#include <ddb/db_extern.h>
1031.40Such#endif
1041.1Sitojun
1051.71Snonaka#ifdef KLOADER
1061.71Snonaka#include <machine/kloader.h>
1071.71Snonaka#endif
1081.71Snonaka
1091.46Sragge#include "ksyms.h"
1101.46Sragge
1111.1Sitojun/* the following is used externally (sysctl_hw) */
1121.37Suchchar machine[] = MACHINE;		/* evbsh3 */
1131.37Suchchar machine_arch[] = MACHINE_ARCH;	/* sh3eb or sh3el */
1141.1Sitojun
1151.71Snonaka#ifdef KLOADER
1161.71Snonakastruct kloader_bootinfo kbootinfo;
1171.71Snonaka#endif
1181.71Snonaka
1191.64Sdslvoid initSH3(void *);
1201.64Sdslvoid LoadAndReset(const char *);
1211.64Sdslvoid XLoadAndReset(char *);
1221.1Sitojun
1231.1Sitojun/*
1241.1Sitojun * Machine-dependent startup code
1251.1Sitojun *
1261.1Sitojun * This is called from main() in kern/main.c.
1271.1Sitojun */
1281.1Sitojunvoid
1291.67Sceggercpu_startup(void)
1301.1Sitojun{
1311.1Sitojun
1321.39Such	sh_startup();
1331.1Sitojun}
1341.1Sitojun
1351.1Sitojun/*
1361.1Sitojun * machine dependent system variables.
1371.1Sitojun */
1381.49Satatatstatic int
1391.49Satatatsysctl_machdep_loadandreset(SYSCTLFN_ARGS)
1401.1Sitojun{
1411.54She	const char *osimage;
1421.49Satatat	int error;
1431.1Sitojun
1441.54She	error = sysctl_lookup(SYSCTLFN_CALL(__UNCONST(rnode)));
1451.49Satatat	if (error || newp == NULL)
1461.49Satatat		return (error);
1471.49Satatat
1481.54She	osimage = (const char *)(*(const u_long *)newp);
1491.49Satatat	LoadAndReset(osimage);
1501.49Satatat	/* not reach here */
1511.49Satatat	return (0);
1521.49Satatat}
1531.49Satatat
1541.49SatatatSYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
1551.49Satatat{
1561.49Satatat
1571.51Satatat	sysctl_createv(clog, 0, NULL, NULL,
1581.51Satatat		       CTLFLAG_PERMANENT,
1591.49Satatat		       CTLTYPE_NODE, "machdep", NULL,
1601.49Satatat		       NULL, 0, NULL, 0,
1611.49Satatat		       CTL_MACHDEP, CTL_EOL);
1621.49Satatat
1631.51Satatat	sysctl_createv(clog, 0, NULL, NULL,
1641.51Satatat		       CTLFLAG_PERMANENT,
1651.49Satatat		       CTLTYPE_STRUCT, "console_device", NULL,
1661.49Satatat		       sysctl_consdev, 0, NULL, sizeof(dev_t),
1671.49Satatat		       CTL_MACHDEP, CPU_CONSDEV, CTL_EOL);
1681.49Satatat/*
1691.49Satatat<atatat> okay...your turn to play.
1701.49Satatat<atatat> pick a number.
1711.49Satatat<kjk> 98752.
1721.49Satatat*/
1731.51Satatat	sysctl_createv(clog, 0, NULL, NULL,
1741.51Satatat		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
1751.49Satatat		       CTLTYPE_INT, "load_and_reset", NULL,
1761.49Satatat		       sysctl_machdep_loadandreset, 98752, NULL, 0,
1771.49Satatat		       CTL_MACHDEP, CPU_LOADANDRESET, CTL_EOL);
1781.1Sitojun}
1791.1Sitojun
1801.1Sitojunvoid
1811.65Sdslcpu_reboot(int howto, char *bootstr)
1821.1Sitojun{
1831.37Such	static int waittime = -1;
1841.1Sitojun
1851.1Sitojun	if (cold) {
1861.1Sitojun		howto |= RB_HALT;
1871.1Sitojun		goto haltsys;
1881.1Sitojun	}
1891.1Sitojun
1901.71Snonaka#ifdef KLOADER
1911.71Snonaka	if ((howto & RB_HALT) == 0) {
1921.71Snonaka		if ((howto & RB_STRING) && (bootstr != NULL)) {
1931.71Snonaka			kloader_reboot_setup(bootstr);
1941.71Snonaka		}
1951.71Snonaka#ifdef KLOADER_KERNEL_PATH
1961.71Snonaka		else {
1971.71Snonaka			kloader_reboot_setup(KLOADER_KERNEL_PATH);
1981.71Snonaka		}
1991.71Snonaka#endif
2001.71Snonaka	}
2011.71Snonaka#endif
2021.71Snonaka
2031.1Sitojun	boothowto = howto;
2041.1Sitojun	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
2051.1Sitojun		waittime = 0;
2061.1Sitojun		vfs_shutdown();
2071.1Sitojun		/*
2081.1Sitojun		 * If we've been adjusting the clock, the todr
2091.1Sitojun		 * will be out of synch; adjust it now.
2101.1Sitojun		 */
2111.1Sitojun		/* resettodr(); */
2121.1Sitojun	}
2131.1Sitojun
2141.1Sitojun	/* Disable interrupts. */
2151.1Sitojun	splhigh();
2161.1Sitojun
2171.1Sitojun	/* Do a dump if requested. */
2181.1Sitojun	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
2191.1Sitojun		dumpsys();
2201.1Sitojun
2211.1Sitojunhaltsys:
2221.1Sitojun	doshutdownhooks();
2231.1Sitojun
2241.61Sdyoung	pmf_system_shutdown(boothowto);
2251.61Sdyoung
2261.1Sitojun	if (howto & RB_HALT) {
2271.1Sitojun		printf("\n");
2281.1Sitojun		printf("The operating system has halted.\n");
2291.1Sitojun		printf("Please press any key to reboot.\n\n");
2301.1Sitojun		cngetc();
2311.1Sitojun	}
2321.71Snonaka#ifdef KLOADER
2331.71Snonaka	else {
2341.71Snonaka		delay(1 * 1000 * 1000);
2351.71Snonaka		kloader_reboot();
2361.71Snonaka		printf("\n");
2371.71Snonaka		printf("Failed to load a new kernel.\n");
2381.71Snonaka		printf("Please press any key to reboot.\n\n");
2391.71Snonaka		cngetc();
2401.71Snonaka	}
2411.71Snonaka#endif
2421.1Sitojun
2431.1Sitojun	printf("rebooting...\n");
2441.1Sitojun	cpu_reset();
2451.1Sitojun	for(;;)
2461.71Snonaka		continue;
2471.1Sitojun	/*NOTREACHED*/
2481.1Sitojun}
2491.1Sitojun
2501.1Sitojunvoid
2511.37SuchinitSH3(void *pc)	/* XXX return address */
2521.1Sitojun{
2531.57Suebayasi	extern char edata[], end[];
2541.37Such	vaddr_t kernend;
2551.3Smsaitoh
2561.37Such	/* Clear bss */
2571.57Suebayasi	memset(edata, 0, end - edata);
2581.3Smsaitoh
2591.37Such	/* Initilize CPU ops. */
2601.30Such#if defined(SH3) && defined(SH4)
2611.30Such#error "don't define both SH3 and SH4"
2621.30Such#elif defined(SH3)
2631.40Such#if defined(SH7708)
2641.40Such	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708);
2651.40Such#elif defined(SH7708S)
2661.40Such	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708S);
2671.40Such#elif defined(SH7708R)
2681.40Such	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708R);
2691.40Such#elif defined(SH7709)
2701.40Such	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7709);
2711.40Such#elif defined(SH7709A)
2721.40Such	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7709A);
2731.68Snonaka#elif defined(SH7706)
2741.68Snonaka	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7706);
2751.40Such#else
2761.40Such#error "unsupported SH3 variants"
2771.40Such#endif
2781.30Such#elif defined(SH4)
2791.40Such#if defined(SH7750)
2801.40Such	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7750);
2811.40Such#elif defined(SH7750S)
2821.40Such	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7750S);
2831.68Snonaka#elif defined(SH7750R)
2841.68Snonaka	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7750R);
2851.68Snonaka#elif defined(SH7751)
2861.68Snonaka	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7751);
2871.68Snonaka#elif defined(SH7751R)
2881.68Snonaka	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7751R);
2891.76Suwe#elif defined(STX7105)
2901.76Suwe	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_STX7105);
2911.40Such#else
2921.40Such#error "unsupported SH4 variants"
2931.40Such#endif
2941.30Such#else
2951.30Such#error "define SH3 or SH4"
2961.30Such#endif
2971.41Such	/* Console */
2981.41Such	consinit();
2991.41Such
3001.71Snonaka#ifdef KLOADER
3011.71Snonaka	/* copy boot parameter for kloader */
3021.71Snonaka	kloader_bootinfo_set(&kbootinfo, 0, NULL, NULL, true);
3031.71Snonaka#endif
3041.71Snonaka
3051.41Such	/* Load memory to UVM */
3061.57Suebayasi	kernend = atop(round_page(SH3_P1SEG_TO_PHYS(end)));
3071.41Such	physmem = atop(IOM_RAM_SIZE);
3081.41Such	uvm_page_physload(
3091.41Such		kernend, atop(IOM_RAM_BEGIN + IOM_RAM_SIZE),
3101.41Such		kernend, atop(IOM_RAM_BEGIN + IOM_RAM_SIZE),
3111.41Such		VM_FREELIST_DEFAULT);
3121.40Such
3131.41Such	/* Initialize proc0 u-area */
3141.41Such	sh_proc0_init();
3151.41Such
3161.41Such	/* Initialize pmap and start to address translation */
3171.41Such	pmap_bootstrap();
3181.1Sitojun
3191.68Snonaka	/*
3201.3Smsaitoh	 * XXX We can't return here, because we change stack pointer.
3211.3Smsaitoh	 *     So jump to return address directly.
3221.3Smsaitoh	 */
3231.56Sperry	__asm volatile (
3241.37Such		"jmp	@%0;"
3251.41Such		"mov	%1, r15"
3261.44Sthorpej		:: "r"(pc),"r"(lwp0.l_md.md_pcb->pcb_sf.sf_r7_bank));
3271.1Sitojun}
3281.1Sitojun
3291.1Sitojun/*
3301.1Sitojun * consinit:
3311.1Sitojun * initialize the system console.
3321.1Sitojun * XXX - shouldn't deal with this initted thing, but then,
3331.1Sitojun * it shouldn't be called from init386 either.
3341.1Sitojun */
3351.1Sitojunvoid
3361.67Sceggerconsinit(void)
3371.1Sitojun{
3381.1Sitojun	static int initted;
3391.1Sitojun
3401.1Sitojun	if (initted)
3411.1Sitojun		return;
3421.1Sitojun	initted = 1;
3431.1Sitojun
3441.1Sitojun	cninit();
3451.1Sitojun}
3461.1Sitojun
3471.18Smsaitoh#if !defined(DONT_INIT_BSC)
3481.1Sitojun/*
3491.1Sitojun * InitializeBsc
3501.50Swiz * : BSC(Bus State Controller)
3511.1Sitojun */
3521.64Sdslvoid InitializeBsc(void);
3531.1Sitojun
3541.1Sitojunvoid
3551.67SceggerInitializeBsc(void)
3561.1Sitojun{
3571.1Sitojun
3581.1Sitojun	/*
3591.1Sitojun	 * Drive RAS,CAS in stand by mode and bus release mode
3601.1Sitojun	 * Area0 = Normal memory, Area5,6=Normal(no burst)
3611.1Sitojun	 * Area2 = Normal memory, Area3 = SDRAM, Area5 = Normal memory
3621.1Sitojun	 * Area4 = Normal Memory
3631.1Sitojun	 * Area6 = Normal memory
3641.1Sitojun	 */
3651.33Such#if defined(SH3)
3661.33Such	_reg_write_2(SH3_BCR1, BSC_BCR1_VAL);
3671.33Such#elif defined(SH4)
3681.33Such	_reg_write_4(SH4_BCR1, BSC_BCR1_VAL);
3691.33Such#endif
3701.1Sitojun
3711.1Sitojun	/*
3721.1Sitojun	 * Bus Width
3731.1Sitojun	 * Area4: Bus width = 16bit
3741.1Sitojun	 * Area6,5 = 16bit
3751.1Sitojun	 * Area1 = 8bit
3761.1Sitojun	 * Area2,3: Bus width = 32bit
3771.1Sitojun	 */
3781.33Such	_reg_write_2(SH_(BCR2), BSC_BCR2_VAL);
3791.1Sitojun
3801.1Sitojun	/*
3811.1Sitojun	 * Idle cycle number in transition area and read to write
3821.1Sitojun	 * Area6 = 3, Area5 = 3, Area4 = 3, Area3 = 3, Area2 = 3
3831.1Sitojun	 * Area1 = 3, Area0 = 3
3841.1Sitojun	 */
3851.33Such#if defined(SH3)
3861.33Such	_reg_write_2(SH3_WCR1, BSC_WCR1_VAL);
3871.33Such#elif defined(SH4)
3881.33Such	_reg_write_4(SH4_WCR1, BSC_WCR1_VAL);
3891.33Such#endif
3901.1Sitojun
3911.1Sitojun	/*
3921.1Sitojun	 * Wait cycle
3931.1Sitojun	 * Area 6 = 6
3941.1Sitojun	 * Area 5 = 2
3951.1Sitojun	 * Area 4 = 10
3961.1Sitojun	 * Area 3 = 3
3971.1Sitojun	 * Area 2,1 = 3
3981.1Sitojun	 * Area 0 = 6
3991.1Sitojun	 */
4001.33Such#if defined(SH3)
4011.33Such	_reg_write_2(SH3_WCR2, BSC_WCR2_VAL);
4021.33Such#elif defined(SH4)
4031.33Such	_reg_write_4(SH4_WCR2, BSC_WCR2_VAL);
4041.33Such#endif
4051.1Sitojun
4061.13Smsaitoh#if defined(SH4) && defined(BSC_WCR3_VAL)
4071.33Such	_reg_write_4(SH4_WCR3, BSC_WCR3_VAL);
4081.1Sitojun#endif
4091.1Sitojun
4101.1Sitojun	/*
4111.1Sitojun	 * RAS pre-charge = 2cycle, RAS-CAS delay = 3 cycle,
4121.1Sitojun	 * write pre-charge=1cycle
4131.1Sitojun	 * CAS before RAS refresh RAS assert time = 3 cycle
4141.1Sitojun	 * Disable burst, Bus size=32bit, Column Address=10bit, Refresh ON
4151.1Sitojun	 * CAS before RAS refresh ON, EDO DRAM
4161.1Sitojun	 */
4171.33Such#if defined(SH3)
4181.33Such	_reg_write_2(SH3_MCR, BSC_MCR_VAL);
4191.33Such#elif defined(SH4)
4201.33Such	_reg_write_4(SH4_MCR, BSC_MCR_VAL);
4211.33Such#endif
4221.1Sitojun
4231.11Smsaitoh#if defined(BSC_SDMR2_VAL)
4241.33Such	_reg_write_1(BSC_SDMR2_VAL, 0);
4251.11Smsaitoh#endif
4261.11Smsaitoh
4271.11Smsaitoh#if defined(BSC_SDMR3_VAL)
4281.19Smsaitoh#if !(defined(COMPUTEXEVB) && defined(SH7709A))
4291.33Such	_reg_write_1(BSC_SDMR3_VAL, 0);
4301.1Sitojun#else
4311.33Such	_reg_write_2(0x1a000000, 0);	/* ADDSET */
4321.33Such	_reg_write_1(BSC_SDMR3_VAL, 0);
4331.33Such	_reg_write_2(0x18000000, 0);	/* ADDRST */
4341.33Such#endif /* !(COMPUTEXEVB && SH7709A) */
4351.33Such#endif /* BSC_SDMR3_VAL */
4361.1Sitojun
4371.1Sitojun	/*
4381.1Sitojun	 * PCMCIA Control Register
4391.1Sitojun	 * OE/WE assert delay 3.5 cycle
4401.1Sitojun	 * OE/WE negate-address delay 3.5 cycle
4411.1Sitojun	 */
4421.1Sitojun#ifdef BSC_PCR_VAL
4431.33Such	_reg_write_2(SH_(PCR), BSC_PCR_VAL);
4441.1Sitojun#endif
4451.1Sitojun
4461.1Sitojun	/*
4471.1Sitojun	 * Refresh Timer Control/Status Register
4481.1Sitojun	 * Disable interrupt by CMF, closk 1/16, Disable OVF interrupt
4491.1Sitojun	 * Count Limit = 1024
4501.1Sitojun	 * In following statement, the reason why high byte = 0xa5(a4 in RFCR)
4511.1Sitojun	 * is the rule of SH3 in writing these register.
4521.1Sitojun	 */
4531.33Such	_reg_write_2(SH_(RTCSR), BSC_RTCSR_VAL);
4541.1Sitojun
4551.1Sitojun	/*
4561.1Sitojun	 * Refresh Timer Counter
4571.1Sitojun	 * Initialize to 0
4581.1Sitojun	 */
4591.9Smsaitoh#ifdef BSC_RTCNT_VAL
4601.33Such	_reg_write_2(SH_(RTCNT), BSC_RTCNT_VAL);
4611.9Smsaitoh#endif
4621.1Sitojun
4631.1Sitojun	/* set Refresh Time Constant Register */
4641.33Such	_reg_write_2(SH_(RTCOR), BSC_RTCOR_VAL);
4651.1Sitojun
4661.1Sitojun	/* init Refresh Count Register */
4671.1Sitojun#ifdef BSC_RFCR_VAL
4681.33Such	_reg_write_2(SH_(RFCR), BSC_RFCR_VAL);
4691.1Sitojun#endif
4701.1Sitojun
4711.33Such	/*
4721.33Such	 * Clock Pulse Generator
4731.33Such	 */
4741.1Sitojun	/* Set Clock mode (make internal clock double speed) */
4751.33Such	_reg_write_2(SH_(FRQCR), FRQCR_VAL);
4761.1Sitojun
4771.33Such	/*
4781.33Such	 * Cache
4791.33Such	 */
4801.33Such#ifndef CACHE_DISABLE
4811.1Sitojun	/* Cache ON */
4821.33Such	_reg_write_4(SH_(CCR), 0x1);
4831.1Sitojun#endif
4841.1Sitojun}
4851.33Such#endif /* !DONT_INIT_BSC */
4861.9Smsaitoh
4871.8Smsaitoh
4881.8Smsaitoh /* XXX This value depends on physical available memory */
4891.8Smsaitoh#define OSIMAGE_BUF_ADDR	(IOM_RAM_BEGIN + 0x00400000)
4901.8Smsaitoh
4911.1Sitojunvoid
4921.65SdslLoadAndReset(const char *osimage)
4931.1Sitojun{
4941.1Sitojun	void *buf_addr;
4951.1Sitojun	u_long size;
4961.54She	const u_long *src;
4971.1Sitojun	u_long *dest;
4981.1Sitojun	u_long csum = 0;
4991.1Sitojun	u_long csum2 = 0;
5001.1Sitojun	u_long size2;
5011.1Sitojun
5021.3Smsaitoh	printf("LoadAndReset: copy start\n");
5031.1Sitojun	buf_addr = (void *)OSIMAGE_BUF_ADDR;
5041.1Sitojun
5051.54She	size = *(const u_long *)osimage;
5061.54She	src = (const u_long *)osimage;
5071.1Sitojun	dest = buf_addr;
5081.1Sitojun
5091.3Smsaitoh	size = (size + sizeof(u_long) * 2 + 3) >> 2;
5101.1Sitojun	size2 = size;
5111.1Sitojun
5121.3Smsaitoh	while (size--) {
5131.1Sitojun		csum += *src;
5141.1Sitojun		*dest++ = *src++;
5151.1Sitojun	}
5161.1Sitojun
5171.1Sitojun	dest = buf_addr;
5181.1Sitojun	while (size2--)
5191.1Sitojun		csum2 += *dest++;
5201.1Sitojun
5211.3Smsaitoh	printf("LoadAndReset: copy end[%lx,%lx]\n", csum, csum2);
5221.1Sitojun	printf("start XLoadAndReset\n");
5231.1Sitojun
5241.78Sandvar	/* mask all external interrupts (XXX) */
5251.1Sitojun
5261.1Sitojun	XLoadAndReset(buf_addr);
5271.40Such}
5281.40Such
5291.40Suchvoid
5301.40Suchintc_intr(int ssr, int spc, int ssp)
5311.40Such{
5321.40Such	struct intc_intrhand *ih;
5331.40Such	struct clockframe cf;
5341.75Smsaitoh	int evtcode;
5351.40Such
5361.72Smatt	curcpu()->ci_data.cpu_nintr++;
5371.72Smatt
5381.40Such	switch (cpu_product) {
5391.40Such	case CPU_PRODUCT_7708:
5401.40Such	case CPU_PRODUCT_7708S:
5411.40Such	case CPU_PRODUCT_7708R:
5421.40Such		evtcode = _reg_read_4(SH3_INTEVT);
5431.40Such		break;
5441.40Such	case CPU_PRODUCT_7709:
5451.40Such	case CPU_PRODUCT_7709A:
5461.68Snonaka	case CPU_PRODUCT_7706:
5471.40Such		evtcode = _reg_read_4(SH7709_INTEVT2);
5481.40Such		break;
5491.40Such	case CPU_PRODUCT_7750:
5501.40Such	case CPU_PRODUCT_7750S:
5511.68Snonaka	case CPU_PRODUCT_7750R:
5521.68Snonaka	case CPU_PRODUCT_7751:
5531.68Snonaka	case CPU_PRODUCT_7751R:
5541.40Such		evtcode = _reg_read_4(SH4_INTEVT);
5551.40Such		break;
5561.52Smatt	default:
5571.52Smatt#ifdef DIAGNOSTIC
5581.52Smatt		panic("intr_intc: cpu_product %d unhandled!", cpu_product);
5591.52Smatt#endif
5601.52Smatt		return;
5611.40Such	}
5621.40Such
5631.40Such	ih = EVTCODE_IH(evtcode);
5641.40Such	KDASSERT(ih->ih_func);
5651.40Such	/*
5661.77Sandvar	 * On entry, all interrupts are disabled,
5671.40Such	 * and exception is enabled for P3 access. (kernel stack is P3,
5681.40Such	 * SH3 may or may not cause TLB miss when access stack.)
5691.40Such	 * Enable higher level interrupt here.
5701.40Such	 */
5711.75Smsaitoh	_cpu_intr_resume(ih->ih_level);
5721.40Such
5731.40Such	switch (evtcode) {
5741.40Such	default:
5751.40Such		(*ih->ih_func)(ih->ih_arg);
5761.40Such		break;
5771.40Such	case SH_INTEVT_TMU0_TUNI0:
5781.40Such		cf.spc = spc;
5791.40Such		cf.ssr = ssr;
5801.40Such		cf.ssp = ssp;
5811.40Such		(*ih->ih_func)(&cf);
5821.40Such		break;
5831.40Such	case SH_INTEVT_NMI:
5841.40Such		printf("NMI ignored.\n");
5851.40Such		break;
5861.40Such	}
5871.42Such}
588