machdep.c revision 1.48
1/*	$NetBSD: machdep.c,v 1.48 2003/08/07 16:27:24 agc 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.48 2003/08/07 16:27:24 agc 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((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 */
134int
135cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
136	int *name;
137	u_int namelen;
138	void *oldp;
139	size_t *oldlenp;
140	void *newp;
141	size_t newlen;
142	struct proc *p;
143{
144	dev_t consdev;
145	char *osimage;
146
147	/* all sysctl names at this level are terminal */
148	if (namelen != 1)
149		return (ENOTDIR);		/* overloaded */
150
151	switch (name[0]) {
152	case CPU_CONSDEV:
153		if (cn_tab != NULL)
154			consdev = cn_tab->cn_dev;
155		else
156			consdev = NODEV;
157		return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
158		    sizeof consdev));
159
160	case CPU_LOADANDRESET:
161		if (newp != NULL) {
162			osimage = (char *)(*(u_long *)newp);
163
164			LoadAndReset(osimage);
165			/* not reach here */
166		}
167		return (0);
168
169	default:
170		return (EOPNOTSUPP);
171	}
172	/* NOTREACHED */
173}
174
175void
176cpu_reboot(howto, bootstr)
177	int howto;
178	char *bootstr;
179{
180	static int waittime = -1;
181
182	if (cold) {
183		howto |= RB_HALT;
184		goto haltsys;
185	}
186
187	boothowto = howto;
188	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
189		waittime = 0;
190		vfs_shutdown();
191		/*
192		 * If we've been adjusting the clock, the todr
193		 * will be out of synch; adjust it now.
194		 */
195		/* resettodr(); */
196	}
197
198	/* Disable interrupts. */
199	splhigh();
200
201	/* Do a dump if requested. */
202	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
203		dumpsys();
204
205haltsys:
206	doshutdownhooks();
207
208	if (howto & RB_HALT) {
209		printf("\n");
210		printf("The operating system has halted.\n");
211		printf("Please press any key to reboot.\n\n");
212		cngetc();
213	}
214
215	printf("rebooting...\n");
216	cpu_reset();
217	for(;;)
218		;
219	/*NOTREACHED*/
220}
221
222void
223initSH3(void *pc)	/* XXX return address */
224{
225	extern char _edata[], _end[];
226	vaddr_t kernend;
227
228	/* Clear bss */
229	memset(_edata, 0, _end - _edata);
230
231	/* Initilize CPU ops. */
232#if defined(SH3) && defined(SH4)
233#error "don't define both SH3 and SH4"
234#elif defined(SH3)
235#if defined(SH7708)
236	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708);
237#elif defined(SH7708S)
238	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708S);
239#elif defined(SH7708R)
240	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708R);
241#elif defined(SH7709)
242	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7709);
243#elif defined(SH7709A)
244	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7709A);
245#else
246#error "unsupported SH3 variants"
247#endif
248#elif defined(SH4)
249#if defined(SH7750)
250	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7750);
251#elif defined(SH7750S)
252	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7750S);
253#else
254#error "unsupported SH4 variants"
255#endif
256#else
257#error "define SH3 or SH4"
258#endif
259	/* Console */
260	consinit();
261
262	/* Load memory to UVM */
263	kernend = atop(round_page(SH3_P1SEG_TO_PHYS(_end)));
264	physmem = atop(IOM_RAM_SIZE);
265	uvm_page_physload(
266		kernend, atop(IOM_RAM_BEGIN + IOM_RAM_SIZE),
267		kernend, atop(IOM_RAM_BEGIN + IOM_RAM_SIZE),
268		VM_FREELIST_DEFAULT);
269
270	/* Initialize proc0 u-area */
271	sh_proc0_init();
272
273	/* Initialize pmap and start to address translation */
274	pmap_bootstrap();
275
276#if NKSYMS || defined(DDB) || defined(LKM)
277	ksyms_init(0, NULL, NULL);
278#endif
279
280	/*
281	 * XXX We can't return here, because we change stack pointer.
282	 *     So jump to return address directly.
283	 */
284	__asm __volatile (
285		"jmp	@%0;"
286		"mov	%1, r15"
287		:: "r"(pc),"r"(lwp0.l_md.md_pcb->pcb_sf.sf_r7_bank));
288}
289
290/*
291 * consinit:
292 * initialize the system console.
293 * XXX - shouldn't deal with this initted thing, but then,
294 * it shouldn't be called from init386 either.
295 */
296void
297consinit()
298{
299	static int initted;
300
301	if (initted)
302		return;
303	initted = 1;
304
305	cninit();
306}
307
308int
309bus_space_map (t, addr, size, flags, bshp)
310	bus_space_tag_t t;
311	bus_addr_t addr;
312	bus_size_t size;
313	int flags;
314	bus_space_handle_t *bshp;
315{
316
317	*bshp = (bus_space_handle_t)addr;
318
319	return 0;
320}
321
322int
323sh_memio_subregion(t, bsh, offset, size, nbshp)
324	bus_space_tag_t t;
325	bus_space_handle_t bsh;
326	bus_size_t offset, size;
327	bus_space_handle_t *nbshp;
328{
329
330	*nbshp = bsh + offset;
331	return (0);
332}
333
334int
335sh_memio_alloc(t, rstart, rend, size, alignment, boundary, flags,
336	       bpap, bshp)
337	bus_space_tag_t t;
338	bus_addr_t rstart, rend;
339	bus_size_t size, alignment, boundary;
340	int flags;
341	bus_addr_t *bpap;
342	bus_space_handle_t *bshp;
343{
344	*bshp = *bpap = rstart;
345
346	return (0);
347}
348
349void
350sh_memio_free(t, bsh, size)
351	bus_space_tag_t t;
352	bus_space_handle_t bsh;
353	bus_size_t size;
354{
355
356}
357
358void
359sh_memio_unmap(t, bsh, size)
360	bus_space_tag_t t;
361	bus_space_handle_t bsh;
362	bus_size_t size;
363{
364	return;
365}
366
367#ifdef SH4_PCMCIA
368
369int
370shpcmcia_memio_map(t, bpa, size, flags, bshp)
371	bus_space_tag_t t;
372	bus_addr_t bpa;
373	bus_size_t size;
374	int flags;
375	bus_space_handle_t *bshp;
376{
377	int error;
378	struct extent *ex;
379	bus_space_tag_t pt = t & ~SH3_BUS_SPACE_PCMCIA_8BIT;
380
381	if (pt != SH3_BUS_SPACE_PCMCIA_IO &&
382	    pt != SH3_BUS_SPACE_PCMCIA_MEM &&
383	    pt != SH3_BUS_SPACE_PCMCIA_ATT) {
384		*bshp = (bus_space_handle_t)bpa;
385
386		return 0;
387	}
388
389	ex = iomem_ex;
390
391#if 0
392	/*
393	 * Before we go any further, let's make sure that this
394	 * region is available.
395	 */
396	error = extent_alloc_region(ex, bpa, size,
397				    EX_NOWAIT | EX_MALLOCOK );
398	if (error){
399		printf("sh3_pcmcia_memio_map:extent_alloc_region error\n");
400		return (error);
401	}
402#endif
403
404	/*
405	 * For memory space, map the bus physical address to
406	 * a kernel virtual address.
407	 */
408	error = shpcmcia_mem_add_mapping(bpa, size, (int)t, bshp );
409#if 0
410	if (error) {
411		if (extent_free(ex, bpa, size, EX_NOWAIT | EX_MALLOCOK )) {
412			printf("sh3_pcmcia_memio_map: pa 0x%lx, size 0x%lx\n",
413			       bpa, size);
414			printf("sh3_pcmcia_memio_map: can't free region\n");
415		}
416	}
417#endif
418
419	return (error);
420}
421
422int
423shpcmcia_mem_add_mapping(bpa, size, type, bshp)
424	bus_addr_t bpa;
425	bus_size_t size;
426	int type;
427	bus_space_handle_t *bshp;
428{
429	u_long pa, endpa;
430	vaddr_t va;
431	pt_entry_t *pte;
432	unsigned int m = 0;
433	int io_type = type & ~SH3_BUS_SPACE_PCMCIA_8BIT;
434
435	pa = sh3_trunc_page(bpa);
436	endpa = sh3_round_page(bpa + size);
437
438#ifdef DIAGNOSTIC
439	if (endpa <= pa)
440		panic("sh3_pcmcia_mem_add_mapping: overflow");
441#endif
442
443	va = uvm_km_valloc(kernel_map, endpa - pa);
444	if (va == 0){
445		printf("shpcmcia_add_mapping: nomem \n");
446		return (ENOMEM);
447	}
448
449	*bshp = (bus_space_handle_t)(va + (bpa & PGOFSET));
450
451#define MODE(t, s)							\
452	(t) & SH3_BUS_SPACE_PCMCIA_8BIT ?				\
453		_PG_PCMCIA_ ## s ## 8 :					\
454		_PG_PCMCIA_ ## s ## 16
455	switch (io_type) {
456	default:
457		panic("unknown pcmcia space.");
458		/* NOTREACHED */
459	case SH3_BUS_SPACE_PCMCIA_IO:
460		m = MODE(type, IO);
461		break;
462	case SH3_BUS_SPACE_PCMCIA_MEM:
463		m = MODE(type, MEM);
464		break;
465	case SH3_BUS_SPACE_PCMCIA_ATT:
466		m = MODE(type, ATTR);
467		break;
468	}
469#undef MODE
470
471	for (; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) {
472		pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE);
473		pte = __pmap_kpte_lookup(va);
474		KDASSERT(pte);
475		*pte |= m;  /* PTEA PCMCIA assistant bit */
476		sh_tlb_update(0, va, *pte);
477	}
478
479	return 0;
480}
481
482void
483shpcmcia_memio_unmap(t, bsh, size)
484	bus_space_tag_t t;
485	bus_space_handle_t bsh;
486	bus_size_t size;
487{
488	struct extent *ex;
489	u_long va, endva;
490	bus_addr_t bpa;
491	bus_space_tag_t pt = t & ~SH3_BUS_SPACE_PCMCIA_8BIT;
492
493	if (pt != SH3_BUS_SPACE_PCMCIA_IO &&
494	    pt != SH3_BUS_SPACE_PCMCIA_MEM &&
495	    pt != SH3_BUS_SPACE_PCMCIA_ATT) {
496		return ;
497	}
498
499	ex = iomem_ex;
500
501	va = sh3_trunc_page(bsh);
502	endva = sh3_round_page(bsh + size);
503
504#ifdef DIAGNOSTIC
505	if (endva <= va)
506		panic("sh3_pcmcia_memio_unmap: overflow");
507#endif
508
509	pmap_extract(pmap_kernel(), va, &bpa);
510	bpa += bsh & PGOFSET;
511
512	/*
513	 * Free the kernel virtual mapping.
514	 */
515	uvm_km_free(kernel_map, va, endva - va);
516
517#if 0
518	if (extent_free(ex, bpa, size,
519			EX_NOWAIT | EX_MALLOCOK)) {
520		printf("sh3_pcmcia_memio_unmap: %s 0x%lx, size 0x%lx\n",
521		       "pa", bpa, size);
522		printf("sh3_pcmcia_memio_unmap: can't free region\n");
523	}
524#endif
525}
526
527void
528shpcmcia_memio_free(t, bsh, size)
529	bus_space_tag_t t;
530	bus_space_handle_t bsh;
531	bus_size_t size;
532{
533
534	/* sh3_pcmcia_memio_unmap() does all that we need to do. */
535	shpcmcia_memio_unmap(t, bsh, size);
536}
537
538int
539shpcmcia_memio_subregion(t, bsh, offset, size, nbshp)
540	bus_space_tag_t t;
541	bus_space_handle_t bsh;
542	bus_size_t offset, size;
543	bus_space_handle_t *nbshp;
544{
545
546	*nbshp = bsh + offset;
547	return (0);
548}
549
550#endif /* SH4_PCMCIA */
551
552#if !defined(DONT_INIT_BSC)
553/*
554 * InitializeBsc
555 * : BSC(Bus State Controler)
556 */
557void InitializeBsc __P((void));
558
559void
560InitializeBsc()
561{
562
563	/*
564	 * Drive RAS,CAS in stand by mode and bus release mode
565	 * Area0 = Normal memory, Area5,6=Normal(no burst)
566	 * Area2 = Normal memory, Area3 = SDRAM, Area5 = Normal memory
567	 * Area4 = Normal Memory
568	 * Area6 = Normal memory
569	 */
570#if defined(SH3)
571	_reg_write_2(SH3_BCR1, BSC_BCR1_VAL);
572#elif defined(SH4)
573	_reg_write_4(SH4_BCR1, BSC_BCR1_VAL);
574#endif
575
576	/*
577	 * Bus Width
578	 * Area4: Bus width = 16bit
579	 * Area6,5 = 16bit
580	 * Area1 = 8bit
581	 * Area2,3: Bus width = 32bit
582	 */
583	_reg_write_2(SH_(BCR2), BSC_BCR2_VAL);
584
585	/*
586	 * Idle cycle number in transition area and read to write
587	 * Area6 = 3, Area5 = 3, Area4 = 3, Area3 = 3, Area2 = 3
588	 * Area1 = 3, Area0 = 3
589	 */
590#if defined(SH3)
591	_reg_write_2(SH3_WCR1, BSC_WCR1_VAL);
592#elif defined(SH4)
593	_reg_write_4(SH4_WCR1, BSC_WCR1_VAL);
594#endif
595
596	/*
597	 * Wait cycle
598	 * Area 6 = 6
599	 * Area 5 = 2
600	 * Area 4 = 10
601	 * Area 3 = 3
602	 * Area 2,1 = 3
603	 * Area 0 = 6
604	 */
605#if defined(SH3)
606	_reg_write_2(SH3_WCR2, BSC_WCR2_VAL);
607#elif defined(SH4)
608	_reg_write_4(SH4_WCR2, BSC_WCR2_VAL);
609#endif
610
611#if defined(SH4) && defined(BSC_WCR3_VAL)
612	_reg_write_4(SH4_WCR3, BSC_WCR3_VAL);
613#endif
614
615	/*
616	 * RAS pre-charge = 2cycle, RAS-CAS delay = 3 cycle,
617	 * write pre-charge=1cycle
618	 * CAS before RAS refresh RAS assert time = 3 cycle
619	 * Disable burst, Bus size=32bit, Column Address=10bit, Refresh ON
620	 * CAS before RAS refresh ON, EDO DRAM
621	 */
622#if defined(SH3)
623	_reg_write_2(SH3_MCR, BSC_MCR_VAL);
624#elif defined(SH4)
625	_reg_write_4(SH4_MCR, BSC_MCR_VAL);
626#endif
627
628#if defined(BSC_SDMR2_VAL)
629	_reg_write_1(BSC_SDMR2_VAL, 0);
630#endif
631
632#if defined(BSC_SDMR3_VAL)
633#if !(defined(COMPUTEXEVB) && defined(SH7709A))
634	_reg_write_1(BSC_SDMR3_VAL, 0);
635#else
636	_reg_write_2(0x1a000000, 0);	/* ADDSET */
637	_reg_write_1(BSC_SDMR3_VAL, 0);
638	_reg_write_2(0x18000000, 0);	/* ADDRST */
639#endif /* !(COMPUTEXEVB && SH7709A) */
640#endif /* BSC_SDMR3_VAL */
641
642	/*
643	 * PCMCIA Control Register
644	 * OE/WE assert delay 3.5 cycle
645	 * OE/WE negate-address delay 3.5 cycle
646	 */
647#ifdef BSC_PCR_VAL
648	_reg_write_2(SH_(PCR), BSC_PCR_VAL);
649#endif
650
651	/*
652	 * Refresh Timer Control/Status Register
653	 * Disable interrupt by CMF, closk 1/16, Disable OVF interrupt
654	 * Count Limit = 1024
655	 * In following statement, the reason why high byte = 0xa5(a4 in RFCR)
656	 * is the rule of SH3 in writing these register.
657	 */
658	_reg_write_2(SH_(RTCSR), BSC_RTCSR_VAL);
659
660	/*
661	 * Refresh Timer Counter
662	 * Initialize to 0
663	 */
664#ifdef BSC_RTCNT_VAL
665	_reg_write_2(SH_(RTCNT), BSC_RTCNT_VAL);
666#endif
667
668	/* set Refresh Time Constant Register */
669	_reg_write_2(SH_(RTCOR), BSC_RTCOR_VAL);
670
671	/* init Refresh Count Register */
672#ifdef BSC_RFCR_VAL
673	_reg_write_2(SH_(RFCR), BSC_RFCR_VAL);
674#endif
675
676	/*
677	 * Clock Pulse Generator
678	 */
679	/* Set Clock mode (make internal clock double speed) */
680	_reg_write_2(SH_(FRQCR), FRQCR_VAL);
681
682	/*
683	 * Cache
684	 */
685#ifndef CACHE_DISABLE
686	/* Cache ON */
687	_reg_write_4(SH_(CCR), 0x1);
688#endif
689}
690#endif /* !DONT_INIT_BSC */
691
692
693 /* XXX This value depends on physical available memory */
694#define OSIMAGE_BUF_ADDR	(IOM_RAM_BEGIN + 0x00400000)
695
696void
697LoadAndReset(osimage)
698	char *osimage;
699{
700	void *buf_addr;
701	u_long size;
702	u_long *src;
703	u_long *dest;
704	u_long csum = 0;
705	u_long csum2 = 0;
706	u_long size2;
707
708	printf("LoadAndReset: copy start\n");
709	buf_addr = (void *)OSIMAGE_BUF_ADDR;
710
711	size = *(u_long *)osimage;
712	src = (u_long *)osimage;
713	dest = buf_addr;
714
715	size = (size + sizeof(u_long) * 2 + 3) >> 2;
716	size2 = size;
717
718	while (size--) {
719		csum += *src;
720		*dest++ = *src++;
721	}
722
723	dest = buf_addr;
724	while (size2--)
725		csum2 += *dest++;
726
727	printf("LoadAndReset: copy end[%lx,%lx]\n", csum, csum2);
728	printf("start XLoadAndReset\n");
729
730	/* mask all externel interrupt (XXX) */
731
732	XLoadAndReset(buf_addr);
733}
734
735void
736intc_intr(int ssr, int spc, int ssp)
737{
738	struct intc_intrhand *ih;
739	struct clockframe cf;
740	int s, evtcode;
741
742	switch (cpu_product) {
743	case CPU_PRODUCT_7708:
744	case CPU_PRODUCT_7708S:
745	case CPU_PRODUCT_7708R:
746		evtcode = _reg_read_4(SH3_INTEVT);
747		break;
748	case CPU_PRODUCT_7709:
749	case CPU_PRODUCT_7709A:
750		evtcode = _reg_read_4(SH7709_INTEVT2);
751		break;
752	case CPU_PRODUCT_7750:
753	case CPU_PRODUCT_7750S:
754		evtcode = _reg_read_4(SH4_INTEVT);
755		break;
756	}
757
758	ih = EVTCODE_IH(evtcode);
759	KDASSERT(ih->ih_func);
760	/*
761	 * On entry, all interrrupts are disabled,
762	 * and exception is enabled for P3 access. (kernel stack is P3,
763	 * SH3 may or may not cause TLB miss when access stack.)
764	 * Enable higher level interrupt here.
765	 */
766	s = _cpu_intr_resume(ih->ih_level);
767
768	switch (evtcode) {
769	default:
770		(*ih->ih_func)(ih->ih_arg);
771		break;
772	case SH_INTEVT_TMU0_TUNI0:
773		cf.spc = spc;
774		cf.ssr = ssr;
775		cf.ssp = ssp;
776		(*ih->ih_func)(&cf);
777		break;
778	case SH_INTEVT_NMI:
779		printf("NMI ignored.\n");
780		break;
781	}
782}
783
784