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