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