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