machdep.c revision 1.57
1/*	$NetBSD: machdep.c,v 1.57 2006/03/17 16:06:51 uebayasi Exp $	*/
2
3/*-
4 * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
9 * Simulation Facility, NASA Ames Research Center.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 *    must display the following acknowledgement:
21 *	This product includes software developed by the NetBSD
22 *	Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 *    contributors may be used to endorse or promote products derived
25 *    from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40/*-
41 * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
42 * All rights reserved.
43 *
44 * This code is derived from software contributed to Berkeley by
45 * William Jolitz.
46 *
47 * Redistribution and use in source and binary forms, with or without
48 * modification, are permitted provided that the following conditions
49 * are met:
50 * 1. Redistributions of source code must retain the above copyright
51 *    notice, this list of conditions and the following disclaimer.
52 * 2. Redistributions in binary form must reproduce the above copyright
53 *    notice, this list of conditions and the following disclaimer in the
54 *    documentation and/or other materials provided with the distribution.
55 * 3. Neither the name of the University nor the names of its contributors
56 *    may be used to endorse or promote products derived from this software
57 *    without specific prior written permission.
58 *
59 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
60 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
61 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
62 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
63 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69 * SUCH DAMAGE.
70 *
71 *	@(#)machdep.c	7.4 (Berkeley) 6/3/91
72 */
73
74#include <sys/cdefs.h>
75__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.57 2006/03/17 16:06:51 uebayasi Exp $");
76
77#include "opt_ddb.h"
78#include "opt_kgdb.h"
79#include "opt_memsize.h"
80#include "opt_initbsc.h"
81
82#include <sys/param.h>
83#include <sys/systm.h>
84#include <sys/kernel.h>
85#include <sys/user.h>
86#include <sys/mount.h>
87#include <sys/reboot.h>
88#include <sys/sysctl.h>
89#include <sys/ksyms.h>
90
91#include <uvm/uvm_extern.h>
92
93#include <dev/cons.h>
94
95#include <sh3/bscreg.h>
96#include <sh3/cpgreg.h>
97#include <sh3/cache_sh3.h>
98#include <sh3/cache_sh4.h>
99#include <sh3/exception.h>
100
101#include <machine/bus.h>
102#include <machine/intr.h>
103
104#ifdef DDB
105#include <machine/db_machdep.h>
106#include <ddb/db_extern.h>
107#endif
108
109#include "ksyms.h"
110
111/* the following is used externally (sysctl_hw) */
112char machine[] = MACHINE;		/* evbsh3 */
113char machine_arch[] = MACHINE_ARCH;	/* sh3eb or sh3el */
114
115void initSH3 __P((void *));
116void LoadAndReset __P((const char *));
117void XLoadAndReset __P((char *));
118
119/*
120 * Machine-dependent startup code
121 *
122 * This is called from main() in kern/main.c.
123 */
124void
125cpu_startup()
126{
127
128	sh_startup();
129}
130
131/*
132 * machine dependent system variables.
133 */
134static int
135sysctl_machdep_loadandreset(SYSCTLFN_ARGS)
136{
137	const char *osimage;
138	int error;
139
140	error = sysctl_lookup(SYSCTLFN_CALL(__UNCONST(rnode)));
141	if (error || newp == NULL)
142		return (error);
143
144	osimage = (const char *)(*(const u_long *)newp);
145	LoadAndReset(osimage);
146	/* not reach here */
147	return (0);
148}
149
150SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
151{
152
153	sysctl_createv(clog, 0, NULL, NULL,
154		       CTLFLAG_PERMANENT,
155		       CTLTYPE_NODE, "machdep", NULL,
156		       NULL, 0, NULL, 0,
157		       CTL_MACHDEP, CTL_EOL);
158
159	sysctl_createv(clog, 0, NULL, NULL,
160		       CTLFLAG_PERMANENT,
161		       CTLTYPE_STRUCT, "console_device", NULL,
162		       sysctl_consdev, 0, NULL, sizeof(dev_t),
163		       CTL_MACHDEP, CPU_CONSDEV, CTL_EOL);
164/*
165<atatat> okay...your turn to play.
166<atatat> pick a number.
167<kjk> 98752.
168*/
169	sysctl_createv(clog, 0, NULL, NULL,
170		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
171		       CTLTYPE_INT, "load_and_reset", NULL,
172		       sysctl_machdep_loadandreset, 98752, NULL, 0,
173		       CTL_MACHDEP, CPU_LOADANDRESET, CTL_EOL);
174}
175
176void
177cpu_reboot(howto, bootstr)
178	int howto;
179	char *bootstr;
180{
181	static int waittime = -1;
182
183	if (cold) {
184		howto |= RB_HALT;
185		goto haltsys;
186	}
187
188	boothowto = howto;
189	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
190		waittime = 0;
191		vfs_shutdown();
192		/*
193		 * If we've been adjusting the clock, the todr
194		 * will be out of synch; adjust it now.
195		 */
196		/* resettodr(); */
197	}
198
199	/* Disable interrupts. */
200	splhigh();
201
202	/* Do a dump if requested. */
203	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
204		dumpsys();
205
206haltsys:
207	doshutdownhooks();
208
209	if (howto & RB_HALT) {
210		printf("\n");
211		printf("The operating system has halted.\n");
212		printf("Please press any key to reboot.\n\n");
213		cngetc();
214	}
215
216	printf("rebooting...\n");
217	cpu_reset();
218	for(;;)
219		;
220	/*NOTREACHED*/
221}
222
223void
224initSH3(void *pc)	/* XXX return address */
225{
226	extern char edata[], end[];
227	vaddr_t kernend;
228
229	/* Clear bss */
230	memset(edata, 0, end - edata);
231
232	/* Initilize CPU ops. */
233#if defined(SH3) && defined(SH4)
234#error "don't define both SH3 and SH4"
235#elif defined(SH3)
236#if defined(SH7708)
237	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708);
238#elif defined(SH7708S)
239	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708S);
240#elif defined(SH7708R)
241	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708R);
242#elif defined(SH7709)
243	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7709);
244#elif defined(SH7709A)
245	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7709A);
246#else
247#error "unsupported SH3 variants"
248#endif
249#elif defined(SH4)
250#if defined(SH7750)
251	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7750);
252#elif defined(SH7750S)
253	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7750S);
254#else
255#error "unsupported SH4 variants"
256#endif
257#else
258#error "define SH3 or SH4"
259#endif
260	/* Console */
261	consinit();
262
263	/* Load memory to UVM */
264	kernend = atop(round_page(SH3_P1SEG_TO_PHYS(end)));
265	physmem = atop(IOM_RAM_SIZE);
266	uvm_page_physload(
267		kernend, atop(IOM_RAM_BEGIN + IOM_RAM_SIZE),
268		kernend, atop(IOM_RAM_BEGIN + IOM_RAM_SIZE),
269		VM_FREELIST_DEFAULT);
270
271	/* Initialize proc0 u-area */
272	sh_proc0_init();
273
274	/* Initialize pmap and start to address translation */
275	pmap_bootstrap();
276
277#if NKSYMS || defined(DDB) || defined(LKM)
278	ksyms_init(0, NULL, NULL);
279#endif
280
281	/*
282	 * XXX We can't return here, because we change stack pointer.
283	 *     So jump to return address directly.
284	 */
285	__asm volatile (
286		"jmp	@%0;"
287		"mov	%1, r15"
288		:: "r"(pc),"r"(lwp0.l_md.md_pcb->pcb_sf.sf_r7_bank));
289}
290
291/*
292 * consinit:
293 * initialize the system console.
294 * XXX - shouldn't deal with this initted thing, but then,
295 * it shouldn't be called from init386 either.
296 */
297void
298consinit()
299{
300	static int initted;
301
302	if (initted)
303		return;
304	initted = 1;
305
306	cninit();
307}
308
309int
310bus_space_map (t, addr, size, flags, bshp)
311	bus_space_tag_t t;
312	bus_addr_t addr;
313	bus_size_t size;
314	int flags;
315	bus_space_handle_t *bshp;
316{
317
318	*bshp = (bus_space_handle_t)addr;
319
320	return 0;
321}
322
323int
324sh_memio_subregion(t, bsh, offset, size, nbshp)
325	bus_space_tag_t t;
326	bus_space_handle_t bsh;
327	bus_size_t offset, size;
328	bus_space_handle_t *nbshp;
329{
330
331	*nbshp = bsh + offset;
332	return (0);
333}
334
335int
336sh_memio_alloc(t, rstart, rend, size, alignment, boundary, flags,
337	       bpap, bshp)
338	bus_space_tag_t t;
339	bus_addr_t rstart, rend;
340	bus_size_t size, alignment, boundary;
341	int flags;
342	bus_addr_t *bpap;
343	bus_space_handle_t *bshp;
344{
345	*bshp = *bpap = rstart;
346
347	return (0);
348}
349
350void
351sh_memio_free(t, bsh, size)
352	bus_space_tag_t t;
353	bus_space_handle_t bsh;
354	bus_size_t size;
355{
356
357}
358
359void
360sh_memio_unmap(t, bsh, size)
361	bus_space_tag_t t;
362	bus_space_handle_t bsh;
363	bus_size_t size;
364{
365	return;
366}
367
368#ifdef SH4_PCMCIA
369
370int
371shpcmcia_memio_map(t, bpa, size, flags, bshp)
372	bus_space_tag_t t;
373	bus_addr_t bpa;
374	bus_size_t size;
375	int flags;
376	bus_space_handle_t *bshp;
377{
378	int error;
379	struct extent *ex;
380	bus_space_tag_t pt = t & ~SH3_BUS_SPACE_PCMCIA_8BIT;
381
382	if (pt != SH3_BUS_SPACE_PCMCIA_IO &&
383	    pt != SH3_BUS_SPACE_PCMCIA_MEM &&
384	    pt != SH3_BUS_SPACE_PCMCIA_ATT) {
385		*bshp = (bus_space_handle_t)bpa;
386
387		return 0;
388	}
389
390	ex = iomem_ex;
391
392#if 0
393	/*
394	 * Before we go any further, let's make sure that this
395	 * region is available.
396	 */
397	error = extent_alloc_region(ex, bpa, size,
398				    EX_NOWAIT | EX_MALLOCOK );
399	if (error){
400		printf("sh3_pcmcia_memio_map:extent_alloc_region error\n");
401		return (error);
402	}
403#endif
404
405	/*
406	 * For memory space, map the bus physical address to
407	 * a kernel virtual address.
408	 */
409	error = shpcmcia_mem_add_mapping(bpa, size, (int)t, bshp );
410#if 0
411	if (error) {
412		if (extent_free(ex, bpa, size, EX_NOWAIT | EX_MALLOCOK )) {
413			printf("sh3_pcmcia_memio_map: pa 0x%lx, size 0x%lx\n",
414			       bpa, size);
415			printf("sh3_pcmcia_memio_map: can't free region\n");
416		}
417	}
418#endif
419
420	return (error);
421}
422
423int
424shpcmcia_mem_add_mapping(bpa, size, type, bshp)
425	bus_addr_t bpa;
426	bus_size_t size;
427	int type;
428	bus_space_handle_t *bshp;
429{
430	u_long pa, endpa;
431	vaddr_t va;
432	pt_entry_t *pte;
433	unsigned int m = 0;
434	int io_type = type & ~SH3_BUS_SPACE_PCMCIA_8BIT;
435
436	pa = sh3_trunc_page(bpa);
437	endpa = sh3_round_page(bpa + size);
438
439#ifdef DIAGNOSTIC
440	if (endpa <= pa)
441		panic("sh3_pcmcia_mem_add_mapping: overflow");
442#endif
443
444	va = uvm_km_alloc(kernel_map, endpa - pa, 0,
445	    UVM_KMF_VAONLY | UVM_KMF_NOWAIT);
446	if (va == 0){
447		printf("shpcmcia_add_mapping: nomem \n");
448		return (ENOMEM);
449	}
450
451	*bshp = (bus_space_handle_t)(va + (bpa & PGOFSET));
452
453#define MODE(t, s)							\
454	(t) & SH3_BUS_SPACE_PCMCIA_8BIT ?				\
455		_PG_PCMCIA_ ## s ## 8 :					\
456		_PG_PCMCIA_ ## s ## 16
457	switch (io_type) {
458	default:
459		panic("unknown pcmcia space.");
460		/* NOTREACHED */
461	case SH3_BUS_SPACE_PCMCIA_IO:
462		m = MODE(type, IO);
463		break;
464	case SH3_BUS_SPACE_PCMCIA_MEM:
465		m = MODE(type, MEM);
466		break;
467	case SH3_BUS_SPACE_PCMCIA_ATT:
468		m = MODE(type, ATTR);
469		break;
470	}
471#undef MODE
472
473	for (; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) {
474		pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE);
475		pte = __pmap_kpte_lookup(va);
476		KDASSERT(pte);
477		*pte |= m;  /* PTEA PCMCIA assistant bit */
478		sh_tlb_update(0, va, *pte);
479	}
480
481	return 0;
482}
483
484void
485shpcmcia_memio_unmap(t, bsh, size)
486	bus_space_tag_t t;
487	bus_space_handle_t bsh;
488	bus_size_t size;
489{
490	struct extent *ex;
491	u_long va, endva;
492	bus_addr_t bpa;
493	bus_space_tag_t pt = t & ~SH3_BUS_SPACE_PCMCIA_8BIT;
494
495	if (pt != SH3_BUS_SPACE_PCMCIA_IO &&
496	    pt != SH3_BUS_SPACE_PCMCIA_MEM &&
497	    pt != SH3_BUS_SPACE_PCMCIA_ATT) {
498		return ;
499	}
500
501	ex = iomem_ex;
502
503	va = sh3_trunc_page(bsh);
504	endva = sh3_round_page(bsh + size);
505
506#ifdef DIAGNOSTIC
507	if (endva <= va)
508		panic("sh3_pcmcia_memio_unmap: overflow");
509#endif
510
511	pmap_extract(pmap_kernel(), va, &bpa);
512	bpa += bsh & PGOFSET;
513
514	/*
515	 * Free the kernel virtual mapping.
516	 */
517	pmap_kremove(va, endva - va);
518	pmap_update(pmap_kernel());
519	uvm_km_free(kernel_map, va, endva - va, UVM_KMF_VAONLY);
520
521#if 0
522	if (extent_free(ex, bpa, size,
523			EX_NOWAIT | EX_MALLOCOK)) {
524		printf("sh3_pcmcia_memio_unmap: %s 0x%lx, size 0x%lx\n",
525		       "pa", bpa, size);
526		printf("sh3_pcmcia_memio_unmap: can't free region\n");
527	}
528#endif
529}
530
531void
532shpcmcia_memio_free(t, bsh, size)
533	bus_space_tag_t t;
534	bus_space_handle_t bsh;
535	bus_size_t size;
536{
537
538	/* sh3_pcmcia_memio_unmap() does all that we need to do. */
539	shpcmcia_memio_unmap(t, bsh, size);
540}
541
542int
543shpcmcia_memio_subregion(t, bsh, offset, size, nbshp)
544	bus_space_tag_t t;
545	bus_space_handle_t bsh;
546	bus_size_t offset, size;
547	bus_space_handle_t *nbshp;
548{
549
550	*nbshp = bsh + offset;
551	return (0);
552}
553
554#endif /* SH4_PCMCIA */
555
556#if !defined(DONT_INIT_BSC)
557/*
558 * InitializeBsc
559 * : BSC(Bus State Controller)
560 */
561void InitializeBsc __P((void));
562
563void
564InitializeBsc()
565{
566
567	/*
568	 * Drive RAS,CAS in stand by mode and bus release mode
569	 * Area0 = Normal memory, Area5,6=Normal(no burst)
570	 * Area2 = Normal memory, Area3 = SDRAM, Area5 = Normal memory
571	 * Area4 = Normal Memory
572	 * Area6 = Normal memory
573	 */
574#if defined(SH3)
575	_reg_write_2(SH3_BCR1, BSC_BCR1_VAL);
576#elif defined(SH4)
577	_reg_write_4(SH4_BCR1, BSC_BCR1_VAL);
578#endif
579
580	/*
581	 * Bus Width
582	 * Area4: Bus width = 16bit
583	 * Area6,5 = 16bit
584	 * Area1 = 8bit
585	 * Area2,3: Bus width = 32bit
586	 */
587	_reg_write_2(SH_(BCR2), BSC_BCR2_VAL);
588
589	/*
590	 * Idle cycle number in transition area and read to write
591	 * Area6 = 3, Area5 = 3, Area4 = 3, Area3 = 3, Area2 = 3
592	 * Area1 = 3, Area0 = 3
593	 */
594#if defined(SH3)
595	_reg_write_2(SH3_WCR1, BSC_WCR1_VAL);
596#elif defined(SH4)
597	_reg_write_4(SH4_WCR1, BSC_WCR1_VAL);
598#endif
599
600	/*
601	 * Wait cycle
602	 * Area 6 = 6
603	 * Area 5 = 2
604	 * Area 4 = 10
605	 * Area 3 = 3
606	 * Area 2,1 = 3
607	 * Area 0 = 6
608	 */
609#if defined(SH3)
610	_reg_write_2(SH3_WCR2, BSC_WCR2_VAL);
611#elif defined(SH4)
612	_reg_write_4(SH4_WCR2, BSC_WCR2_VAL);
613#endif
614
615#if defined(SH4) && defined(BSC_WCR3_VAL)
616	_reg_write_4(SH4_WCR3, BSC_WCR3_VAL);
617#endif
618
619	/*
620	 * RAS pre-charge = 2cycle, RAS-CAS delay = 3 cycle,
621	 * write pre-charge=1cycle
622	 * CAS before RAS refresh RAS assert time = 3 cycle
623	 * Disable burst, Bus size=32bit, Column Address=10bit, Refresh ON
624	 * CAS before RAS refresh ON, EDO DRAM
625	 */
626#if defined(SH3)
627	_reg_write_2(SH3_MCR, BSC_MCR_VAL);
628#elif defined(SH4)
629	_reg_write_4(SH4_MCR, BSC_MCR_VAL);
630#endif
631
632#if defined(BSC_SDMR2_VAL)
633	_reg_write_1(BSC_SDMR2_VAL, 0);
634#endif
635
636#if defined(BSC_SDMR3_VAL)
637#if !(defined(COMPUTEXEVB) && defined(SH7709A))
638	_reg_write_1(BSC_SDMR3_VAL, 0);
639#else
640	_reg_write_2(0x1a000000, 0);	/* ADDSET */
641	_reg_write_1(BSC_SDMR3_VAL, 0);
642	_reg_write_2(0x18000000, 0);	/* ADDRST */
643#endif /* !(COMPUTEXEVB && SH7709A) */
644#endif /* BSC_SDMR3_VAL */
645
646	/*
647	 * PCMCIA Control Register
648	 * OE/WE assert delay 3.5 cycle
649	 * OE/WE negate-address delay 3.5 cycle
650	 */
651#ifdef BSC_PCR_VAL
652	_reg_write_2(SH_(PCR), BSC_PCR_VAL);
653#endif
654
655	/*
656	 * Refresh Timer Control/Status Register
657	 * Disable interrupt by CMF, closk 1/16, Disable OVF interrupt
658	 * Count Limit = 1024
659	 * In following statement, the reason why high byte = 0xa5(a4 in RFCR)
660	 * is the rule of SH3 in writing these register.
661	 */
662	_reg_write_2(SH_(RTCSR), BSC_RTCSR_VAL);
663
664	/*
665	 * Refresh Timer Counter
666	 * Initialize to 0
667	 */
668#ifdef BSC_RTCNT_VAL
669	_reg_write_2(SH_(RTCNT), BSC_RTCNT_VAL);
670#endif
671
672	/* set Refresh Time Constant Register */
673	_reg_write_2(SH_(RTCOR), BSC_RTCOR_VAL);
674
675	/* init Refresh Count Register */
676#ifdef BSC_RFCR_VAL
677	_reg_write_2(SH_(RFCR), BSC_RFCR_VAL);
678#endif
679
680	/*
681	 * Clock Pulse Generator
682	 */
683	/* Set Clock mode (make internal clock double speed) */
684	_reg_write_2(SH_(FRQCR), FRQCR_VAL);
685
686	/*
687	 * Cache
688	 */
689#ifndef CACHE_DISABLE
690	/* Cache ON */
691	_reg_write_4(SH_(CCR), 0x1);
692#endif
693}
694#endif /* !DONT_INIT_BSC */
695
696
697 /* XXX This value depends on physical available memory */
698#define OSIMAGE_BUF_ADDR	(IOM_RAM_BEGIN + 0x00400000)
699
700void
701LoadAndReset(osimage)
702	const char *osimage;
703{
704	void *buf_addr;
705	u_long size;
706	const u_long *src;
707	u_long *dest;
708	u_long csum = 0;
709	u_long csum2 = 0;
710	u_long size2;
711
712	printf("LoadAndReset: copy start\n");
713	buf_addr = (void *)OSIMAGE_BUF_ADDR;
714
715	size = *(const u_long *)osimage;
716	src = (const u_long *)osimage;
717	dest = buf_addr;
718
719	size = (size + sizeof(u_long) * 2 + 3) >> 2;
720	size2 = size;
721
722	while (size--) {
723		csum += *src;
724		*dest++ = *src++;
725	}
726
727	dest = buf_addr;
728	while (size2--)
729		csum2 += *dest++;
730
731	printf("LoadAndReset: copy end[%lx,%lx]\n", csum, csum2);
732	printf("start XLoadAndReset\n");
733
734	/* mask all externel interrupt (XXX) */
735
736	XLoadAndReset(buf_addr);
737}
738
739void
740intc_intr(int ssr, int spc, int ssp)
741{
742	struct intc_intrhand *ih;
743	struct clockframe cf;
744	int s, evtcode;
745
746	switch (cpu_product) {
747	case CPU_PRODUCT_7708:
748	case CPU_PRODUCT_7708S:
749	case CPU_PRODUCT_7708R:
750		evtcode = _reg_read_4(SH3_INTEVT);
751		break;
752	case CPU_PRODUCT_7709:
753	case CPU_PRODUCT_7709A:
754		evtcode = _reg_read_4(SH7709_INTEVT2);
755		break;
756	case CPU_PRODUCT_7750:
757	case CPU_PRODUCT_7750S:
758		evtcode = _reg_read_4(SH4_INTEVT);
759		break;
760	default:
761#ifdef DIAGNOSTIC
762		panic("intr_intc: cpu_product %d unhandled!", cpu_product);
763#endif
764		return;
765	}
766
767	ih = EVTCODE_IH(evtcode);
768	KDASSERT(ih->ih_func);
769	/*
770	 * On entry, all interrrupts are disabled,
771	 * and exception is enabled for P3 access. (kernel stack is P3,
772	 * SH3 may or may not cause TLB miss when access stack.)
773	 * Enable higher level interrupt here.
774	 */
775	s = _cpu_intr_resume(ih->ih_level);
776
777	switch (evtcode) {
778	default:
779		(*ih->ih_func)(ih->ih_arg);
780		break;
781	case SH_INTEVT_TMU0_TUNI0:
782		cf.spc = spc;
783		cf.ssr = ssr;
784		cf.ssp = ssp;
785		(*ih->ih_func)(&cf);
786		break;
787	case SH_INTEVT_NMI:
788		printf("NMI ignored.\n");
789		break;
790	}
791}
792
793