1/*	$NetBSD: machdep.c,v 1.54 2011/01/19 10:19:07 he 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.54 2011/01/19 10:19:07 he 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) */
111char machine[] = MACHINE;		/* mmeye */
112char machine_arch[] = MACHINE_ARCH;	/* sh3eb */
113
114char bootinfo[BOOTINFO_SIZE];
115
116void initSH3(void *, u_int, int32_t);
117void LoadAndReset(const char *);
118void XLoadAndReset(char *);
119void consinit(void);
120void sh3_cache_on(void);
121void InitializeBsc(void);
122void *lookup_bootinfo(unsigned int);
123
124struct 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 */
134void
135cpu_startup(void)
136{
137
138	sh_startup();
139}
140
141/*
142 * machine dependent system variables.
143 */
144static int
145sysctl_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
160SYSCTL_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
186int waittime = -1;
187
188void
189cpu_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
219haltsys:
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
239void
240initSH3(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	int i;
247	const char *bi_msg;
248
249	/* Clear bss */
250	memset(edata, 0, end - edata);
251
252	/* Check for valid bootinfo passed from bootstrap */
253	if (bim == BOOTINFO_MAGIC) {
254		struct btinfo_magic *bi_magic;
255
256		memcpy(bootinfo, (void *)bip, BOOTINFO_SIZE);
257		bi_magic = lookup_bootinfo(BTINFO_MAGIC);
258		if (bi_magic == NULL) {
259			bi_msg = "missing bootinfo structure";
260			bim = (uintptr_t)bip;
261		} else if (bi_magic->magic != BOOTINFO_MAGIC) {
262			bi_msg = "invalid bootinfo structure";
263			bim = bi_magic->magic;
264		} else
265			bi_msg = NULL;
266	} else {
267		bi_msg = "invalid bootinfo (standalone boot?)";
268	}
269
270	symbolsize = 0;
271#if NKSYMS || defined(MODULAR) || defined(DDB)
272	if (memcmp(&end, ELFMAG, SELFMAG) == 0) {
273		Elf_Ehdr *eh = (void *)end;
274		Elf_Shdr *sh = (void *)(end + eh->e_shoff);
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 */
341void
342consinit(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 */
357void
358InitializeBsc(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
511void
512sh3_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
525void
526LoadAndReset(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
597void
598Init16550()
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
629void
630Send16550(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
647void
648intc_intr(int ssr, int spc, int ssp)
649{
650	struct intc_intrhand *ih;
651	int s, 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 interrrupts 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	s = _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
678void *
679mmeye_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
693void
694mmeye_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
703int
704bus_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
761void
762sh_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
796int
797sh_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 */
808void *
809lookup_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 */
832void
833module_init_md(void)
834{
835}
836#endif /* MODULAR */
837
838#if defined(MMEYE_EPC_WDT)
839callout_t epc_wdtc;
840
841void
842epc_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