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