xref: /netbsd-src/sys/arch/mmeye/mmeye/machdep.c (revision 6e3d02bbcd6ad76dfee4cfb9687a4fd87c0e86d6)
1 /*	$NetBSD: machdep.c,v 1.58 2024/02/05 22:08:05 andvar 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  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*-
34  * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
35  * All rights reserved.
36  *
37  * This code is derived from software contributed to Berkeley by
38  * William Jolitz.
39  *
40  * Redistribution and use in source and binary forms, with or without
41  * modification, are permitted provided that the following conditions
42  * are met:
43  * 1. Redistributions of source code must retain the above copyright
44  *    notice, this list of conditions and the following disclaimer.
45  * 2. Redistributions in binary form must reproduce the above copyright
46  *    notice, this list of conditions and the following disclaimer in the
47  *    documentation and/or other materials provided with the distribution.
48  * 3. Neither the name of the University nor the names of its contributors
49  *    may be used to endorse or promote products derived from this software
50  *    without specific prior written permission.
51  *
52  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62  * SUCH DAMAGE.
63  *
64  *	@(#)machdep.c	7.4 (Berkeley) 6/3/91
65  */
66 
67 #include <sys/cdefs.h>
68 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.58 2024/02/05 22:08:05 andvar Exp $");
69 
70 #include "opt_ddb.h"
71 #include "opt_memsize.h"
72 #include "opt_modular.h"
73 
74 #include <sys/param.h>
75 #include <sys/bus.h>
76 #include <sys/callout.h>
77 #include <sys/device.h>
78 #include <sys/kernel.h>
79 #include <sys/ksyms.h>
80 #include <sys/module.h>
81 #include <sys/mount.h>
82 #include <sys/msgbuf.h>
83 #include <sys/reboot.h>
84 #include <sys/sysctl.h>
85 #include <sys/systm.h>
86 
87 #include <uvm/uvm_extern.h>
88 
89 #include <sh3/bscreg.h>
90 #include <sh3/cpgreg.h>
91 #include <sh3/cache_sh3.h>
92 #include <sh3/exception.h>
93 #include <sh3/mmu.h>
94 
95 #include <machine/bootinfo.h>
96 #include <machine/mmeye.h>
97 #include <machine/intr.h>
98 #include <machine/pcb.h>
99 
100 #include <dev/cons.h>
101 
102 #include "ksyms.h"
103 
104 #if NKSYMS || defined(MODULAR) || defined(DDB)
105 #include <machine/db_machdep.h>
106 #include <ddb/db_extern.h>
107 #include <sys/exec_elf.h>
108 #endif
109 
110 /* the following is used externally (sysctl_hw) */
111 char machine[] = MACHINE;		/* mmeye */
112 char machine_arch[] = MACHINE_ARCH;	/* sh3eb */
113 
114 char bootinfo[BOOTINFO_SIZE];
115 
116 void initSH3(void *, u_int, int32_t);
117 void LoadAndReset(const char *);
118 void XLoadAndReset(char *);
119 void consinit(void);
120 void sh3_cache_on(void);
121 void InitializeBsc(void);
122 void *lookup_bootinfo(unsigned int);
123 
124 struct mmeye_intrhand {
125 	void *intc_ih;
126 	int irq;
127 } mmeye_intrhand[_INTR_N];
128 
129 /*
130  * Machine-dependent startup code
131  *
132  * This is called from main() in kern/main.c.
133  */
134 void
cpu_startup(void)135 cpu_startup(void)
136 {
137 
138 	sh_startup();
139 }
140 
141 /*
142  * machine dependent system variables.
143  */
144 static int
sysctl_machdep_loadandreset(SYSCTLFN_ARGS)145 sysctl_machdep_loadandreset(SYSCTLFN_ARGS)
146 {
147 	const char *osimage;
148 	int error;
149 
150 	error = sysctl_lookup(SYSCTLFN_CALL(__UNCONST(rnode)));
151 	if (error || newp == NULL)
152 		return (error);
153 
154 	osimage = (const char *)(*(const u_long *)newp);
155 	LoadAndReset(osimage);
156 	/* not reach here */
157 	return (0);
158 }
159 
160 SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
161 {
162 
163 	sysctl_createv(clog, 0, NULL, NULL,
164 		       CTLFLAG_PERMANENT,
165 		       CTLTYPE_NODE, "machdep", NULL,
166 		       NULL, 0, NULL, 0,
167 		       CTL_MACHDEP, CTL_EOL);
168 
169 	sysctl_createv(clog, 0, NULL, NULL,
170 		       CTLFLAG_PERMANENT,
171 		       CTLTYPE_STRUCT, "console_device", NULL,
172 		       sysctl_consdev, 0, NULL, sizeof(dev_t),
173 		       CTL_MACHDEP, CPU_CONSDEV, CTL_EOL);
174 /*
175 <atatat> okay...your turn to play.
176 <atatat> pick a number.
177 <kjk> 98752.
178 */
179 	sysctl_createv(clog, 0, NULL, NULL,
180 		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
181 		       CTLTYPE_INT, "load_and_reset", NULL,
182 		       sysctl_machdep_loadandreset, 98752, NULL, 0,
183 		       CTL_MACHDEP, CPU_LOADANDRESET, CTL_EOL);
184 }
185 
186 int waittime = -1;
187 
188 void
cpu_reboot(int howto,char * bootstr)189 cpu_reboot(int howto, char *bootstr)
190 {
191 
192 #if defined(MMEYE_EPC_WDT)
193 	epc_watchdog_timer_reset(NULL);
194 #endif
195 
196 	if (cold) {
197 		howto |= RB_HALT;
198 		goto haltsys;
199 	}
200 
201 	boothowto = howto;
202 	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
203 		waittime = 0;
204 		vfs_shutdown();
205 		/*
206 		 * If we've been adjusting the clock, the todr
207 		 * will be out of synch; adjust it now.
208 		 */
209 		/* resettodr(); */
210 	}
211 
212 	/* Disable interrupts. */
213 	splhigh();
214 
215 	/* Do a dump if requested. */
216 	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
217 		dumpsys();
218 
219 haltsys:
220 	doshutdownhooks();
221 
222 	pmf_system_shutdown(boothowto);
223 
224 	if (howto & RB_HALT) {
225 		printf("\n");
226 		printf("The operating system has halted.\n");
227 		printf("Please press any key to reboot.\n\n");
228 		cngetc();
229 	}
230 
231 	printf("rebooting...\n");
232 #if !defined(MMEYE_EPC_WDT)
233 	cpu_reset();
234 #endif
235 	for(;;) ;
236 	/*NOTREACHED*/
237 }
238 
239 void
initSH3(void * pc,u_int bim,int32_t bip)240 initSH3(void *pc, u_int bim, int32_t bip)	/* XXX return address */
241 {
242 	extern char edata[], end[];
243 	struct btinfo_howto *bi_howto;
244 	size_t symbolsize;
245 	vaddr_t kernend;
246 	const char *bi_msg;
247 
248 	/* Clear bss */
249 	memset(edata, 0, end - edata);
250 
251 	/* Check for valid bootinfo passed from bootstrap */
252 	if (bim == BOOTINFO_MAGIC) {
253 		struct btinfo_magic *bi_magic;
254 
255 		memcpy(bootinfo, (void *)bip, BOOTINFO_SIZE);
256 		bi_magic = lookup_bootinfo(BTINFO_MAGIC);
257 		if (bi_magic == NULL) {
258 			bi_msg = "missing bootinfo structure";
259 			bim = (uintptr_t)bip;
260 		} else if (bi_magic->magic != BOOTINFO_MAGIC) {
261 			bi_msg = "invalid bootinfo structure";
262 			bim = bi_magic->magic;
263 		} else
264 			bi_msg = NULL;
265 	} else {
266 		bi_msg = "invalid bootinfo (standalone boot?)";
267 	}
268 
269 	symbolsize = 0;
270 #if NKSYMS || defined(MODULAR) || defined(DDB)
271 	if (memcmp(&end, ELFMAG, SELFMAG) == 0) {
272 		Elf_Ehdr *eh = (void *)end;
273 		Elf_Shdr *sh = (void *)(end + eh->e_shoff);
274 		int i;
275 		for (i = 0; i < eh->e_shnum; i++, sh++)
276 			if (sh->sh_offset > 0 &&
277 			    (sh->sh_offset + sh->sh_size) > symbolsize)
278 				symbolsize = sh->sh_offset + sh->sh_size;
279 	}
280 #endif
281 
282 	/* Start to determine heap area */
283 	kernend = (vaddr_t)sh3_round_page(end + symbolsize);
284 
285 	/* Initilize CPU ops. */
286 #if defined(SH7708R)
287 	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708R);
288 #elif defined(SH7708)
289 	sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708);
290 #elif defined(SH7750R)
291 	sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7750R);
292 #else
293 #warning "unknown product"
294 #endif
295 	consinit();
296 
297 	if (bi_msg != NULL)
298 		printf("%s: magic=%#x\n", bi_msg, bim);
299 
300 	bi_howto = lookup_bootinfo(BTINFO_HOWTO);
301 	if (bi_howto != NULL)
302 		boothowto = bi_howto->bi_howto;
303 
304 	/* Load memory to UVM */
305 	physmem = atop(IOM_RAM_SIZE);
306 	kernend = atop(round_page(SH3_P1SEG_TO_PHYS(kernend)));
307 	uvm_page_physload(
308 		kernend, atop(IOM_RAM_BEGIN + IOM_RAM_SIZE),
309 		kernend, atop(IOM_RAM_BEGIN + IOM_RAM_SIZE),
310 		VM_FREELIST_DEFAULT);
311 
312 	/* Initialize proc0 u-area */
313 	sh_proc0_init();
314 
315 	/* Initialize pmap and start to address translation */
316 	pmap_bootstrap();
317 
318 #if NKSYMS || defined(DDB) || defined(MODULAR)
319 	if (symbolsize)
320 		ksyms_addsyms_elf(symbolsize, &end, end + symbolsize);
321 #endif
322 #if defined(DDB)
323 	if (boothowto & RB_KDB)
324 		Debugger();
325 #endif
326 
327 	/*
328 	 * XXX We can't return here, because we change stack pointer.
329 	 *     So jump to return address directly.
330 	 */
331 	__asm volatile (
332 		"jmp	@%0;"
333 		"mov	%1, r15"
334 		:: "r"(pc),"r"(lwp0.l_md.md_pcb->pcb_sf.sf_r7_bank));
335 }
336 
337 /*
338  * consinit:
339  * initialize the system console.
340  */
341 void
consinit(void)342 consinit(void)
343 {
344 	static int initted;
345 
346 	if (initted)
347 		return;
348 	initted = 1;
349 
350 	cninit();
351 }
352 
353 /*
354  * InitializeBsc
355  * : BSC(Bus State Controller)
356  */
357 void
InitializeBsc(void)358 InitializeBsc(void)
359 {
360 #ifdef SH3
361 #ifdef NOPCMCIA
362 	/*
363 	 * Drive RAS,CAS in stand by mode and bus release mode
364 	 * Area0 = Normal memory, Area5,6=Normal(no burst)
365 	 * Area2 = Normal memory, Area3 = DRAM, Area5 = Normal memory
366 	 * Area4 = Normal Memory
367 	 * Area6 = Normal memory
368 	 */
369 	_reg_write_2(SH3_BCR1, 0x1010);
370 #else /* NOPCMCIA */
371 	/*
372 	 * Drive RAS,CAS in stand by mode and bus release mode
373 	 * Area0 = Normal memory, Area5,6=Normal(no burst)
374 	 * Area2 = Normal memory, Area3 = DRAM, Area5 = PCMCIA
375 	 * Area4 = Normal Memory
376 	 * Area6 = PCMCIA
377 	 */
378 	_reg_write_2(SH3_BCR1, 0x1013);
379 #endif /* NOPCMCIA */
380 
381 #define PCMCIA_16
382 #ifdef PCMCIA_16
383 	/*
384 	 * Bus Width
385 	 * Area4: Bus width = 16bit
386 	 * Area6,5 = 16bit
387 	 * Area1 = 8bit
388 	 * Area2,3: Bus width = 32bit
389 	 */
390 	_reg_write_2(SH3_BCR2, 0x2af4);
391 #else /* PCMCIA16 */
392 	/*
393 	 * Bus Width
394 	 * Area4: Bus width = 16bit
395 	 * Area6,5 = 8bit
396 	 * Area1 = 8bit
397 	 * Area2,3: Bus width = 32bit
398 	 */
399 	_reg_write_2(SH3_BCR2, 0x16f4);
400 #endif /* PCMCIA16 */
401 	/*
402 	 * Idle cycle number in transition area and read to write
403 	 * Area6 = 3, Area5 = 3, Area4 = 3, Area3 = 3, Area2 = 3
404 	 * Area1 = 3, Area0 = 3
405 	 */
406 	_reg_write_2(SH3_WCR1, 0x3fff);
407 
408 #if 0
409 	/*
410 	 * Wait cycle
411 	 * Area 6,5 = 2
412 	 * Area 4 = 10
413 	 * Area 3 = 2
414 	 * Area 2,1 = 3
415 	 * Area 0 = 6
416 	 */
417 	_reg_write_2(SH3_WCR2, 0x4bdd);
418 #else
419 	/*
420 	 * Wait cycle
421 	 * Area 6 = 6
422 	 * Area 5 = 2
423 	 * Area 4 = 10
424 	 * Area 3 = 3
425 	 * Area 2,1 = 3
426 	 * Area 0 = 6
427 	 */
428 	_reg_write_2(SH3_WCR2, 0xabfd);
429 #endif
430 
431 	/*
432 	 * RAS pre-charge = 2cycle, RAS-CAS delay = 3 cycle,
433 	 * write pre-charge = 1cycle
434 	 * CAS before RAS refresh RAS assert time = 3  cycle
435 	 * Disable burst, Bus size=32bit, Column Address=10bit,Refresh ON
436 	 * CAS before RAS refresh ON, EDO DRAM
437 	 */
438 	_reg_write_2(SH3_MCR, 0x6135);
439 	/* SHREG_MCR = 0x4135; */
440 
441 	/* DRAM Control Register */
442 	_reg_write_2(SH3_DCR, 0x0000);
443 
444 	/*
445 	 * PCMCIA Control Register
446 	 * OE/WE assert delay 3.5 cycle
447 	 * OE/WE negate-address delay 3.5 cycle
448 	 */
449 	_reg_write_2(SH3_PCR, 0x00ff);
450 #endif
451 #ifdef SH4
452 	/*
453 	 * mmEye-WLF sets these values to registers.
454 	 * Its values takes from that original kernel.
455 	 */
456 	_reg_write_4(SH4_BCR1, 0x0008000d);
457 	_reg_write_2(SH4_BCR2, 0x6af9);
458 	_reg_write_4(SH4_WCR1, 0x11111111);
459 	_reg_write_4(SH4_WCR2, 0xdd7845a7);
460 	_reg_write_4(SH4_WCR3, 0x05555555);
461 	_reg_write_4(SH4_MCR, 0x500921f4);
462 	_reg_write_2(SH4_PCR, 0x4b2d);
463 #endif
464 
465 	/*
466 	 * Refresh Timer Control/Status Register
467 	 * Disable interrupt by CMF, closk 1/16, Disable OVF interrupt
468 	 * Count Limit = 1024
469 	 * In following statement, the reason why high byte = 0xa5(a4 in RFCR)
470 	 * is the rule of SH3 in writing these register .
471 	 */
472 	_reg_write_2(SH_(RTCSR), 0xa594);
473 
474 	/*
475 	 * Refresh Timer Counter
476 	 * initialize to 0
477 	 */
478 	_reg_write_2(SH_(RTCNT), 0xa500);
479 
480 	/*
481 	 * set Refresh Time Constant Register
482 	 */
483 #ifdef SH3
484 	_reg_write_2(SH3_RTCOR, 0xa50d);
485 #elif SH4
486 	_reg_write_2(SH4_RTCOR, 0xa575);
487 #endif
488 
489 	/*
490 	 * init Refresh Count Register
491 	 */
492 	_reg_write_2(SH_(RFCR), 0xa400);
493 
494 	/*
495 	 * Set Clock mode (make internal clock double speed)
496 	 */
497 #if defined(SH7708R)
498 	_reg_write_2(SH3_FRQCR, 0xa100); /* 100MHz */
499 #elif defined(SH7708)
500 	_reg_write_2(SH3_FRQCR, 0x0112); /* 60MHz */
501 #elif defined(SH7750R)
502 	_reg_write_2(SH4_FRQCR, 0x0e0a);
503 #endif
504 
505 #ifndef MMEYE_NO_CACHE
506 	/* Cache ON */
507 	_reg_write_4(SH3_CCR, SH3_CCR_CE);
508 #endif
509 }
510 
511 void
sh3_cache_on(void)512 sh3_cache_on(void)
513 {
514 #ifndef MMEYE_NO_CACHE
515 	/* Cache ON */
516 	_reg_write_4(SH3_CCR, SH3_CCR_CE);
517 	_reg_write_4(SH3_CCR, SH3_CCR_CF | SH3_CCR_CE);	/* cache clear */
518 	_reg_write_4(SH3_CCR, SH3_CCR_CE);
519 #endif
520 }
521 
522  /* XXX This value depends on physical available memory */
523 #define OSIMAGE_BUF_ADDR	(IOM_RAM_BEGIN + 0x00400000)
524 
525 void
LoadAndReset(const char * osimage)526 LoadAndReset(const char *osimage)
527 {
528 	void *buf_addr;
529 	u_long size;
530 	const u_long *src;
531 	u_long *dest;
532 	u_long csum = 0;
533 	u_long csum2 = 0;
534 	u_long size2;
535 
536 	MMTA_IMASK = 0; /* mask all externel interrupt */
537 
538 	printf("LoadAndReset: copy start\n");
539 	buf_addr = (void *)OSIMAGE_BUF_ADDR;
540 
541 	size = *(const u_long *)osimage;
542 	src = (const u_long *)osimage;
543 	dest = buf_addr;
544 
545 	size = (size + sizeof(u_long) * 2 + 3) >> 2;
546 	size2 = size;
547 
548 	while (size--) {
549 		csum += *src;
550 		*dest++ = *src++;
551 	}
552 
553 	dest = buf_addr;
554 	while (size2--)
555 		csum2 += *dest++;
556 
557 	printf("LoadAndReset: copy end[%lx,%lx]\n", csum, csum2);
558 	printf("start XLoadAndReset\n");
559 
560 	XLoadAndReset(buf_addr);
561 }
562 
563 #ifdef sh3_tmp
564 
565 #define	UART_BASE	0xa4000008
566 
567 #define	IER	1
568 #define	IER_RBF	0x01
569 #define	IER_TBE	0x02
570 #define	IER_MSI	0x08
571 #define	FCR	2
572 #define	LCR	3
573 #define	LCR_DLAB	0x80
574 #define	DLM	1
575 #define	DLL	0
576 #define	MCR	4
577 #define	MCR_RTS	0x02
578 #define	MCR_DTR	0x01
579 #define	MCR_OUT2	0x08
580 #define	RTS_MODE	(MCR_RTS|MCR_DTR)
581 #define	LSR	5
582 #define	LSR_THRE	0x20
583 #define	LSR_ERROR	0x1e
584 #define	THR	0
585 #define	IIR	2
586 #define	IIR_II	0x06
587 #define	IIR_LSI	0x06
588 #define	IIR_MSI	0x00
589 #define	IIR_TBE	0x02
590 #define	IIR_PEND	0x01
591 #define	RBR	0
592 #define	MSR	6
593 
594 #define	OUTP(port, val)	*(volatile unsigned char *)(UART_BASE+port) = val
595 #define	INP(port)	(*(volatile unsigned char *)(UART_BASE+port))
596 
597 void
Init16550()598 Init16550()
599 {
600 	int diviser;
601 	int tmp;
602 
603 	/* Set speed */
604 	/* diviser = 12; */	/* 9600 bps */
605 	diviser = 6;	/* 19200 bps */
606 
607 	OUTP(IER, 0);
608 	/* OUTP(FCR, 0x87); */	/* FIFO mode */
609 	OUTP(FCR, 0x00);	/* no FIFO mode */
610 
611 	tmp = INP(LSR);
612 	tmp = INP(MSR);
613 	tmp = INP(IIR);
614 	tmp = INP(RBR);
615 
616 	OUTP(LCR, INP(LCR) | LCR_DLAB);
617 	OUTP(DLM, 0xff & (diviser>>8));
618 	OUTP(DLL, 0xff & diviser);
619 	OUTP(LCR, INP(LCR) & ~LCR_DLAB);
620 	OUTP(MCR, 0);
621 
622 	OUTP(LCR, 0x03);	/* 8 bit , no parity, 1 stop */
623 
624 	/* start comm */
625 	OUTP(MCR, RTS_MODE | MCR_OUT2);
626 	/* OUTP(IER, IER_RBF | IER_TBE | IER_MSI); */
627 }
628 
629 void
Send16550(int c)630 Send16550(int c)
631 {
632 	while (1) {
633 		OUTP(THR, c);
634 
635 		while ((INP(LSR) & LSR_THRE) == 0)
636 			;
637 
638 		if (c == '\n')
639 			c = '\r';
640 		else
641 			return;
642 	}
643 }
644 #endif /* sh3_tmp */
645 
646 
647 void
intc_intr(int ssr,int spc,int ssp)648 intc_intr(int ssr, int spc, int ssp)
649 {
650 	struct intc_intrhand *ih;
651 	int evtcode;
652 
653 	curcpu()->ci_data.cpu_nintr++;
654 
655 	evtcode = _reg_read_4(SH_(INTEVT));
656 
657 	ih = EVTCODE_IH(evtcode);
658 	KDASSERT(ih->ih_func);
659 	/*
660 	 * On entry, all interrupts are disabled,
661 	 * and exception is enabled for P3 access. (kernel stack is P3,
662 	 * SH3 may or may not cause TLB miss when access stack.)
663 	 * Enable higher level interrupt here.
664 	 */
665 	(void)_cpu_intr_resume(ih->ih_level);
666 
667 	if (evtcode == SH_INTEVT_TMU0_TUNI0) {	/* hardclock */
668 		struct clockframe cf;
669 		cf.spc = spc;
670 		cf.ssr = ssr;
671 		cf.ssp = ssp;
672 		(*ih->ih_func)(&cf);
673 	} else {
674 		(*ih->ih_func)(ih->ih_arg);
675 	}
676 }
677 
678 void *
mmeye_intr_establish(int irq,int trigger,int level,int (* func)(void *),void * arg)679 mmeye_intr_establish(int irq, int trigger, int level, int (*func)(void *),
680     void *arg)
681 {
682 	struct mmeye_intrhand *mh = &mmeye_intrhand[irq];
683 
684 	mh->intc_ih = intc_intr_establish(0x200 + (irq << 5), IST_LEVEL, level,
685 	    func, arg);
686 	mh->irq = irq;
687 
688 	MMTA_IMASK |= (1 << (15 - irq));
689 
690 	return (mh);
691 }
692 
693 void
mmeye_intr_disestablish(void * ih)694 mmeye_intr_disestablish(void *ih)
695 {
696 	struct mmeye_intrhand *mh = ih;
697 
698 	MMTA_IMASK &= ~(1 << (15 - mh->irq));
699 
700 	intc_intr_disestablish(mh->intc_ih);
701 }
702 
703 int
bus_space_map(bus_space_tag_t t,bus_addr_t addr,bus_size_t size,int flags,bus_space_handle_t * bshp)704 bus_space_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size, int flags,
705     bus_space_handle_t *bshp)
706 {
707 
708 #if defined(SH7750R)
709 	if (t == SH3_BUS_SPACE_PCMCIA_IO ||
710 	    t == SH3_BUS_SPACE_PCMCIA_IO8 ||
711 	    t == SH3_BUS_SPACE_PCMCIA_MEM ||
712 	    t == SH3_BUS_SPACE_PCMCIA_MEM8 ||
713 	    t == SH3_BUS_SPACE_PCMCIA_ATT ||
714 	    t == SH3_BUS_SPACE_PCMCIA_ATT8) {
715 		pt_entry_t *pte;
716 		vaddr_t va;
717 		u_long pa, endpa;
718 		uint32_t sa = 0;
719 
720 		pa = sh3_trunc_page(addr);
721 		endpa = sh3_round_page(addr + size);
722 
723 #ifdef DIAGNOSTIC
724 		if (endpa <= pa)
725 			panic("bus_space_map: overflow");
726 #endif
727 
728 		va = uvm_km_alloc(kernel_map, endpa - pa, 0, UVM_KMF_VAONLY);
729 		if (va == 0) {
730 			printf("%s: nomem\n", __func__);
731 			return ENOMEM;
732 		}
733 
734 		*bshp = (bus_space_handle_t)(va + (addr & PGOFSET));
735 
736 		switch (t) {
737 		case SH3_BUS_SPACE_PCMCIA_IO:	sa = _PG_PCMCIA_IO16;	break;
738 		case SH3_BUS_SPACE_PCMCIA_IO8:	sa = _PG_PCMCIA_IO8;	break;
739 		case SH3_BUS_SPACE_PCMCIA_MEM:	sa = _PG_PCMCIA_MEM16;	break;
740 		case SH3_BUS_SPACE_PCMCIA_MEM8:	sa = _PG_PCMCIA_MEM8;	break;
741 		case SH3_BUS_SPACE_PCMCIA_ATT:	sa = _PG_PCMCIA_ATTR16;	break;
742 		case SH3_BUS_SPACE_PCMCIA_ATT8:	sa = _PG_PCMCIA_ATTR8;	break;
743 		}
744 
745 		for ( ; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) {
746 			pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE, 0);
747 			pte = __pmap_kpte_lookup(va);
748 			KDASSERT(pte);
749 			*pte |= sa;
750 			sh_tlb_update(0, va, *pte);
751 		}
752 
753 		return 0;
754 	}
755 #endif
756 
757 	*bshp = (bus_space_handle_t)addr;
758 	return 0;
759 }
760 
761 void
sh_memio_unmap(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t size)762 sh_memio_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
763 {
764 
765 #if defined(SH7750R)
766 	if (t == SH3_BUS_SPACE_PCMCIA_IO ||
767 	    t == SH3_BUS_SPACE_PCMCIA_IO8 ||
768 	    t == SH3_BUS_SPACE_PCMCIA_MEM ||
769 	    t == SH3_BUS_SPACE_PCMCIA_MEM8 ||
770 	    t == SH3_BUS_SPACE_PCMCIA_ATT ||
771 	    t == SH3_BUS_SPACE_PCMCIA_ATT8) {
772 		u_long va, endva;
773 
774 		va = sh3_trunc_page(bsh);
775 		endva = sh3_round_page(bsh + size);
776 
777 #ifdef DIAGNOSTIC
778 		if (endva <= va)
779 			panic("bus_space_unmap: overflow");
780 #endif
781 
782 		pmap_kremove(va, endva - va);
783 
784 		/*
785 		 * Free the kernel virtual mapping
786 		 */
787 		uvm_km_free(kernel_map, va, endva - va, UVM_KMF_VAONLY);
788 
789 		return;
790 	}
791 #endif
792 
793 	/* Nothing */
794 }
795 
796 int
sh_memio_subregion(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,bus_size_t size,bus_space_handle_t * nbshp)797 sh_memio_subregion(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t offset,
798     bus_size_t size, bus_space_handle_t *nbshp)
799 {
800 
801 	*nbshp = bsh + offset;
802 	return 0;
803 }
804 
805 /*
806  * Look up information in bootinfo of boot loader.
807  */
808 void *
lookup_bootinfo(unsigned int type)809 lookup_bootinfo(unsigned int type)
810 {
811 	struct btinfo_common *bt;
812 	char *help = bootinfo;
813 
814 	if (((struct btinfo_common *)help)->next == 0)
815 		return NULL;		/* bootinfo not present */
816 	do {
817 		bt = (struct btinfo_common *)help;
818 		printf("Type %d @%p\n", bt->type, (void *)(intptr_t)bt);
819 		if (bt->type == type)
820 			return (void *)help;
821 		help += bt->next;
822 	} while (bt->next != 0 &&
823 	    (size_t)help < (size_t)bootinfo + BOOTINFO_SIZE);
824 
825 	return NULL;
826 }
827 
828 #ifdef MODULAR
829 /*
830  * Push any modules loaded by the boot loader.
831  */
832 void
module_init_md(void)833 module_init_md(void)
834 {
835 }
836 #endif /* MODULAR */
837 
838 #if defined(MMEYE_EPC_WDT)
839 callout_t epc_wdtc;
840 
841 void
epc_watchdog_timer_reset(void * arg)842 epc_watchdog_timer_reset(void *arg)
843 {
844 
845 	callout_schedule(&epc_wdtc, 15 * hz);
846 
847 	EPC_WDT = WDT_RDYCMD;
848 	EPC_WDT = WDT_CLRCMD;
849 }
850 #endif
851