xref: /netbsd/sys/arch/mmeye/mmeye/machdep.c (revision bf9ec67e)
1 /*	$NetBSD: machdep.c,v 1.28 2002/05/10 20:14:40 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_memsize.h"
80 
81 #include <sys/param.h>
82 #include <sys/systm.h>
83 #include <sys/kernel.h>
84 #include <sys/user.h>
85 #include <sys/mount.h>
86 #include <sys/reboot.h>
87 #include <sys/sysctl.h>
88 #include <sys/msgbuf.h>
89 #include <uvm/uvm_extern.h>
90 #ifdef DDB
91 #include <machine/db_machdep.h>
92 #include <ddb/db_extern.h>
93 #endif
94 
95 #include <sh3/bscreg.h>
96 #include <sh3/cpgreg.h>
97 #include <sh3/cache_sh3.h>
98 #include <sh3/exception.h>
99 
100 #include <machine/bus.h>
101 #include <machine/mmeye.h>
102 #include <machine/intr.h>
103 
104 #include <dev/cons.h>
105 
106 /* the following is used externally (sysctl_hw) */
107 char machine[] = MACHINE;		/* mmeye */
108 char machine_arch[] = MACHINE_ARCH;	/* sh3eb */
109 
110 void initSH3 __P((void *));
111 void LoadAndReset __P((char *));
112 void XLoadAndReset __P((char *));
113 void consinit __P((void));
114 void sh3_cache_on __P((void));
115 void InitializeBsc(void);
116 
117 struct mmeye_intrhand {
118 	void *intc_ih;
119 	int irq;
120 } mmeye_intrhand[_INTR_N];
121 
122 /*
123  * Machine-dependent startup code
124  *
125  * This is called from main() in kern/main.c.
126  */
127 void
128 cpu_startup()
129 {
130 
131 	sh_startup();
132 }
133 
134 /*
135  * machine dependent system variables.
136  */
137 int
138 cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
139 	int *name;
140 	u_int namelen;
141 	void *oldp;
142 	size_t *oldlenp;
143 	void *newp;
144 	size_t newlen;
145 	struct proc *p;
146 {
147 	dev_t consdev;
148 	char *osimage;
149 
150 	/* all sysctl names at this level are terminal */
151 	if (namelen != 1)
152 		return (ENOTDIR);		/* overloaded */
153 
154 	switch (name[0]) {
155 	case CPU_CONSDEV:
156 		if (cn_tab != NULL)
157 			consdev = cn_tab->cn_dev;
158 		else
159 			consdev = NODEV;
160 		return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
161 		    sizeof consdev));
162 
163 	case CPU_LOADANDRESET:
164 		if (newp != NULL) {
165 			osimage = (char *)(*(u_long *)newp);
166 
167 			LoadAndReset(osimage);
168 			/* not reach here */
169 		}
170 		return (0);
171 
172 	default:
173 		return (EOPNOTSUPP);
174 	}
175 	/* NOTREACHED */
176 }
177 
178 int waittime = -1;
179 
180 void
181 cpu_reboot(howto, bootstr)
182 	int howto;
183 	char *bootstr;
184 {
185 	if (cold) {
186 		howto |= RB_HALT;
187 		goto haltsys;
188 	}
189 
190 	boothowto = howto;
191 	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
192 		waittime = 0;
193 		vfs_shutdown();
194 		/*
195 		 * If we've been adjusting the clock, the todr
196 		 * will be out of synch; adjust it now.
197 		 */
198 		/* resettodr(); */
199 	}
200 
201 	/* Disable interrupts. */
202 	splhigh();
203 
204 	/* Do a dump if requested. */
205 	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
206 		dumpsys();
207 
208 haltsys:
209 	doshutdownhooks();
210 
211 	if (howto & RB_HALT) {
212 		printf("\n");
213 		printf("The operating system has halted.\n");
214 		printf("Please press any key to reboot.\n\n");
215 		cngetc();
216 	}
217 
218 	printf("rebooting...\n");
219 	cpu_reset();
220 	for(;;) ;
221 	/*NOTREACHED*/
222 }
223 
224 void
225 initSH3(void *pc)	/* XXX return address */
226 {
227 	extern char edata[], end[];
228 	vaddr_t kernend;
229 
230 	/* Clear bss */
231 	memset(edata, 0, end - edata);
232 
233 	/* Initilize CPU ops. */
234 #if defined(SH7708R)
235 	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708R);
236 #elif defined(SH7708)
237 	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708);
238 #else
239 #warning "unknown product"
240 #endif
241 	consinit();
242 
243 	kernend = atop(round_page(SH3_P1SEG_TO_PHYS(end)));
244 #ifdef DDB
245 	/* XXX Currently symbol table size is not passed to the kernel. */
246 	kernend += 0x40000;					/* XXX */
247 #endif
248 
249 	/* Load memory to UVM */
250 	physmem = atop(IOM_RAM_SIZE);
251 	uvm_page_physload(
252 		kernend, atop(IOM_RAM_BEGIN + IOM_RAM_SIZE),
253 		kernend, atop(IOM_RAM_BEGIN + IOM_RAM_SIZE),
254 		VM_FREELIST_DEFAULT);
255 
256 	/* Initialize proc0 u-area */
257 	sh_proc0_init();
258 
259 	/* Initialize pmap and start to address translation */
260 	pmap_bootstrap();
261 
262 #ifdef DDB
263 	ddb_init(1, end, end + 0x40000);			/* XXX */
264 #endif
265 	/*
266 	 * XXX We can't return here, because we change stack pointer.
267 	 *     So jump to return address directly.
268 	 */
269 	__asm __volatile (
270 		"jmp	@%0;"
271 		"mov	%1, r15"
272 		:: "r"(pc),"r"(proc0.p_md.md_pcb->pcb_sf.sf_r7_bank));
273 }
274 
275 /*
276  * consinit:
277  * initialize the system console.
278  */
279 void
280 consinit()
281 {
282 	static int initted;
283 
284 	if (initted)
285 		return;
286 	initted = 1;
287 
288 	cninit();
289 }
290 
291 /*
292  * InitializeBsc
293  * : BSC(Bus State Controler)
294  */
295 void
296 InitializeBsc()
297 {
298 #ifdef NOPCMCIA
299 	/*
300 	 * Drive RAS,CAS in stand by mode and bus release mode
301 	 * Area0 = Normal memory, Area5,6=Normal(no burst)
302 	 * Area2 = Normal memory, Area3 = DRAM, Area5 = Normal memory
303 	 * Area4 = Normal Memory
304 	 * Area6 = Normal memory
305 	 */
306 	_reg_write_2(SH3_BCR1, 0x1010);
307 #else /* NOPCMCIA */
308 	/*
309 	 * Drive RAS,CAS in stand by mode and bus release mode
310 	 * Area0 = Normal memory, Area5,6=Normal(no burst)
311 	 * Area2 = Normal memory, Area3 = DRAM, Area5 = PCMCIA
312 	 * Area4 = Normal Memory
313 	 * Area6 = PCMCIA
314 	 */
315 	_reg_write_2(SH3_BCR1, 0x1013);
316 #endif /* NOPCMCIA */
317 
318 #define PCMCIA_16
319 #ifdef PCMCIA_16
320 	/*
321 	 * Bus Width
322 	 * Area4: Bus width = 16bit
323 	 * Area6,5 = 16bit
324 	 * Area1 = 8bit
325 	 * Area2,3: Bus width = 32bit
326 	 */
327 	_reg_write_2(SH3_BCR2, 0x2af4);
328 #else /* PCMCIA16 */
329 	/*
330 	 * Bus Width
331 	 * Area4: Bus width = 16bit
332 	 * Area6,5 = 8bit
333 	 * Area1 = 8bit
334 	 * Area2,3: Bus width = 32bit
335 	 */
336 	_reg_write_2(SH3_BCR2, 0x16f4);
337 #endif /* PCMCIA16 */
338 	/*
339 	 * Idle cycle number in transition area and read to write
340 	 * Area6 = 3, Area5 = 3, Area4 = 3, Area3 = 3, Area2 = 3
341 	 * Area1 = 3, Area0 = 3
342 	 */
343 	_reg_write_2(SH3_WCR1, 0x3fff);
344 
345 #if 0
346 	/*
347 	 * Wait cycle
348 	 * Area 6,5 = 2
349 	 * Area 4 = 10
350 	 * Area 3 = 2
351 	 * Area 2,1 = 3
352 	 * Area 0 = 6
353 	 */
354 	_reg_write_2(SH3_WCR2, 0x4bdd);
355 #else
356 	/*
357 	 * Wait cycle
358 	 * Area 6 = 6
359 	 * Area 5 = 2
360 	 * Area 4 = 10
361 	 * Area 3 = 3
362 	 * Area 2,1 = 3
363 	 * Area 0 = 6
364 	 */
365 	_reg_write_2(SH3_WCR2, 0xabfd);
366 #endif
367 
368 	/*
369 	 * RAS pre-charge = 2cycle, RAS-CAS delay = 3 cycle,
370 	 * write pre-charge = 1cycle
371 	 * CAS before RAS refresh RAS assert time = 3  cycle
372 	 * Disable burst, Bus size=32bit, Column Address=10bit,Refresh ON
373 	 * CAS before RAS refresh ON, EDO DRAM
374 	 */
375 	_reg_write_2(SH3_MCR, 0x6135);
376 	/* SHREG_MCR = 0x4135; */
377 
378 	/* DRAM Control Register */
379 	_reg_write_2(SH3_DCR, 0x0000);
380 
381 	/*
382 	 * PCMCIA Control Register
383 	 * OE/WE assert delay 3.5 cycle
384 	 * OE/WE negate-address delay 3.5 cycle
385 	 */
386 	_reg_write_2(SH3_PCR, 0x00ff);
387 
388 	/*
389 	 * Refresh Timer Control/Status Register
390 	 * Disable interrupt by CMF, closk 1/16, Disable OVF interrupt
391 	 * Count Limit = 1024
392 	 * In following statement, the reason why high byte = 0xa5(a4 in RFCR)
393 	 * is the rule of SH3 in writing these register .
394 	 */
395 	_reg_write_2(SH3_RTCSR, 0xa594);
396 
397 	/*
398 	 * Refresh Timer Counter
399 	 * initialize to 0
400 	 */
401 	_reg_write_2(SH3_RTCNT, 0xa500);
402 
403 	/*
404 	 * set Refresh Time Constant Register
405 	 */
406 	_reg_write_2(SH3_RTCOR, 0xa50d);
407 
408 	/*
409 	 * init Refresh Count Register
410 	 */
411 	_reg_write_2(SH3_RFCR, 0xa400);
412 
413 	/*
414 	 * Set Clock mode (make internal clock double speed)
415 	 */
416 #ifdef SH7708R
417 	_reg_write_2(SH3_FRQCR, 0xa100); /* 100MHz */
418 #else
419 	_reg_write_2(SH3_FRQCR, 0x0112); /* 60MHz */
420 #endif
421 
422 #ifndef MMEYE_NO_CACHE
423 	/* Cache ON */
424 	_reg_write_4(SH3_CCR, SH3_CCR_CE);
425 #endif
426 }
427 
428 void
429 sh3_cache_on(void)
430 {
431 #ifndef MMEYE_NO_CACHE
432 	/* Cache ON */
433 	_reg_write_4(SH3_CCR, SH3_CCR_CE);
434 	_reg_write_4(SH3_CCR, SH3_CCR_CF | SH3_CCR_CE);	/* cache clear */
435 	_reg_write_4(SH3_CCR, SH3_CCR_CE);
436 #endif
437 }
438 
439  /* XXX This value depends on physical available memory */
440 #define OSIMAGE_BUF_ADDR	(IOM_RAM_BEGIN + 0x00400000)
441 
442 void
443 LoadAndReset(osimage)
444 	char *osimage;
445 {
446 	void *buf_addr;
447 	u_long size;
448 	u_long *src;
449 	u_long *dest;
450 	u_long csum = 0;
451 	u_long csum2 = 0;
452 	u_long size2;
453 
454 	MMTA_IMASK = 0; /* mask all externel interrupt */
455 
456 	printf("LoadAndReset: copy start\n");
457 	buf_addr = (void *)OSIMAGE_BUF_ADDR;
458 
459 	size = *(u_long *)osimage;
460 	src = (u_long *)osimage;
461 	dest = buf_addr;
462 
463 	size = (size + sizeof(u_long) * 2 + 3) >> 2;
464 	size2 = size;
465 
466 	while (size--) {
467 		csum += *src;
468 		*dest++ = *src++;
469 	}
470 
471 	dest = buf_addr;
472 	while (size2--)
473 		csum2 += *dest++;
474 
475 	printf("LoadAndReset: copy end[%lx,%lx]\n", csum, csum2);
476 	printf("start XLoadAndReset\n");
477 
478 	XLoadAndReset(buf_addr);
479 }
480 
481 #ifdef sh3_tmp
482 
483 #define	UART_BASE	0xa4000008
484 
485 #define	IER	1
486 #define	IER_RBF	0x01
487 #define	IER_TBE	0x02
488 #define	IER_MSI	0x08
489 #define	FCR	2
490 #define	LCR	3
491 #define	LCR_DLAB	0x80
492 #define	DLM	1
493 #define	DLL	0
494 #define	MCR	4
495 #define	MCR_RTS	0x02
496 #define	MCR_DTR	0x01
497 #define	MCR_OUT2	0x08
498 #define	RTS_MODE	(MCR_RTS|MCR_DTR)
499 #define	LSR	5
500 #define	LSR_THRE	0x20
501 #define	LSR_ERROR	0x1e
502 #define	THR	0
503 #define	IIR	2
504 #define	IIR_II	0x06
505 #define	IIR_LSI	0x06
506 #define	IIR_MSI	0x00
507 #define	IIR_TBE	0x02
508 #define	IIR_PEND	0x01
509 #define	RBR	0
510 #define	MSR	6
511 
512 #define	OUTP(port, val)	*(volatile unsigned char *)(UART_BASE+port) = val
513 #define	INP(port)	(*(volatile unsigned char *)(UART_BASE+port))
514 
515 void
516 Init16550()
517 {
518 	int diviser;
519 	int tmp;
520 
521 	/* Set speed */
522 	/* diviser = 12; */	/* 9600 bps */
523 	diviser = 6;	/* 19200 bps */
524 
525 	OUTP(IER, 0);
526 	/* OUTP(FCR, 0x87); */	/* FIFO mode */
527 	OUTP(FCR, 0x00);	/* no FIFO mode */
528 
529 	tmp = INP(LSR);
530 	tmp = INP(MSR);
531 	tmp = INP(IIR);
532 	tmp = INP(RBR);
533 
534 	OUTP(LCR, INP(LCR) | LCR_DLAB);
535 	OUTP(DLM, 0xff & (diviser>>8));
536 	OUTP(DLL, 0xff & diviser);
537 	OUTP(LCR, INP(LCR) & ~LCR_DLAB);
538 	OUTP(MCR, 0);
539 
540 	OUTP(LCR, 0x03);	/* 8 bit , no parity, 1 stop */
541 
542 	/* start comm */
543 	OUTP(MCR, RTS_MODE | MCR_OUT2);
544 	/* OUTP(IER, IER_RBF | IER_TBE | IER_MSI); */
545 }
546 
547 void
548 Send16550(int c)
549 {
550 	while (1) {
551 		OUTP(THR, c);
552 
553 		while ((INP(LSR) & LSR_THRE) == 0)
554 			;
555 
556 		if (c == '\n')
557 			c = '\r';
558 		else
559 			return;
560 	}
561 }
562 #endif /* sh3_tmp */
563 
564 
565 void
566 intc_intr(int ssr, int spc, int ssp)
567 {
568 	struct intc_intrhand *ih;
569 	int s, evtcode;
570 
571 	evtcode = _reg_read_4(SH3_INTEVT);
572 
573 	ih = EVTCODE_IH(evtcode);
574 	KDASSERT(ih->ih_func);
575 	/*
576 	 * On entry, all interrrupts are disabled,
577 	 * and exception is enabled for P3 access. (kernel stack is P3,
578 	 * SH3 may or may not cause TLB miss when access stack.)
579 	 * Enable higher level interrupt here.
580 	 */
581 	s = _cpu_intr_resume(ih->ih_level);
582 
583 	if (evtcode == SH_INTEVT_TMU0_TUNI0) {	/* hardclock */
584 		struct clockframe cf;
585 		cf.spc = spc;
586 		cf.ssr = ssr;
587 		cf.ssp = ssp;
588 		(*ih->ih_func)(&cf);
589 	} else {
590 		(*ih->ih_func)(ih->ih_arg);
591 	}
592 }
593 
594 void *
595 mmeye_intr_establish(int irq, int trigger, int level, int (*func)(void *),
596     void *arg)
597 {
598 	struct mmeye_intrhand *mh = &mmeye_intrhand[irq];
599 
600 	mh->intc_ih = intc_intr_establish(0x200 + (irq << 5), IST_LEVEL, level,
601 	    func, arg);
602 	mh->irq = irq;
603 
604 	MMTA_IMASK |= (1 << (15 - irq));
605 
606 	return ((void *)irq);
607 }
608 
609 void
610 mmeye_intr_disestablish(void *ih)
611 {
612 	struct mmeye_intrhand *mh = ih;
613 
614 	MMTA_IMASK &= ~(1 << (15 - mh->irq));
615 
616 	intc_intr_disestablish(mh->intc_ih);
617 }
618 
619 int
620 bus_space_map(t, addr, size, flags, bshp)
621 	bus_space_tag_t t;
622 	bus_addr_t addr;
623 	bus_size_t size;
624 	int flags;
625 	bus_space_handle_t *bshp;
626 {
627 	*bshp = (bus_space_handle_t)addr;
628 
629 	return 0;
630 }
631 
632 int
633 sh_memio_subregion(t, bsh, offset, size, nbshp)
634 	bus_space_tag_t t;
635 	bus_space_handle_t bsh;
636 	bus_size_t offset, size;
637 	bus_space_handle_t *nbshp;
638 {
639 
640 	*nbshp = bsh + offset;
641 	return (0);
642 }
643