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