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