Home | History | Annotate | Line # | Download | only in mmeye
      1 /*	$NetBSD: machdep.c,v 1.59 2025/07/13 21:07:04 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.59 2025/07/13 21:07:04 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
    135 cpu_startup(void)
    136 {
    137 
    138 	sh_startup();
    139 }
    140 
    141 /*
    142  * machine dependent system variables.
    143  */
    144 static int
    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
    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
    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
    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
    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
    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
    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 external interrupts */
    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
    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
    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
    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 *
    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
    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
    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
    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
    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 *
    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
    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
    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