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