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