1 /* $NetBSD: machdep.c,v 1.28 2002/05/10 20:14:40 uch 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 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /*- 41 * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. 42 * All rights reserved. 43 * 44 * This code is derived from software contributed to Berkeley by 45 * William Jolitz. 46 * 47 * Redistribution and use in source and binary forms, with or without 48 * modification, are permitted provided that the following conditions 49 * are met: 50 * 1. Redistributions of source code must retain the above copyright 51 * notice, this list of conditions and the following disclaimer. 52 * 2. Redistributions in binary form must reproduce the above copyright 53 * notice, this list of conditions and the following disclaimer in the 54 * documentation and/or other materials provided with the distribution. 55 * 3. All advertising materials mentioning features or use of this software 56 * must display the following acknowledgement: 57 * This product includes software developed by the University of 58 * California, Berkeley and its contributors. 59 * 4. Neither the name of the University nor the names of its contributors 60 * may be used to endorse or promote products derived from this software 61 * without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 64 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 65 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 66 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 67 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 68 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 69 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 70 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 71 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 72 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 73 * SUCH DAMAGE. 74 * 75 * @(#)machdep.c 7.4 (Berkeley) 6/3/91 76 */ 77 78 #include "opt_ddb.h" 79 #include "opt_memsize.h" 80 81 #include <sys/param.h> 82 #include <sys/systm.h> 83 #include <sys/kernel.h> 84 #include <sys/user.h> 85 #include <sys/mount.h> 86 #include <sys/reboot.h> 87 #include <sys/sysctl.h> 88 #include <sys/msgbuf.h> 89 #include <uvm/uvm_extern.h> 90 #ifdef DDB 91 #include <machine/db_machdep.h> 92 #include <ddb/db_extern.h> 93 #endif 94 95 #include <sh3/bscreg.h> 96 #include <sh3/cpgreg.h> 97 #include <sh3/cache_sh3.h> 98 #include <sh3/exception.h> 99 100 #include <machine/bus.h> 101 #include <machine/mmeye.h> 102 #include <machine/intr.h> 103 104 #include <dev/cons.h> 105 106 /* the following is used externally (sysctl_hw) */ 107 char machine[] = MACHINE; /* mmeye */ 108 char machine_arch[] = MACHINE_ARCH; /* sh3eb */ 109 110 void initSH3 __P((void *)); 111 void LoadAndReset __P((char *)); 112 void XLoadAndReset __P((char *)); 113 void consinit __P((void)); 114 void sh3_cache_on __P((void)); 115 void InitializeBsc(void); 116 117 struct mmeye_intrhand { 118 void *intc_ih; 119 int irq; 120 } mmeye_intrhand[_INTR_N]; 121 122 /* 123 * Machine-dependent startup code 124 * 125 * This is called from main() in kern/main.c. 126 */ 127 void 128 cpu_startup() 129 { 130 131 sh_startup(); 132 } 133 134 /* 135 * machine dependent system variables. 136 */ 137 int 138 cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 139 int *name; 140 u_int namelen; 141 void *oldp; 142 size_t *oldlenp; 143 void *newp; 144 size_t newlen; 145 struct proc *p; 146 { 147 dev_t consdev; 148 char *osimage; 149 150 /* all sysctl names at this level are terminal */ 151 if (namelen != 1) 152 return (ENOTDIR); /* overloaded */ 153 154 switch (name[0]) { 155 case CPU_CONSDEV: 156 if (cn_tab != NULL) 157 consdev = cn_tab->cn_dev; 158 else 159 consdev = NODEV; 160 return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev, 161 sizeof consdev)); 162 163 case CPU_LOADANDRESET: 164 if (newp != NULL) { 165 osimage = (char *)(*(u_long *)newp); 166 167 LoadAndReset(osimage); 168 /* not reach here */ 169 } 170 return (0); 171 172 default: 173 return (EOPNOTSUPP); 174 } 175 /* NOTREACHED */ 176 } 177 178 int waittime = -1; 179 180 void 181 cpu_reboot(howto, bootstr) 182 int howto; 183 char *bootstr; 184 { 185 if (cold) { 186 howto |= RB_HALT; 187 goto haltsys; 188 } 189 190 boothowto = howto; 191 if ((howto & RB_NOSYNC) == 0 && waittime < 0) { 192 waittime = 0; 193 vfs_shutdown(); 194 /* 195 * If we've been adjusting the clock, the todr 196 * will be out of synch; adjust it now. 197 */ 198 /* resettodr(); */ 199 } 200 201 /* Disable interrupts. */ 202 splhigh(); 203 204 /* Do a dump if requested. */ 205 if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) 206 dumpsys(); 207 208 haltsys: 209 doshutdownhooks(); 210 211 if (howto & RB_HALT) { 212 printf("\n"); 213 printf("The operating system has halted.\n"); 214 printf("Please press any key to reboot.\n\n"); 215 cngetc(); 216 } 217 218 printf("rebooting...\n"); 219 cpu_reset(); 220 for(;;) ; 221 /*NOTREACHED*/ 222 } 223 224 void 225 initSH3(void *pc) /* XXX return address */ 226 { 227 extern char edata[], end[]; 228 vaddr_t kernend; 229 230 /* Clear bss */ 231 memset(edata, 0, end - edata); 232 233 /* Initilize CPU ops. */ 234 #if defined(SH7708R) 235 sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708R); 236 #elif defined(SH7708) 237 sh_cpu_init(CPU_ARCH_SH3, CPU_PRODUCT_7708); 238 #else 239 #warning "unknown product" 240 #endif 241 consinit(); 242 243 kernend = atop(round_page(SH3_P1SEG_TO_PHYS(end))); 244 #ifdef DDB 245 /* XXX Currently symbol table size is not passed to the kernel. */ 246 kernend += 0x40000; /* XXX */ 247 #endif 248 249 /* Load memory to UVM */ 250 physmem = atop(IOM_RAM_SIZE); 251 uvm_page_physload( 252 kernend, atop(IOM_RAM_BEGIN + IOM_RAM_SIZE), 253 kernend, atop(IOM_RAM_BEGIN + IOM_RAM_SIZE), 254 VM_FREELIST_DEFAULT); 255 256 /* Initialize proc0 u-area */ 257 sh_proc0_init(); 258 259 /* Initialize pmap and start to address translation */ 260 pmap_bootstrap(); 261 262 #ifdef DDB 263 ddb_init(1, end, end + 0x40000); /* XXX */ 264 #endif 265 /* 266 * XXX We can't return here, because we change stack pointer. 267 * So jump to return address directly. 268 */ 269 __asm __volatile ( 270 "jmp @%0;" 271 "mov %1, r15" 272 :: "r"(pc),"r"(proc0.p_md.md_pcb->pcb_sf.sf_r7_bank)); 273 } 274 275 /* 276 * consinit: 277 * initialize the system console. 278 */ 279 void 280 consinit() 281 { 282 static int initted; 283 284 if (initted) 285 return; 286 initted = 1; 287 288 cninit(); 289 } 290 291 /* 292 * InitializeBsc 293 * : BSC(Bus State Controler) 294 */ 295 void 296 InitializeBsc() 297 { 298 #ifdef NOPCMCIA 299 /* 300 * Drive RAS,CAS in stand by mode and bus release mode 301 * Area0 = Normal memory, Area5,6=Normal(no burst) 302 * Area2 = Normal memory, Area3 = DRAM, Area5 = Normal memory 303 * Area4 = Normal Memory 304 * Area6 = Normal memory 305 */ 306 _reg_write_2(SH3_BCR1, 0x1010); 307 #else /* NOPCMCIA */ 308 /* 309 * Drive RAS,CAS in stand by mode and bus release mode 310 * Area0 = Normal memory, Area5,6=Normal(no burst) 311 * Area2 = Normal memory, Area3 = DRAM, Area5 = PCMCIA 312 * Area4 = Normal Memory 313 * Area6 = PCMCIA 314 */ 315 _reg_write_2(SH3_BCR1, 0x1013); 316 #endif /* NOPCMCIA */ 317 318 #define PCMCIA_16 319 #ifdef PCMCIA_16 320 /* 321 * Bus Width 322 * Area4: Bus width = 16bit 323 * Area6,5 = 16bit 324 * Area1 = 8bit 325 * Area2,3: Bus width = 32bit 326 */ 327 _reg_write_2(SH3_BCR2, 0x2af4); 328 #else /* PCMCIA16 */ 329 /* 330 * Bus Width 331 * Area4: Bus width = 16bit 332 * Area6,5 = 8bit 333 * Area1 = 8bit 334 * Area2,3: Bus width = 32bit 335 */ 336 _reg_write_2(SH3_BCR2, 0x16f4); 337 #endif /* PCMCIA16 */ 338 /* 339 * Idle cycle number in transition area and read to write 340 * Area6 = 3, Area5 = 3, Area4 = 3, Area3 = 3, Area2 = 3 341 * Area1 = 3, Area0 = 3 342 */ 343 _reg_write_2(SH3_WCR1, 0x3fff); 344 345 #if 0 346 /* 347 * Wait cycle 348 * Area 6,5 = 2 349 * Area 4 = 10 350 * Area 3 = 2 351 * Area 2,1 = 3 352 * Area 0 = 6 353 */ 354 _reg_write_2(SH3_WCR2, 0x4bdd); 355 #else 356 /* 357 * Wait cycle 358 * Area 6 = 6 359 * Area 5 = 2 360 * Area 4 = 10 361 * Area 3 = 3 362 * Area 2,1 = 3 363 * Area 0 = 6 364 */ 365 _reg_write_2(SH3_WCR2, 0xabfd); 366 #endif 367 368 /* 369 * RAS pre-charge = 2cycle, RAS-CAS delay = 3 cycle, 370 * write pre-charge = 1cycle 371 * CAS before RAS refresh RAS assert time = 3 cycle 372 * Disable burst, Bus size=32bit, Column Address=10bit,Refresh ON 373 * CAS before RAS refresh ON, EDO DRAM 374 */ 375 _reg_write_2(SH3_MCR, 0x6135); 376 /* SHREG_MCR = 0x4135; */ 377 378 /* DRAM Control Register */ 379 _reg_write_2(SH3_DCR, 0x0000); 380 381 /* 382 * PCMCIA Control Register 383 * OE/WE assert delay 3.5 cycle 384 * OE/WE negate-address delay 3.5 cycle 385 */ 386 _reg_write_2(SH3_PCR, 0x00ff); 387 388 /* 389 * Refresh Timer Control/Status Register 390 * Disable interrupt by CMF, closk 1/16, Disable OVF interrupt 391 * Count Limit = 1024 392 * In following statement, the reason why high byte = 0xa5(a4 in RFCR) 393 * is the rule of SH3 in writing these register . 394 */ 395 _reg_write_2(SH3_RTCSR, 0xa594); 396 397 /* 398 * Refresh Timer Counter 399 * initialize to 0 400 */ 401 _reg_write_2(SH3_RTCNT, 0xa500); 402 403 /* 404 * set Refresh Time Constant Register 405 */ 406 _reg_write_2(SH3_RTCOR, 0xa50d); 407 408 /* 409 * init Refresh Count Register 410 */ 411 _reg_write_2(SH3_RFCR, 0xa400); 412 413 /* 414 * Set Clock mode (make internal clock double speed) 415 */ 416 #ifdef SH7708R 417 _reg_write_2(SH3_FRQCR, 0xa100); /* 100MHz */ 418 #else 419 _reg_write_2(SH3_FRQCR, 0x0112); /* 60MHz */ 420 #endif 421 422 #ifndef MMEYE_NO_CACHE 423 /* Cache ON */ 424 _reg_write_4(SH3_CCR, SH3_CCR_CE); 425 #endif 426 } 427 428 void 429 sh3_cache_on(void) 430 { 431 #ifndef MMEYE_NO_CACHE 432 /* Cache ON */ 433 _reg_write_4(SH3_CCR, SH3_CCR_CE); 434 _reg_write_4(SH3_CCR, SH3_CCR_CF | SH3_CCR_CE); /* cache clear */ 435 _reg_write_4(SH3_CCR, SH3_CCR_CE); 436 #endif 437 } 438 439 /* XXX This value depends on physical available memory */ 440 #define OSIMAGE_BUF_ADDR (IOM_RAM_BEGIN + 0x00400000) 441 442 void 443 LoadAndReset(osimage) 444 char *osimage; 445 { 446 void *buf_addr; 447 u_long size; 448 u_long *src; 449 u_long *dest; 450 u_long csum = 0; 451 u_long csum2 = 0; 452 u_long size2; 453 454 MMTA_IMASK = 0; /* mask all externel interrupt */ 455 456 printf("LoadAndReset: copy start\n"); 457 buf_addr = (void *)OSIMAGE_BUF_ADDR; 458 459 size = *(u_long *)osimage; 460 src = (u_long *)osimage; 461 dest = buf_addr; 462 463 size = (size + sizeof(u_long) * 2 + 3) >> 2; 464 size2 = size; 465 466 while (size--) { 467 csum += *src; 468 *dest++ = *src++; 469 } 470 471 dest = buf_addr; 472 while (size2--) 473 csum2 += *dest++; 474 475 printf("LoadAndReset: copy end[%lx,%lx]\n", csum, csum2); 476 printf("start XLoadAndReset\n"); 477 478 XLoadAndReset(buf_addr); 479 } 480 481 #ifdef sh3_tmp 482 483 #define UART_BASE 0xa4000008 484 485 #define IER 1 486 #define IER_RBF 0x01 487 #define IER_TBE 0x02 488 #define IER_MSI 0x08 489 #define FCR 2 490 #define LCR 3 491 #define LCR_DLAB 0x80 492 #define DLM 1 493 #define DLL 0 494 #define MCR 4 495 #define MCR_RTS 0x02 496 #define MCR_DTR 0x01 497 #define MCR_OUT2 0x08 498 #define RTS_MODE (MCR_RTS|MCR_DTR) 499 #define LSR 5 500 #define LSR_THRE 0x20 501 #define LSR_ERROR 0x1e 502 #define THR 0 503 #define IIR 2 504 #define IIR_II 0x06 505 #define IIR_LSI 0x06 506 #define IIR_MSI 0x00 507 #define IIR_TBE 0x02 508 #define IIR_PEND 0x01 509 #define RBR 0 510 #define MSR 6 511 512 #define OUTP(port, val) *(volatile unsigned char *)(UART_BASE+port) = val 513 #define INP(port) (*(volatile unsigned char *)(UART_BASE+port)) 514 515 void 516 Init16550() 517 { 518 int diviser; 519 int tmp; 520 521 /* Set speed */ 522 /* diviser = 12; */ /* 9600 bps */ 523 diviser = 6; /* 19200 bps */ 524 525 OUTP(IER, 0); 526 /* OUTP(FCR, 0x87); */ /* FIFO mode */ 527 OUTP(FCR, 0x00); /* no FIFO mode */ 528 529 tmp = INP(LSR); 530 tmp = INP(MSR); 531 tmp = INP(IIR); 532 tmp = INP(RBR); 533 534 OUTP(LCR, INP(LCR) | LCR_DLAB); 535 OUTP(DLM, 0xff & (diviser>>8)); 536 OUTP(DLL, 0xff & diviser); 537 OUTP(LCR, INP(LCR) & ~LCR_DLAB); 538 OUTP(MCR, 0); 539 540 OUTP(LCR, 0x03); /* 8 bit , no parity, 1 stop */ 541 542 /* start comm */ 543 OUTP(MCR, RTS_MODE | MCR_OUT2); 544 /* OUTP(IER, IER_RBF | IER_TBE | IER_MSI); */ 545 } 546 547 void 548 Send16550(int c) 549 { 550 while (1) { 551 OUTP(THR, c); 552 553 while ((INP(LSR) & LSR_THRE) == 0) 554 ; 555 556 if (c == '\n') 557 c = '\r'; 558 else 559 return; 560 } 561 } 562 #endif /* sh3_tmp */ 563 564 565 void 566 intc_intr(int ssr, int spc, int ssp) 567 { 568 struct intc_intrhand *ih; 569 int s, evtcode; 570 571 evtcode = _reg_read_4(SH3_INTEVT); 572 573 ih = EVTCODE_IH(evtcode); 574 KDASSERT(ih->ih_func); 575 /* 576 * On entry, all interrrupts are disabled, 577 * and exception is enabled for P3 access. (kernel stack is P3, 578 * SH3 may or may not cause TLB miss when access stack.) 579 * Enable higher level interrupt here. 580 */ 581 s = _cpu_intr_resume(ih->ih_level); 582 583 if (evtcode == SH_INTEVT_TMU0_TUNI0) { /* hardclock */ 584 struct clockframe cf; 585 cf.spc = spc; 586 cf.ssr = ssr; 587 cf.ssp = ssp; 588 (*ih->ih_func)(&cf); 589 } else { 590 (*ih->ih_func)(ih->ih_arg); 591 } 592 } 593 594 void * 595 mmeye_intr_establish(int irq, int trigger, int level, int (*func)(void *), 596 void *arg) 597 { 598 struct mmeye_intrhand *mh = &mmeye_intrhand[irq]; 599 600 mh->intc_ih = intc_intr_establish(0x200 + (irq << 5), IST_LEVEL, level, 601 func, arg); 602 mh->irq = irq; 603 604 MMTA_IMASK |= (1 << (15 - irq)); 605 606 return ((void *)irq); 607 } 608 609 void 610 mmeye_intr_disestablish(void *ih) 611 { 612 struct mmeye_intrhand *mh = ih; 613 614 MMTA_IMASK &= ~(1 << (15 - mh->irq)); 615 616 intc_intr_disestablish(mh->intc_ih); 617 } 618 619 int 620 bus_space_map(t, addr, size, flags, bshp) 621 bus_space_tag_t t; 622 bus_addr_t addr; 623 bus_size_t size; 624 int flags; 625 bus_space_handle_t *bshp; 626 { 627 *bshp = (bus_space_handle_t)addr; 628 629 return 0; 630 } 631 632 int 633 sh_memio_subregion(t, bsh, offset, size, nbshp) 634 bus_space_tag_t t; 635 bus_space_handle_t bsh; 636 bus_size_t offset, size; 637 bus_space_handle_t *nbshp; 638 { 639 640 *nbshp = bsh + offset; 641 return (0); 642 } 643