machdep.c revision 1.47
1/*	$NetBSD: machdep.c,v 1.47 2003/07/15 01:37:39 lukem 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. All advertising materials mentioning features or use of this software
56 *    must display the following acknowledgement:
57 *	This product includes software developed by the University of
58 *	California, Berkeley and its contributors.
59 * 4. Neither the name of the University nor the names of its contributors
60 *    may be used to endorse or promote products derived from this software
61 *    without specific prior written permission.
62 *
63 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
64 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
65 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
66 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
67 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
68 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
69 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
70 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
71 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
72 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
73 * SUCH DAMAGE.
74 *
75 *	@(#)machdep.c	7.4 (Berkeley) 6/3/91
76 */
77
78#include <sys/cdefs.h>
79__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.47 2003/07/15 01:37:39 lukem Exp $");
80
81#include "opt_ddb.h"
82#include "opt_kgdb.h"
83#include "opt_memsize.h"
84#include "opt_initbsc.h"
85
86#include <sys/param.h>
87#include <sys/systm.h>
88#include <sys/kernel.h>
89#include <sys/user.h>
90#include <sys/mount.h>
91#include <sys/reboot.h>
92#include <sys/sysctl.h>
93#include <sys/ksyms.h>
94
95#include <uvm/uvm_extern.h>
96
97#include <dev/cons.h>
98
99#include <sh3/bscreg.h>
100#include <sh3/cpgreg.h>
101#include <sh3/cache_sh3.h>
102#include <sh3/cache_sh4.h>
103#include <sh3/exception.h>
104
105#include <machine/bus.h>
106#include <machine/intr.h>
107
108#ifdef DDB
109#include <machine/db_machdep.h>
110#include <ddb/db_extern.h>
111#endif
112
113#include "ksyms.h"
114
115/* the following is used externally (sysctl_hw) */
116char machine[] = MACHINE;		/* evbsh3 */
117char machine_arch[] = MACHINE_ARCH;	/* sh3eb or sh3el */
118
119void initSH3 __P((void *));
120void LoadAndReset __P((char *));
121void XLoadAndReset __P((char *));
122
123/*
124 * Machine-dependent startup code
125 *
126 * This is called from main() in kern/main.c.
127 */
128void
129cpu_startup()
130{
131
132	sh_startup();
133}
134
135/*
136 * machine dependent system variables.
137 */
138int
139cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
140	int *name;
141	u_int namelen;
142	void *oldp;
143	size_t *oldlenp;
144	void *newp;
145	size_t newlen;
146	struct proc *p;
147{
148	dev_t consdev;
149	char *osimage;
150
151	/* all sysctl names at this level are terminal */
152	if (namelen != 1)
153		return (ENOTDIR);		/* overloaded */
154
155	switch (name[0]) {
156	case CPU_CONSDEV:
157		if (cn_tab != NULL)
158			consdev = cn_tab->cn_dev;
159		else
160			consdev = NODEV;
161		return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
162		    sizeof consdev));
163
164	case CPU_LOADANDRESET:
165		if (newp != NULL) {
166			osimage = (char *)(*(u_long *)newp);
167
168			LoadAndReset(osimage);
169			/* not reach here */
170		}
171		return (0);
172
173	default:
174		return (EOPNOTSUPP);
175	}
176	/* NOTREACHED */
177}
178
179void
180cpu_reboot(howto, bootstr)
181	int howto;
182	char *bootstr;
183{
184	static int waittime = -1;
185
186	if (cold) {
187		howto |= RB_HALT;
188		goto haltsys;
189	}
190
191	boothowto = howto;
192	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
193		waittime = 0;
194		vfs_shutdown();
195		/*
196		 * If we've been adjusting the clock, the todr
197		 * will be out of synch; adjust it now.
198		 */
199		/* resettodr(); */
200	}
201
202	/* Disable interrupts. */
203	splhigh();
204
205	/* Do a dump if requested. */
206	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
207		dumpsys();
208
209haltsys:
210	doshutdownhooks();
211
212	if (howto & RB_HALT) {
213		printf("\n");
214		printf("The operating system has halted.\n");
215		printf("Please press any key to reboot.\n\n");
216		cngetc();
217	}
218
219	printf("rebooting...\n");
220	cpu_reset();
221	for(;;)
222		;
223	/*NOTREACHED*/
224}
225
226void
227initSH3(void *pc)	/* XXX return address */
228{
229	extern char _edata[], _end[];
230	vaddr_t kernend;
231
232	/* Clear bss */
233	memset(_edata, 0, _end - _edata);
234
235	/* Initilize CPU ops. */
236#if defined(SH3) && defined(SH4)
237#error "don't define both SH3 and SH4"
238#elif defined(SH3)
239#if defined(SH7708)
240	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708);
241#elif defined(SH7708S)
242	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708S);
243#elif defined(SH7708R)
244	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708R);
245#elif defined(SH7709)
246	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7709);
247#elif defined(SH7709A)
248	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7709A);
249#else
250#error "unsupported SH3 variants"
251#endif
252#elif defined(SH4)
253#if defined(SH7750)
254	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7750);
255#elif defined(SH7750S)
256	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7750S);
257#else
258#error "unsupported SH4 variants"
259#endif
260#else
261#error "define SH3 or SH4"
262#endif
263	/* Console */
264	consinit();
265
266	/* Load memory to UVM */
267	kernend = atop(round_page(SH3_P1SEG_TO_PHYS(_end)));
268	physmem = atop(IOM_RAM_SIZE);
269	uvm_page_physload(
270		kernend, atop(IOM_RAM_BEGIN + IOM_RAM_SIZE),
271		kernend, atop(IOM_RAM_BEGIN + IOM_RAM_SIZE),
272		VM_FREELIST_DEFAULT);
273
274	/* Initialize proc0 u-area */
275	sh_proc0_init();
276
277	/* Initialize pmap and start to address translation */
278	pmap_bootstrap();
279
280#if NKSYMS || defined(DDB) || defined(LKM)
281	ksyms_init(0, NULL, NULL);
282#endif
283
284	/*
285	 * XXX We can't return here, because we change stack pointer.
286	 *     So jump to return address directly.
287	 */
288	__asm __volatile (
289		"jmp	@%0;"
290		"mov	%1, r15"
291		:: "r"(pc),"r"(lwp0.l_md.md_pcb->pcb_sf.sf_r7_bank));
292}
293
294/*
295 * consinit:
296 * initialize the system console.
297 * XXX - shouldn't deal with this initted thing, but then,
298 * it shouldn't be called from init386 either.
299 */
300void
301consinit()
302{
303	static int initted;
304
305	if (initted)
306		return;
307	initted = 1;
308
309	cninit();
310}
311
312int
313bus_space_map (t, addr, size, flags, bshp)
314	bus_space_tag_t t;
315	bus_addr_t addr;
316	bus_size_t size;
317	int flags;
318	bus_space_handle_t *bshp;
319{
320
321	*bshp = (bus_space_handle_t)addr;
322
323	return 0;
324}
325
326int
327sh_memio_subregion(t, bsh, offset, size, nbshp)
328	bus_space_tag_t t;
329	bus_space_handle_t bsh;
330	bus_size_t offset, size;
331	bus_space_handle_t *nbshp;
332{
333
334	*nbshp = bsh + offset;
335	return (0);
336}
337
338int
339sh_memio_alloc(t, rstart, rend, size, alignment, boundary, flags,
340	       bpap, bshp)
341	bus_space_tag_t t;
342	bus_addr_t rstart, rend;
343	bus_size_t size, alignment, boundary;
344	int flags;
345	bus_addr_t *bpap;
346	bus_space_handle_t *bshp;
347{
348	*bshp = *bpap = rstart;
349
350	return (0);
351}
352
353void
354sh_memio_free(t, bsh, size)
355	bus_space_tag_t t;
356	bus_space_handle_t bsh;
357	bus_size_t size;
358{
359
360}
361
362void
363sh_memio_unmap(t, bsh, size)
364	bus_space_tag_t t;
365	bus_space_handle_t bsh;
366	bus_size_t size;
367{
368	return;
369}
370
371#ifdef SH4_PCMCIA
372
373int
374shpcmcia_memio_map(t, bpa, size, flags, bshp)
375	bus_space_tag_t t;
376	bus_addr_t bpa;
377	bus_size_t size;
378	int flags;
379	bus_space_handle_t *bshp;
380{
381	int error;
382	struct extent *ex;
383	bus_space_tag_t pt = t & ~SH3_BUS_SPACE_PCMCIA_8BIT;
384
385	if (pt != SH3_BUS_SPACE_PCMCIA_IO &&
386	    pt != SH3_BUS_SPACE_PCMCIA_MEM &&
387	    pt != SH3_BUS_SPACE_PCMCIA_ATT) {
388		*bshp = (bus_space_handle_t)bpa;
389
390		return 0;
391	}
392
393	ex = iomem_ex;
394
395#if 0
396	/*
397	 * Before we go any further, let's make sure that this
398	 * region is available.
399	 */
400	error = extent_alloc_region(ex, bpa, size,
401				    EX_NOWAIT | EX_MALLOCOK );
402	if (error){
403		printf("sh3_pcmcia_memio_map:extent_alloc_region error\n");
404		return (error);
405	}
406#endif
407
408	/*
409	 * For memory space, map the bus physical address to
410	 * a kernel virtual address.
411	 */
412	error = shpcmcia_mem_add_mapping(bpa, size, (int)t, bshp );
413#if 0
414	if (error) {
415		if (extent_free(ex, bpa, size, EX_NOWAIT | EX_MALLOCOK )) {
416			printf("sh3_pcmcia_memio_map: pa 0x%lx, size 0x%lx\n",
417			       bpa, size);
418			printf("sh3_pcmcia_memio_map: can't free region\n");
419		}
420	}
421#endif
422
423	return (error);
424}
425
426int
427shpcmcia_mem_add_mapping(bpa, size, type, bshp)
428	bus_addr_t bpa;
429	bus_size_t size;
430	int type;
431	bus_space_handle_t *bshp;
432{
433	u_long pa, endpa;
434	vaddr_t va;
435	pt_entry_t *pte;
436	unsigned int m = 0;
437	int io_type = type & ~SH3_BUS_SPACE_PCMCIA_8BIT;
438
439	pa = sh3_trunc_page(bpa);
440	endpa = sh3_round_page(bpa + size);
441
442#ifdef DIAGNOSTIC
443	if (endpa <= pa)
444		panic("sh3_pcmcia_mem_add_mapping: overflow");
445#endif
446
447	va = uvm_km_valloc(kernel_map, endpa - pa);
448	if (va == 0){
449		printf("shpcmcia_add_mapping: nomem \n");
450		return (ENOMEM);
451	}
452
453	*bshp = (bus_space_handle_t)(va + (bpa & PGOFSET));
454
455#define MODE(t, s)							\
456	(t) & SH3_BUS_SPACE_PCMCIA_8BIT ?				\
457		_PG_PCMCIA_ ## s ## 8 :					\
458		_PG_PCMCIA_ ## s ## 16
459	switch (io_type) {
460	default:
461		panic("unknown pcmcia space.");
462		/* NOTREACHED */
463	case SH3_BUS_SPACE_PCMCIA_IO:
464		m = MODE(type, IO);
465		break;
466	case SH3_BUS_SPACE_PCMCIA_MEM:
467		m = MODE(type, MEM);
468		break;
469	case SH3_BUS_SPACE_PCMCIA_ATT:
470		m = MODE(type, ATTR);
471		break;
472	}
473#undef MODE
474
475	for (; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) {
476		pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE);
477		pte = __pmap_kpte_lookup(va);
478		KDASSERT(pte);
479		*pte |= m;  /* PTEA PCMCIA assistant bit */
480		sh_tlb_update(0, va, *pte);
481	}
482
483	return 0;
484}
485
486void
487shpcmcia_memio_unmap(t, bsh, size)
488	bus_space_tag_t t;
489	bus_space_handle_t bsh;
490	bus_size_t size;
491{
492	struct extent *ex;
493	u_long va, endva;
494	bus_addr_t bpa;
495	bus_space_tag_t pt = t & ~SH3_BUS_SPACE_PCMCIA_8BIT;
496
497	if (pt != SH3_BUS_SPACE_PCMCIA_IO &&
498	    pt != SH3_BUS_SPACE_PCMCIA_MEM &&
499	    pt != SH3_BUS_SPACE_PCMCIA_ATT) {
500		return ;
501	}
502
503	ex = iomem_ex;
504
505	va = sh3_trunc_page(bsh);
506	endva = sh3_round_page(bsh + size);
507
508#ifdef DIAGNOSTIC
509	if (endva <= va)
510		panic("sh3_pcmcia_memio_unmap: overflow");
511#endif
512
513	pmap_extract(pmap_kernel(), va, &bpa);
514	bpa += bsh & PGOFSET;
515
516	/*
517	 * Free the kernel virtual mapping.
518	 */
519	uvm_km_free(kernel_map, va, endva - va);
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 Controler)
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	char *osimage;
703{
704	void *buf_addr;
705	u_long size;
706	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 = *(u_long *)osimage;
716	src = (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	}
761
762	ih = EVTCODE_IH(evtcode);
763	KDASSERT(ih->ih_func);
764	/*
765	 * On entry, all interrrupts are disabled,
766	 * and exception is enabled for P3 access. (kernel stack is P3,
767	 * SH3 may or may not cause TLB miss when access stack.)
768	 * Enable higher level interrupt here.
769	 */
770	s = _cpu_intr_resume(ih->ih_level);
771
772	switch (evtcode) {
773	default:
774		(*ih->ih_func)(ih->ih_arg);
775		break;
776	case SH_INTEVT_TMU0_TUNI0:
777		cf.spc = spc;
778		cf.ssr = ssr;
779		cf.ssp = ssp;
780		(*ih->ih_func)(&cf);
781		break;
782	case SH_INTEVT_NMI:
783		printf("NMI ignored.\n");
784		break;
785	}
786}
787
788