machdep.c revision 1.5
1/*	$NetBSD: machdep.c,v 1.5 1999/09/21 13:16:15 tsubai 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_memsize.h"
80#include "opt_initbsc.h"
81
82#include <sys/param.h>
83#include <sys/systm.h>
84#include <sys/signalvar.h>
85#include <sys/kernel.h>
86#include <sys/map.h>
87#include <sys/proc.h>
88#include <sys/user.h>
89#include <sys/exec.h>
90#include <sys/buf.h>
91#include <sys/reboot.h>
92#include <sys/conf.h>
93#include <sys/file.h>
94#include <sys/callout.h>
95#include <sys/malloc.h>
96#include <sys/mbuf.h>
97#include <sys/msgbuf.h>
98#include <sys/mount.h>
99#include <sys/vnode.h>
100#include <sys/device.h>
101#include <sys/extent.h>
102#include <sys/syscallargs.h>
103
104#ifdef KGDB
105#include <sys/kgdb.h>
106#endif
107
108#include <dev/cons.h>
109
110#include <vm/vm.h>
111#include <vm/vm_kern.h>
112#include <vm/vm_page.h>
113
114#include <uvm/uvm_extern.h>
115
116#include <sys/sysctl.h>
117
118#include <machine/cpu.h>
119#include <machine/cpufunc.h>
120#include <machine/psl.h>
121#include <machine/bootinfo.h>
122#include <machine/bus.h>
123#include <sh3/bscreg.h>
124#include <sh3/ccrreg.h>
125#include <sh3/cpgreg.h>
126#include <sh3/intcreg.h>
127#include <sh3/pfcreg.h>
128#include <sh3/wdtreg.h>
129
130#include <sys/termios.h>
131#include "sci.h"
132
133/* the following is used externally (sysctl_hw) */
134char machine[] = MACHINE;		/* cpu "architecture" */
135char machine_arch[] = MACHINE_ARCH;	/* machine_arch = "sh3" */
136
137#ifdef sh3_debug
138int cpu_debug_mode = 1;
139#else
140int cpu_debug_mode = 0;
141#endif
142
143char bootinfo[BOOTINFO_MAXSIZE];
144
145int physmem;
146int dumpmem_low;
147int dumpmem_high;
148vaddr_t atdevbase;	/* location of start of iomem in virtual */
149paddr_t msgbuf_paddr;
150struct user *proc0paddr;
151
152extern int boothowto;
153extern paddr_t avail_start, avail_end;
154
155#ifdef	SYSCALL_DEBUG
156#define	SCDEBUG_ALL 0x0004
157extern int	scdebug;
158#endif
159
160#define IOM_RAM_END	((paddr_t)IOM_RAM_BEGIN + IOM_RAM_SIZE - 1)
161
162/*
163 * Extent maps to manage I/O and ISA memory hole space.  Allocate
164 * storage for 8 regions in each, initially.  Later, ioport_malloc_safe
165 * will indicate that it's safe to use malloc() to dynamically allocate
166 * region descriptors.
167 *
168 * N.B. At least two regions are _always_ allocated from the iomem
169 * extent map; (0 -> ISA hole) and (end of ISA hole -> end of RAM).
170 *
171 * The extent maps are not static!  Machine-dependent ISA and EISA
172 * routines need access to them for bus address space allocation.
173 */
174static	long iomem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)];
175struct	extent *ioport_ex;
176struct	extent *iomem_ex;
177static	int ioport_malloc_safe;
178
179void setup_bootinfo __P((void));
180void dumpsys __P((void));
181void identifycpu __P((void));
182void initSH3 __P((void *));
183void InitializeSci  __P((unsigned char));
184void sh3_cache_on __P((void));
185void LoadAndReset __P((char *));
186void XLoadAndReset __P((char *));
187void Sh3Reset __P((void));
188
189#include <dev/ic/comreg.h>
190#include <dev/ic/comvar.h>
191
192void	consinit __P((void));
193
194/*
195 * Machine-dependent startup code
196 *
197 * This is called from main() in kern/main.c.
198 */
199void
200cpu_startup()
201{
202
203	sh3_startup();
204
205	/* Safe for i/o port allocation to use malloc now. */
206	ioport_malloc_safe = 1;
207
208#ifdef SYSCALL_DEBUG
209	scdebug |= SCDEBUG_ALL;
210#endif
211
212#ifdef FORCE_RB_SINGLE
213	boothowto |= RB_SINGLE;
214#endif
215}
216
217/*
218 * Info for CTL_HW
219 */
220extern	char version[];
221
222#define CPUDEBUG
223
224/*
225 * machine dependent system variables.
226 */
227int
228cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
229	int *name;
230	u_int namelen;
231	void *oldp;
232	size_t *oldlenp;
233	void *newp;
234	size_t newlen;
235	struct proc *p;
236{
237	dev_t consdev;
238	struct btinfo_bootpath *bibp;
239	struct trapframe *tf;
240	char *osimage;
241
242	/* all sysctl names at this level are terminal */
243	if (namelen != 1)
244		return (ENOTDIR);		/* overloaded */
245
246	switch (name[0]) {
247	case CPU_CONSDEV:
248		if (cn_tab != NULL)
249			consdev = cn_tab->cn_dev;
250		else
251			consdev = NODEV;
252		return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
253		    sizeof consdev));
254
255	case CPU_NKPDE:
256		return (sysctl_rdint(oldp, oldlenp, newp, nkpde));
257
258	case CPU_BOOTED_KERNEL:
259	        bibp = lookup_bootinfo(BTINFO_BOOTPATH);
260	        if (!bibp)
261			return (ENOENT); /* ??? */
262		return (sysctl_rdstring(oldp, oldlenp, newp, bibp->bootpath));
263
264	case CPU_SETPRIVPROC:
265		if (newp == NULL)
266			return (0);
267
268		/* set current process to priviledged process */
269		tf = p->p_md.md_regs;
270		tf->tf_ssr |= PSL_MD;
271		return (0);
272
273	case CPU_DEBUGMODE:
274		return (sysctl_int(oldp, oldlenp, newp, newlen,
275				   &cpu_debug_mode));
276
277	case CPU_LOADANDRESET:
278		if (newp != NULL) {
279			osimage = (char *)(*(u_long *)newp);
280
281			LoadAndReset(osimage);
282			/* not reach here */
283		}
284		return (0);
285
286	default:
287		return (EOPNOTSUPP);
288	}
289	/* NOTREACHED */
290}
291
292int waittime = -1;
293int cold = 1;
294struct pcb dumppcb;
295
296void
297cpu_reboot(howto, bootstr)
298	int howto;
299	char *bootstr;
300{
301
302	if (cold) {
303		howto |= RB_HALT;
304		goto haltsys;
305	}
306
307	boothowto = howto;
308	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
309		waittime = 0;
310		vfs_shutdown();
311		/*
312		 * If we've been adjusting the clock, the todr
313		 * will be out of synch; adjust it now.
314		 */
315		/* resettodr(); */
316	}
317
318	/* Disable interrupts. */
319	splhigh();
320
321	/* Do a dump if requested. */
322	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
323		dumpsys();
324
325haltsys:
326	doshutdownhooks();
327
328	if (howto & RB_HALT) {
329		printf("\n");
330		printf("The operating system has halted.\n");
331		printf("Please press any key to reboot.\n\n");
332		cngetc();
333	}
334
335	printf("rebooting...\n");
336	cpu_reset();
337	for(;;)
338		;
339	/*NOTREACHED*/
340}
341
342/*
343 * These variables are needed by /sbin/savecore
344 */
345u_long	dumpmag = 0x8fca0101;	/* magic number */
346int 	dumpsize = 0;		/* pages */
347long	dumplo = 0; 		/* blocks */
348
349/*
350 * This is called by main to set dumplo and dumpsize.
351 * Dumps always skip the first CLBYTES of disk space
352 * in case there might be a disk label stored there.
353 * If there is extra space, put dump at the end to
354 * reduce the chance that swapping trashes it.
355 */
356void
357cpu_dumpconf()
358{
359#ifdef	TODO
360	int nblks;	/* size of dump area */
361	int maj;
362
363	if (dumpdev == NODEV)
364		return;
365	maj = major(dumpdev);
366	if (maj < 0 || maj >= nblkdev)
367		panic("dumpconf: bad dumpdev=0x%x", dumpdev);
368	if (bdevsw[maj].d_psize == NULL)
369		return;
370	nblks = (*bdevsw[maj].d_psize)(dumpdev);
371	if (nblks <= ctod(1))
372		return;
373
374	dumpsize = btoc(IOM_END + ctob(dumpmem_high));
375
376	/* Always skip the first CLBYTES, in case there is a label there. */
377	if (dumplo < ctod(1))
378		dumplo = ctod(1);
379
380	/* Put dump at end of partition, and make it fit. */
381	if (dumpsize > dtoc(nblks - dumplo))
382		dumpsize = dtoc(nblks - dumplo);
383	if (dumplo < nblks - ctod(dumpsize))
384		dumplo = nblks - ctod(dumpsize);
385#endif
386}
387
388/*
389 * Doadump comes here after turning off memory management and
390 * getting on the dump stack, either when called above, or by
391 * the auto-restart code.
392 */
393#define BYTES_PER_DUMP  NBPG	/* must be a multiple of pagesize XXX small */
394static vaddr_t dumpspace;
395
396vaddr_t
397reserve_dumppages(p)
398	vaddr_t p;
399{
400
401	dumpspace = p;
402	return (p + BYTES_PER_DUMP);
403}
404
405void
406dumpsys()
407{
408#ifdef	TODO
409	unsigned bytes, i, n;
410	int maddr, psize;
411	daddr_t blkno;
412	int (*dump) __P((dev_t, daddr_t, caddr_t, size_t));
413	int error;
414
415	/* Save registers. */
416	savectx(&dumppcb);
417
418	msgbufmapped = 0;	/* don't record dump msgs in msgbuf */
419	if (dumpdev == NODEV)
420		return;
421
422	/*
423	 * For dumps during autoconfiguration,
424	 * if dump device has already configured...
425	 */
426	if (dumpsize == 0)
427		cpu_dumpconf();
428	if (dumplo < 0)
429		return;
430	printf("\ndumping to dev %x, offset %ld\n", dumpdev, dumplo);
431
432	psize = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
433	printf("dump ");
434	if (psize == -1) {
435		printf("area unavailable\n");
436		return;
437	}
438
439#if 0	/* XXX this doesn't work.  grr. */
440        /* toss any characters present prior to dump */
441	while (sget() != NULL); /*syscons and pccons differ */
442#endif
443
444	bytes = ctob(dumpmem_high) + IOM_END;
445	maddr = 0;
446	blkno = dumplo;
447	dump = bdevsw[major(dumpdev)].d_dump;
448	error = 0;
449	for (i = 0; i < bytes; i += n) {
450		/*
451		 * Avoid dumping the ISA memory hole, and areas that
452		 * BIOS claims aren't in low memory.
453		 */
454		if (i >= ctob(dumpmem_low) && i < IOM_END) {
455			n = IOM_END - i;
456			maddr += n;
457			blkno += btodb(n);
458			continue;
459		}
460
461		/* Print out how many MBs we to go. */
462		n = bytes - i;
463		if (n && (n % (1024*1024)) == 0)
464			printf("%d ", n / (1024 * 1024));
465
466		/* Limit size for next transfer. */
467		if (n > BYTES_PER_DUMP)
468			n =  BYTES_PER_DUMP;
469
470		(void) pmap_map(dumpspace, maddr, maddr + n, VM_PROT_READ);
471		error = (*dump)(dumpdev, blkno, (caddr_t)dumpspace, n);
472		if (error)
473			break;
474		maddr += n;
475		blkno += btodb(n);			/* XXX? */
476
477#if 0	/* XXX this doesn't work.  grr. */
478		/* operator aborting dump? */
479		if (sget() != NULL) {
480			error = EINTR;
481			break;
482		}
483#endif
484	}
485
486	switch (error) {
487
488	case ENXIO:
489		printf("device bad\n");
490		break;
491
492	case EFAULT:
493		printf("device not ready\n");
494		break;
495
496	case EINVAL:
497		printf("area improper\n");
498		break;
499
500	case EIO:
501		printf("i/o error\n");
502		break;
503
504	case EINTR:
505		printf("aborted from console\n");
506		break;
507
508	case 0:
509		printf("succeeded\n");
510		break;
511
512	default:
513		printf("error %d\n", error);
514		break;
515	}
516	printf("\n\n");
517	delay(5000000);		/* 5 seconds */
518#endif	/* TODO */
519}
520
521/*
522 * Initialize segments and descriptor tables
523 */
524#define VBRINIT		((char *)0x8c000000)
525#define Trap100Vec	(VBRINIT + 0x100)
526#define Trap600Vec	(VBRINIT + 0x600)
527#define TLBVECTOR	(VBRINIT + 0x400)
528#define VADDRSTART	VM_MIN_KERNEL_ADDRESS
529
530extern int nkpde;
531extern char MonTrap100[], MonTrap100_end[];
532extern char MonTrap600[], MonTrap600_end[];
533extern char _start[], etext[], edata[], end[];
534extern char tlbmisshandler_stub[], tlbmisshandler_stub_end[];
535
536void
537initSH3(pc)
538	void *pc;	/* XXX return address */
539{
540	paddr_t avail;
541	pd_entry_t *pagedir;
542	pt_entry_t *pagetab, pte;
543	u_int sp;
544	int x;
545	char *p;
546
547	avail = sh3_round_page(end);
548
549	/* XXX nkpde = kernel page dir area (IOM_RAM_SIZE*2 Mbyte (why?)) */
550	nkpde = IOM_RAM_SIZE >> (PDSHIFT - 1);
551
552	/*
553	 * clear .bss, .common area, page dir area,
554	 *	process0 stack, page table area
555	 */
556	p = (char *)avail + (1 + UPAGES) * NBPG + NBPG * (1 + nkpde); /* XXX */
557	bzero(edata, p - edata);
558
559	/*
560	 * install trap handler
561	 */
562	bcopy(MonTrap100, Trap100Vec, MonTrap100_end - MonTrap100);
563	bcopy(MonTrap600, Trap600Vec, MonTrap600_end - MonTrap600);
564	__asm ("ldc %0, vbr" :: "r"(VBRINIT));
565
566/*
567 *                          edata  end
568 *	+-------------+------+-----+----------+-------------+------------+
569 *	| kernel text | data | bss | Page Dir | Proc0 Stack | Page Table |
570 *	+-------------+------+-----+----------+-------------+------------+
571 *                                     NBPG       USPACE    (1+nkpde)*NBPG
572 *                                                (= 4*NBPG)
573 *	Build initial page tables
574 */
575	pagedir = (void *)avail;
576	pagetab = (void *)(avail + SYSMAP);
577
578	/*
579	 *	Construct a page table directory
580	 *	In SH3 H/W does not support PTD,
581	 *	these structures are used by S/W.
582	 */
583	pte = (pt_entry_t)pagetab;
584	pte |= PG_KW | PG_V | PG_4K | PG_M | PG_N;
585	pagedir[KERNTEXTOFF >> PDSHIFT] = pte;
586
587	/* make pde for 0xd0000000, 0xd0400000, 0xd0800000,0xd0c00000,
588		0xd1000000, 0xd1400000, 0xd1800000, 0xd1c00000 */
589	pte += NBPG;
590	for (x = 0; x < nkpde; x++) {
591		pagedir[(VADDRSTART >> PDSHIFT) + x] = pte;
592		pte += NBPG;
593	}
594
595	/* Install a PDE recursively mapping page directory as a page table! */
596	pte = (u_int)pagedir;
597	pte |= PG_V | PG_4K | PG_KW | PG_M | PG_N;
598	pagedir[PDSLOT_PTE] = pte;
599
600	/* set PageDirReg */
601	SHREG_TTB = (u_int)pagedir;
602
603	/* Set TLB miss handler */
604	p = tlbmisshandler_stub;
605	x = tlbmisshandler_stub_end - p;
606	bcopy(p, TLBVECTOR, x);
607
608	/*
609	 * Activate MMU
610	 */
611
612#define MMUCR_AT	0x0001	/* address traslation enable */
613#define MMUCR_IX	0x0002	/* index mode */
614#define MMUCR_TF	0x0004	/* TLB flush */
615#define MMUCR_SV	0x0100	/* single virtual space mode */
616
617	SHREG_MMUCR = MMUCR_AT | MMUCR_TF | MMUCR_SV;
618
619	/*
620	 * Now here is virtual address
621	 */
622
623	/* Set proc0paddr */
624	proc0paddr = (void *)(avail + NBPG);
625
626	/* Set pcb->PageDirReg of proc0 */
627	proc0paddr->u_pcb.pageDirReg = (int)pagedir;
628
629	/* avail_start is first available physical memory address */
630	avail_start = avail + NBPG + USPACE + NBPG + NBPG * nkpde;
631
632	/* atdevbase is first available logical memory address */
633	atdevbase = VADDRSTART;
634
635	proc0.p_addr = proc0paddr; /* page dir address */
636
637	/* XXX: PMAP_NEW requires valid curpcb.   also init'd in cpu_startup */
638	curpcb = &proc0.p_addr->u_pcb;
639
640	/*
641	 * Initialize the I/O port and I/O mem extent maps.
642	 * Note: we don't have to check the return value since
643	 * creation of a fixed extent map will never fail (since
644	 * descriptor storage has already been allocated).
645	 *
646	 * N.B. The iomem extent manages _all_ physical addresses
647	 * on the machine.  When the amount of RAM is found, the two
648	 * extents of RAM are allocated from the map (0 -> ISA hole
649	 * and end of ISA hole -> end of RAM).
650	 */
651	iomem_ex = extent_create("iomem", 0x0, 0xffffffff, M_DEVBUF,
652	    (caddr_t)iomem_ex_storage, sizeof(iomem_ex_storage),
653	    EX_NOCOALESCE|EX_NOWAIT);
654
655#if 0
656	consinit();	/* XXX SHOULD NOT BE DONE HERE */
657#endif
658
659	splraise(-1);
660	enable_intr();
661
662	avail_end = sh3_trunc_page(IOM_RAM_END + 1);
663
664	printf("initSH3\r\n");
665
666	/*
667	 * Calculate check sum
668	 */
669    {
670	u_short *p, sum;
671	int size;
672
673	size = etext - _start;
674	p = (u_short *)_start;
675	sum = 0;
676	size >>= 1;
677	while (size--)
678		sum += *p++;
679	printf("Check Sum = 0x%x\r\n", sum);
680    }
681	/*
682	 * Allocate the physical addresses used by RAM from the iomem
683	 * extent map.  This is done before the addresses are
684	 * page rounded just to make sure we get them all.
685	 */
686	if (extent_alloc_region(iomem_ex, IOM_RAM_BEGIN,
687				(IOM_RAM_END-IOM_RAM_BEGIN) + 1,
688				EX_NOWAIT)) {
689		/* XXX What should we do? */
690		printf("WARNING: CAN'T ALLOCATE RAM MEMORY FROM IOMEM EXTENT MAP!\n");
691	}
692
693	/* number of pages of physmem addr space */
694	physmem = btoc(IOM_RAM_END - IOM_RAM_BEGIN +1);
695#ifdef	TODO
696	dumpmem = physmem;
697#endif
698
699	/*
700	 * Initialize for pmap_free_pages and pmap_next_page.
701	 * These guys should be page-aligned.
702	 */
703	if (physmem < btoc(2 * 1024 * 1024)) {
704		printf("warning: too little memory available; "
705		       "have %d bytes, want %d bytes\n"
706		       "running in degraded mode\n"
707		       "press a key to confirm\n\n",
708		       ctob(physmem), 2*1024*1024);
709		cngetc();
710	}
711
712	/* Call pmap initialization to make new kernel address space */
713	pmap_bootstrap(atdevbase);
714
715	/*
716	 * Initialize error message buffer (at end of core).
717	 */
718	initmsgbuf((caddr_t)msgbuf_paddr, round_page(MSGBUFSIZE));
719
720	/*
721	 * set boot device information
722	 */
723	setup_bootinfo();
724
725#if 0
726	sh3_cache_on();
727#endif
728
729	/* setup proc0 stack */
730	sp = avail + NBPG + USPACE - 16 - sizeof(struct trapframe);
731
732	/*
733	 * XXX We can't return here, because we change stack pointer.
734	 *     So jump to return address directly.
735	 */
736	__asm __volatile ("jmp @%0; mov %1, r15" :: "r"(pc), "r"(sp));
737}
738
739void
740setup_bootinfo(void)
741{
742	struct btinfo_bootdisk *help;
743
744	*(int *)bootinfo = 1;
745	help = (struct btinfo_bootdisk *)(bootinfo + sizeof(int));
746	help->biosdev = 0;
747	help->partition = 0;
748	((struct btinfo_common *)help)->len = sizeof(struct btinfo_bootdisk);
749	((struct btinfo_common *)help)->type = BTINFO_BOOTDISK;
750}
751
752void *
753lookup_bootinfo(type)
754	int type;
755{
756	struct btinfo_common *help;
757	int n = *(int*)bootinfo;
758	help = (struct btinfo_common *)(bootinfo + sizeof(int));
759	while (n--) {
760		if (help->type == type)
761			return (help);
762		help = (struct btinfo_common *)((char*)help + help->len);
763	}
764	return (0);
765}
766
767
768/*
769 * consinit:
770 * initialize the system console.
771 * XXX - shouldn't deal with this initted thing, but then,
772 * it shouldn't be called from init386 either.
773 */
774void
775consinit()
776{
777	static int initted;
778
779	if (initted)
780		return;
781	initted = 1;
782
783	cninit();
784
785#ifdef DDB
786	ddb_init();
787#endif
788}
789
790void
791cpu_reset()
792{
793
794	disable_intr();
795
796	Sh3Reset();
797	for (;;)
798		;
799}
800
801int
802bus_space_map (t, addr, size, flags, bshp)
803	bus_space_tag_t t;
804	bus_addr_t addr;
805	bus_size_t size;
806	int flags;
807	bus_space_handle_t *bshp;
808{
809
810	*bshp = (bus_space_handle_t)addr;
811
812	return 0;
813}
814
815int
816sh_memio_subregion(t, bsh, offset, size, nbshp)
817	bus_space_tag_t t;
818	bus_space_handle_t bsh;
819	bus_size_t offset, size;
820	bus_space_handle_t *nbshp;
821{
822
823	*nbshp = bsh + offset;
824	return (0);
825}
826
827int
828sh_memio_alloc(t, rstart, rend, size, alignment, boundary, flags,
829	       bpap, bshp)
830	bus_space_tag_t t;
831	bus_addr_t rstart, rend;
832	bus_size_t size, alignment, boundary;
833	int flags;
834	bus_addr_t *bpap;
835	bus_space_handle_t *bshp;
836{
837	*bshp = *bpap = rstart;
838
839	return (0);
840}
841
842void
843sh_memio_free(t, bsh, size)
844	bus_space_tag_t t;
845	bus_space_handle_t bsh;
846	bus_size_t size;
847{
848
849}
850
851void
852sh_memio_unmap(t, bsh, size)
853	bus_space_tag_t t;
854	bus_space_handle_t bsh;
855	bus_size_t size;
856{
857	return;
858}
859
860/*
861 * InitializeBsc
862 * : BSC(Bus State Controler)
863 */
864void InitializeBsc __P((void));
865
866void
867InitializeBsc()
868{
869
870	/*
871	 * Drive RAS,CAS in stand by mode and bus release mode
872	 * Area0 = Normal memory, Area5,6=Normal(no burst)
873	 * Area2 = Normal memory, Area3 = SDRAM, Area5 = Normal memory
874	 * Area4 = Normal Memory
875	 * Area6 = Normal memory
876	 */
877	SHREG_BCR1 = BSC_BCR1_VAL;
878
879	/*
880	 * Bus Width
881	 * Area4: Bus width = 16bit
882	 * Area6,5 = 16bit
883	 * Area1 = 8bit
884	 * Area2,3: Bus width = 32bit
885	 */
886	 SHREG_BCR2 = BSC_BCR2_VAL;
887
888	/*
889	 * Idle cycle number in transition area and read to write
890	 * Area6 = 3, Area5 = 3, Area4 = 3, Area3 = 3, Area2 = 3
891	 * Area1 = 3, Area0 = 3
892	 */
893	SHREG_WCR1 = BSC_WCR1_VAL;
894
895	/*
896	 * Wait cycle
897	 * Area 6 = 6
898	 * Area 5 = 2
899	 * Area 4 = 10
900	 * Area 3 = 3
901	 * Area 2,1 = 3
902	 * Area 0 = 6
903	 */
904	SHREG_WCR2 = BSC_WCR2_VAL;
905
906#ifdef SH4
907	SHREG_WCR3 = BSC_WCR3_VAL;
908#endif
909
910	/*
911	 * RAS pre-charge = 2cycle, RAS-CAS delay = 3 cycle,
912	 * write pre-charge=1cycle
913	 * CAS before RAS refresh RAS assert time = 3 cycle
914	 * Disable burst, Bus size=32bit, Column Address=10bit, Refresh ON
915	 * CAS before RAS refresh ON, EDO DRAM
916	 */
917	SHREG_MCR = BSC_MCR_VAL;
918
919#ifdef BSC_SDMR_VAL
920#if 1
921#define SDMR	(*(volatile unsigned char  *)BSC_SDMR_VAL)
922
923	SDMR = 0;
924#else
925#define ADDSET	(*(volatile unsigned short *)0x1A000000)
926#define ADDRST	(*(volatile unsigned short *)0x18000000)
927#define SDMR	(*(volatile unsigned char  *)BSC_SDMR_VAL)
928
929	ADDSET = 0;
930	SDMR = 0;
931	ADDRST = 0;
932#endif
933#endif
934
935	/*
936	 * PCMCIA Control Register
937	 * OE/WE assert delay 3.5 cycle
938	 * OE/WE negate-address delay 3.5 cycle
939	 */
940#ifdef BSC_PCR_VAL
941	SHREG_PCR = 0x00ff;
942#endif
943
944	/*
945	 * Refresh Timer Control/Status Register
946	 * Disable interrupt by CMF, closk 1/16, Disable OVF interrupt
947	 * Count Limit = 1024
948	 * In following statement, the reason why high byte = 0xa5(a4 in RFCR)
949	 * is the rule of SH3 in writing these register.
950	 */
951	SHREG_RTCSR = BSC_RTCSR_VAL;
952
953
954	/*
955	 * Refresh Timer Counter
956	 * Initialize to 0
957	 */
958	SHREG_RTCNT = BSC_RTCNT_VAL;
959
960	/* set Refresh Time Constant Register */
961	SHREG_RTCOR = BSC_RTCOR_VAL;
962
963	/* init Refresh Count Register */
964#ifdef BSC_RFCR_VAL
965	SHREG_RFCR = BSC_RFCR_VAL;
966#endif
967
968	/* Set Clock mode (make internal clock double speed) */
969
970	SHREG_FRQCR = FRQCR_VAL;
971
972#ifndef MMEYE_NO_CACHE
973	/* Cache ON */
974	SHREG_CCR = 0x0001;
975#endif
976}
977
978void
979sh3_cache_on(void)
980{
981#ifndef MMEYE_NO_CACHE
982	/* Cache ON */
983	SHREG_CCR = 0x0001;
984	SHREG_CCR = 0x0009; /* cache clear */
985	SHREG_CCR = 0x0001; /* cache on */
986#endif
987}
988
989#include <machine/mmeye.h>
990void
991LoadAndReset(osimage)
992	char *osimage;
993{
994	void *buf_addr;
995	u_long size;
996	u_long *src;
997	u_long *dest;
998	u_long csum = 0;
999	u_long csum2 = 0;
1000	u_long size2;
1001#define OSIMAGE_BUF_ADDR 0x8c400000 /* !!!!!! This value depends on physical
1002				       available memory */
1003
1004
1005	printf("LoadAndReset: copy start\n");
1006	buf_addr = (void *)OSIMAGE_BUF_ADDR;
1007
1008	size = *(u_long *)osimage;
1009	src = (u_long *)osimage;
1010	dest = buf_addr;
1011
1012	size = (size + sizeof(u_long) * 2 + 3) >> 2;
1013	size2 = size;
1014
1015	while (size--) {
1016		csum += *src;
1017		*dest++ = *src++;
1018	}
1019
1020	dest = buf_addr;
1021	while (size2--)
1022		csum2 += *dest++;
1023
1024	printf("LoadAndReset: copy end[%lx,%lx]\n", csum, csum2);
1025	printf("start XLoadAndReset\n");
1026
1027	/* mask all externel interrupt (XXX) */
1028
1029	XLoadAndReset(buf_addr);
1030}
1031