machdep.c revision 1.39
1/*	$NetBSD: machdep.c,v 1.39 2002/03/17 17:55:23 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/kernel.h>
87#include <sys/user.h>
88#include <sys/mount.h>
89#include <sys/reboot.h>
90#include <sys/sysctl.h>
91#include <sys/msgbuf.h>
92
93#include <uvm/uvm_extern.h>
94
95#include <dev/cons.h>
96#include <machine/bus.h>
97#include <sh3/bscreg.h>
98#include <sh3/cpgreg.h>
99#include <sh3/cache_sh3.h>
100
101/* the following is used externally (sysctl_hw) */
102char machine[] = MACHINE;		/* evbsh3 */
103char machine_arch[] = MACHINE_ARCH;	/* sh3eb or sh3el */
104
105paddr_t msgbuf_paddr;
106extern paddr_t avail_start, avail_end;
107
108#define IOM_RAM_END	((paddr_t)IOM_RAM_BEGIN + IOM_RAM_SIZE - 1)
109
110void initSH3 __P((void *));
111void LoadAndReset __P((char *));
112void XLoadAndReset __P((char *));
113void consinit __P((void));
114
115extern char start[], etext[], edata[], end[];
116
117/*
118 * Machine-dependent startup code
119 *
120 * This is called from main() in kern/main.c.
121 */
122void
123cpu_startup()
124{
125
126	sh_startup();
127}
128
129/*
130 * machine dependent system variables.
131 */
132int
133cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
134	int *name;
135	u_int namelen;
136	void *oldp;
137	size_t *oldlenp;
138	void *newp;
139	size_t newlen;
140	struct proc *p;
141{
142	dev_t consdev;
143	char *osimage;
144
145	/* all sysctl names at this level are terminal */
146	if (namelen != 1)
147		return (ENOTDIR);		/* overloaded */
148
149	switch (name[0]) {
150	case CPU_CONSDEV:
151		if (cn_tab != NULL)
152			consdev = cn_tab->cn_dev;
153		else
154			consdev = NODEV;
155		return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
156		    sizeof consdev));
157
158	case CPU_LOADANDRESET:
159		if (newp != NULL) {
160			osimage = (char *)(*(u_long *)newp);
161
162			LoadAndReset(osimage);
163			/* not reach here */
164		}
165		return (0);
166
167	default:
168		return (EOPNOTSUPP);
169	}
170	/* NOTREACHED */
171}
172
173void
174cpu_reboot(howto, bootstr)
175	int howto;
176	char *bootstr;
177{
178	static int waittime = -1;
179
180	if (cold) {
181		howto |= RB_HALT;
182		goto haltsys;
183	}
184
185	boothowto = howto;
186	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
187		waittime = 0;
188		vfs_shutdown();
189		/*
190		 * If we've been adjusting the clock, the todr
191		 * will be out of synch; adjust it now.
192		 */
193		/* resettodr(); */
194	}
195
196	/* Disable interrupts. */
197	splhigh();
198
199	/* Do a dump if requested. */
200	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
201		dumpsys();
202
203haltsys:
204	doshutdownhooks();
205
206	if (howto & RB_HALT) {
207		printf("\n");
208		printf("The operating system has halted.\n");
209		printf("Please press any key to reboot.\n\n");
210		cngetc();
211	}
212
213	printf("rebooting...\n");
214	cpu_reset();
215	for(;;)
216		;
217	/*NOTREACHED*/
218}
219
220void
221initSH3(void *pc)	/* XXX return address */
222{
223	vaddr_t kernend;
224	vsize_t sz;
225
226	kernend = sh3_round_page(end);
227
228	/* Clear bss */
229	memset(edata, 0, end - edata);
230
231	/* Initilize CPU ops. */
232#if defined(SH3) && defined(SH4)
233#error "don't define both SH3 and SH4"
234#elif defined(SH3)
235	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_UNKNOWN);
236#elif defined(SH4)
237	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_UNKNOWN);
238#else
239#error "define SH3 or SH4"
240#endif
241	/* Initialize proc0 and enable MMU. */
242	sz = sh_proc0_init(kernend, IOM_RAM_BEGIN, IOM_RAM_END);
243
244	/* Number of pages of physmem addr space */
245	physmem = atop(IOM_RAM_END - IOM_RAM_BEGIN + 1);
246
247	/* avail_start is first available physical memory address */
248	avail_start = kernend + sz;
249	avail_end = IOM_RAM_END + 1;
250
251	consinit();
252
253	/* Call pmap initialization to make new kernel address space */
254	pmap_bootstrap(VM_MIN_KERNEL_ADDRESS);
255
256	/*
257	 * Initialize error message buffer (at end of core).
258	 */
259	initmsgbuf((caddr_t)msgbuf_paddr, round_page(MSGBUFSIZE));
260
261	/*
262	 * XXX We can't return here, because we change stack pointer.
263	 *     So jump to return address directly.
264	 */
265	__asm __volatile (
266		"jmp	@%0;"
267		"mov	%1, r15" :: "r"(pc), "r"(proc0.p_addr->u_pcb.pcb_sp));
268}
269
270/*
271 * consinit:
272 * initialize the system console.
273 * XXX - shouldn't deal with this initted thing, but then,
274 * it shouldn't be called from init386 either.
275 */
276void
277consinit()
278{
279	static int initted;
280
281	if (initted)
282		return;
283	initted = 1;
284
285	cninit();
286
287#ifdef DDB
288	ddb_init();
289#endif
290}
291
292int
293bus_space_map (t, addr, size, flags, bshp)
294	bus_space_tag_t t;
295	bus_addr_t addr;
296	bus_size_t size;
297	int flags;
298	bus_space_handle_t *bshp;
299{
300
301	*bshp = (bus_space_handle_t)addr;
302
303	return 0;
304}
305
306int
307sh_memio_subregion(t, bsh, offset, size, nbshp)
308	bus_space_tag_t t;
309	bus_space_handle_t bsh;
310	bus_size_t offset, size;
311	bus_space_handle_t *nbshp;
312{
313
314	*nbshp = bsh + offset;
315	return (0);
316}
317
318int
319sh_memio_alloc(t, rstart, rend, size, alignment, boundary, flags,
320	       bpap, bshp)
321	bus_space_tag_t t;
322	bus_addr_t rstart, rend;
323	bus_size_t size, alignment, boundary;
324	int flags;
325	bus_addr_t *bpap;
326	bus_space_handle_t *bshp;
327{
328	*bshp = *bpap = rstart;
329
330	return (0);
331}
332
333void
334sh_memio_free(t, bsh, size)
335	bus_space_tag_t t;
336	bus_space_handle_t bsh;
337	bus_size_t size;
338{
339
340}
341
342void
343sh_memio_unmap(t, bsh, size)
344	bus_space_tag_t t;
345	bus_space_handle_t bsh;
346	bus_size_t size;
347{
348	return;
349}
350
351#ifdef SH4_PCMCIA
352
353int
354shpcmcia_memio_map(t, bpa, size, flags, bshp)
355	bus_space_tag_t t;
356	bus_addr_t bpa;
357	bus_size_t size;
358	int flags;
359	bus_space_handle_t *bshp;
360{
361	int error;
362	struct extent *ex;
363	bus_space_tag_t pt = t & ~SH3_BUS_SPACE_PCMCIA_8BIT;
364
365	if (pt != SH3_BUS_SPACE_PCMCIA_IO &&
366	    pt != SH3_BUS_SPACE_PCMCIA_MEM &&
367	    pt != SH3_BUS_SPACE_PCMCIA_ATT) {
368		*bshp = (bus_space_handle_t)bpa;
369
370		return 0;
371	}
372
373	ex = iomem_ex;
374
375#if 0
376	/*
377	 * Before we go any further, let's make sure that this
378	 * region is available.
379	 */
380	error = extent_alloc_region(ex, bpa, size,
381				    EX_NOWAIT | EX_MALLOCOK );
382	if (error){
383		printf("sh3_pcmcia_memio_map:extent_alloc_region error\n");
384		return (error);
385	}
386#endif
387
388	/*
389	 * For memory space, map the bus physical address to
390	 * a kernel virtual address.
391	 */
392	error = shpcmcia_mem_add_mapping(bpa, size, (int)t, bshp );
393#if 0
394	if (error) {
395		if (extent_free(ex, bpa, size, EX_NOWAIT | EX_MALLOCOK )) {
396			printf("sh3_pcmcia_memio_map: pa 0x%lx, size 0x%lx\n",
397			       bpa, size);
398			printf("sh3_pcmcia_memio_map: can't free region\n");
399		}
400	}
401#endif
402
403	return (error);
404}
405
406int
407shpcmcia_mem_add_mapping(bpa, size, type, bshp)
408	bus_addr_t bpa;
409	bus_size_t size;
410	int type;
411	bus_space_handle_t *bshp;
412{
413	u_long pa, endpa;
414	vaddr_t va;
415	pt_entry_t *pte;
416	unsigned int m = 0;
417	int io_type = type & ~SH3_BUS_SPACE_PCMCIA_8BIT;
418
419	pa = sh3_trunc_page(bpa);
420	endpa = sh3_round_page(bpa + size);
421
422#ifdef DIAGNOSTIC
423	if (endpa <= pa)
424		panic("sh3_pcmcia_mem_add_mapping: overflow");
425#endif
426
427	va = uvm_km_valloc(kernel_map, endpa - pa);
428	if (va == 0){
429		printf("shpcmcia_add_mapping: nomem \n");
430		return (ENOMEM);
431	}
432
433	*bshp = (bus_space_handle_t)(va + (bpa & PGOFSET));
434
435#define MODE(t, s)							\
436	(t) & SH3_BUS_SPACE_PCMCIA_8BIT ?				\
437		_PG_PCMCIA_ ## s ## 8 :					\
438		_PG_PCMCIA_ ## s ## 16
439	switch (io_type) {
440	default:
441		panic("unknown pcmcia space.");
442		/* NOTREACHED */
443	case SH3_BUS_SPACE_PCMCIA_IO:
444		m = MODE(type, IO);
445		break;
446	case SH3_BUS_SPACE_PCMCIA_MEM:
447		m = MODE(type, MEM);
448		break;
449	case SH3_BUS_SPACE_PCMCIA_ATT:
450		m = MODE(type, ATTR);
451		break;
452	}
453#undef MODE
454
455	for (; pa < endpa; pa += NBPG, va += NBPG) {
456		pmap_enter(pmap_kernel(), va, pa,
457		    VM_PROT_READ | VM_PROT_WRITE, PMAP_WIRED);
458
459		pte = kvtopte(va);
460		*pte &= ~PG_N;
461		*pte |= m;
462		pmap_update_pg(va);
463	}
464	pmap_update(pmap_kernel());
465
466	return 0;
467}
468
469void
470shpcmcia_memio_unmap(t, bsh, size)
471	bus_space_tag_t t;
472	bus_space_handle_t bsh;
473	bus_size_t size;
474{
475	struct extent *ex;
476	u_long va, endva;
477	bus_addr_t bpa;
478	bus_space_tag_t pt = t & ~SH3_BUS_SPACE_PCMCIA_8BIT;
479
480	if (pt != SH3_BUS_SPACE_PCMCIA_IO &&
481	    pt != SH3_BUS_SPACE_PCMCIA_MEM &&
482	    pt != SH3_BUS_SPACE_PCMCIA_ATT) {
483		return ;
484	}
485
486	ex = iomem_ex;
487
488	va = sh3_trunc_page(bsh);
489	endva = sh3_round_page(bsh + size);
490
491#ifdef DIAGNOSTIC
492	if (endva <= va)
493		panic("sh3_pcmcia_memio_unmap: overflow");
494#endif
495
496	pmap_extract(pmap_kernel(), va, &bpa);
497	bpa += bsh & PGOFSET;
498
499	/*
500	 * Free the kernel virtual mapping.
501	 */
502	uvm_km_free(kernel_map, va, endva - va);
503
504#if 0
505	if (extent_free(ex, bpa, size,
506			EX_NOWAIT | EX_MALLOCOK)) {
507		printf("sh3_pcmcia_memio_unmap: %s 0x%lx, size 0x%lx\n",
508		       "pa", bpa, size);
509		printf("sh3_pcmcia_memio_unmap: can't free region\n");
510	}
511#endif
512}
513
514void
515shpcmcia_memio_free(t, bsh, size)
516	bus_space_tag_t t;
517	bus_space_handle_t bsh;
518	bus_size_t size;
519{
520
521	/* sh3_pcmcia_memio_unmap() does all that we need to do. */
522	shpcmcia_memio_unmap(t, bsh, size);
523}
524
525int
526shpcmcia_memio_subregion(t, bsh, offset, size, nbshp)
527	bus_space_tag_t t;
528	bus_space_handle_t bsh;
529	bus_size_t offset, size;
530	bus_space_handle_t *nbshp;
531{
532
533	*nbshp = bsh + offset;
534	return (0);
535}
536
537#endif /* SH4_PCMCIA */
538
539#if !defined(DONT_INIT_BSC)
540/*
541 * InitializeBsc
542 * : BSC(Bus State Controler)
543 */
544void InitializeBsc __P((void));
545
546void
547InitializeBsc()
548{
549
550	/*
551	 * Drive RAS,CAS in stand by mode and bus release mode
552	 * Area0 = Normal memory, Area5,6=Normal(no burst)
553	 * Area2 = Normal memory, Area3 = SDRAM, Area5 = Normal memory
554	 * Area4 = Normal Memory
555	 * Area6 = Normal memory
556	 */
557#if defined(SH3)
558	_reg_write_2(SH3_BCR1, BSC_BCR1_VAL);
559#elif defined(SH4)
560	_reg_write_4(SH4_BCR1, BSC_BCR1_VAL);
561#endif
562
563	/*
564	 * Bus Width
565	 * Area4: Bus width = 16bit
566	 * Area6,5 = 16bit
567	 * Area1 = 8bit
568	 * Area2,3: Bus width = 32bit
569	 */
570	_reg_write_2(SH_(BCR2), BSC_BCR2_VAL);
571
572	/*
573	 * Idle cycle number in transition area and read to write
574	 * Area6 = 3, Area5 = 3, Area4 = 3, Area3 = 3, Area2 = 3
575	 * Area1 = 3, Area0 = 3
576	 */
577#if defined(SH3)
578	_reg_write_2(SH3_WCR1, BSC_WCR1_VAL);
579#elif defined(SH4)
580	_reg_write_4(SH4_WCR1, BSC_WCR1_VAL);
581#endif
582
583	/*
584	 * Wait cycle
585	 * Area 6 = 6
586	 * Area 5 = 2
587	 * Area 4 = 10
588	 * Area 3 = 3
589	 * Area 2,1 = 3
590	 * Area 0 = 6
591	 */
592#if defined(SH3)
593	_reg_write_2(SH3_WCR2, BSC_WCR2_VAL);
594#elif defined(SH4)
595	_reg_write_4(SH4_WCR2, BSC_WCR2_VAL);
596#endif
597
598#if defined(SH4) && defined(BSC_WCR3_VAL)
599	_reg_write_4(SH4_WCR3, BSC_WCR3_VAL);
600#endif
601
602	/*
603	 * RAS pre-charge = 2cycle, RAS-CAS delay = 3 cycle,
604	 * write pre-charge=1cycle
605	 * CAS before RAS refresh RAS assert time = 3 cycle
606	 * Disable burst, Bus size=32bit, Column Address=10bit, Refresh ON
607	 * CAS before RAS refresh ON, EDO DRAM
608	 */
609#if defined(SH3)
610	_reg_write_2(SH3_MCR, BSC_MCR_VAL);
611#elif defined(SH4)
612	_reg_write_4(SH4_MCR, BSC_MCR_VAL);
613#endif
614
615#if defined(BSC_SDMR2_VAL)
616	_reg_write_1(BSC_SDMR2_VAL, 0);
617#endif
618
619#if defined(BSC_SDMR3_VAL)
620#if !(defined(COMPUTEXEVB) && defined(SH7709A))
621	_reg_write_1(BSC_SDMR3_VAL, 0);
622#else
623	_reg_write_2(0x1a000000, 0);	/* ADDSET */
624	_reg_write_1(BSC_SDMR3_VAL, 0);
625	_reg_write_2(0x18000000, 0);	/* ADDRST */
626#endif /* !(COMPUTEXEVB && SH7709A) */
627#endif /* BSC_SDMR3_VAL */
628
629	/*
630	 * PCMCIA Control Register
631	 * OE/WE assert delay 3.5 cycle
632	 * OE/WE negate-address delay 3.5 cycle
633	 */
634#ifdef BSC_PCR_VAL
635	_reg_write_2(SH_(PCR), BSC_PCR_VAL);
636#endif
637
638	/*
639	 * Refresh Timer Control/Status Register
640	 * Disable interrupt by CMF, closk 1/16, Disable OVF interrupt
641	 * Count Limit = 1024
642	 * In following statement, the reason why high byte = 0xa5(a4 in RFCR)
643	 * is the rule of SH3 in writing these register.
644	 */
645	_reg_write_2(SH_(RTCSR), BSC_RTCSR_VAL);
646
647	/*
648	 * Refresh Timer Counter
649	 * Initialize to 0
650	 */
651#ifdef BSC_RTCNT_VAL
652	_reg_write_2(SH_(RTCNT), BSC_RTCNT_VAL);
653#endif
654
655	/* set Refresh Time Constant Register */
656	_reg_write_2(SH_(RTCOR), BSC_RTCOR_VAL);
657
658	/* init Refresh Count Register */
659#ifdef BSC_RFCR_VAL
660	_reg_write_2(SH_(RFCR), BSC_RFCR_VAL);
661#endif
662
663	/*
664	 * Clock Pulse Generator
665	 */
666	/* Set Clock mode (make internal clock double speed) */
667	_reg_write_2(SH_(FRQCR), FRQCR_VAL);
668
669	/*
670	 * Cache
671	 */
672#ifndef CACHE_DISABLE
673	/* Cache ON */
674	_reg_write_4(SH_(CCR), 0x1);
675#endif
676}
677#endif /* !DONT_INIT_BSC */
678
679
680 /* XXX This value depends on physical available memory */
681#define OSIMAGE_BUF_ADDR	(IOM_RAM_BEGIN + 0x00400000)
682
683void
684LoadAndReset(osimage)
685	char *osimage;
686{
687	void *buf_addr;
688	u_long size;
689	u_long *src;
690	u_long *dest;
691	u_long csum = 0;
692	u_long csum2 = 0;
693	u_long size2;
694
695	printf("LoadAndReset: copy start\n");
696	buf_addr = (void *)OSIMAGE_BUF_ADDR;
697
698	size = *(u_long *)osimage;
699	src = (u_long *)osimage;
700	dest = buf_addr;
701
702	size = (size + sizeof(u_long) * 2 + 3) >> 2;
703	size2 = size;
704
705	while (size--) {
706		csum += *src;
707		*dest++ = *src++;
708	}
709
710	dest = buf_addr;
711	while (size2--)
712		csum2 += *dest++;
713
714	printf("LoadAndReset: copy end[%lx,%lx]\n", csum, csum2);
715	printf("start XLoadAndReset\n");
716
717	/* mask all externel interrupt (XXX) */
718
719	XLoadAndReset(buf_addr);
720}
721