Annotation of sys/arch/landisk/landisk/machdep.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: machdep.c,v 1.13 2007/06/06 17:15:12 deraadt Exp $ */
! 2: /* $NetBSD: machdep.c,v 1.1 2006/09/01 21:26:18 uwe Exp $ */
! 3:
! 4: /*-
! 5: * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
! 6: * All rights reserved.
! 7: *
! 8: * This code is derived from software contributed to The NetBSD Foundation
! 9: * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
! 10: * Simulation Facility, NASA Ames Research Center.
! 11: *
! 12: * Redistribution and use in source and binary forms, with or without
! 13: * modification, are permitted provided that the following conditions
! 14: * are met:
! 15: * 1. Redistributions of source code must retain the above copyright
! 16: * notice, this list of conditions and the following disclaimer.
! 17: * 2. Redistributions in binary form must reproduce the above copyright
! 18: * notice, this list of conditions and the following disclaimer in the
! 19: * documentation and/or other materials provided with the distribution.
! 20: * 3. All advertising materials mentioning features or use of this software
! 21: * must display the following acknowledgement:
! 22: * This product includes software developed by the NetBSD
! 23: * Foundation, Inc. and its contributors.
! 24: * 4. Neither the name of The NetBSD Foundation nor the names of its
! 25: * contributors may be used to endorse or promote products derived
! 26: * from this software without specific prior written permission.
! 27: *
! 28: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
! 29: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! 30: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! 31: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
! 32: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! 33: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! 34: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! 35: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! 36: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! 37: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 38: * POSSIBILITY OF SUCH DAMAGE.
! 39: */
! 40:
! 41: /*-
! 42: * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
! 43: * All rights reserved.
! 44: *
! 45: * This code is derived from software contributed to Berkeley by
! 46: * William Jolitz.
! 47: *
! 48: * Redistribution and use in source and binary forms, with or without
! 49: * modification, are permitted provided that the following conditions
! 50: * are met:
! 51: * 1. Redistributions of source code must retain the above copyright
! 52: * notice, this list of conditions and the following disclaimer.
! 53: * 2. Redistributions in binary form must reproduce the above copyright
! 54: * notice, this list of conditions and the following disclaimer in the
! 55: * documentation and/or other materials provided with the distribution.
! 56: * 3. Neither the name of the University nor the names of its contributors
! 57: * may be used to endorse or promote products derived from this software
! 58: * without specific prior written permission.
! 59: *
! 60: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 61: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 62: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 63: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 64: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 65: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 66: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 67: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 68: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 69: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 70: * SUCH DAMAGE.
! 71: *
! 72: * @(#)machdep.c 7.4 (Berkeley) 6/3/91
! 73: */
! 74:
! 75: #include "ksyms.h"
! 76:
! 77: #include <sys/param.h>
! 78: #include <sys/systm.h>
! 79: #include <sys/kernel.h>
! 80: #include <sys/user.h>
! 81: #include <sys/mount.h>
! 82: #include <sys/reboot.h>
! 83: #include <sys/sysctl.h>
! 84: #include <sys/exec.h>
! 85: #include <sys/core.h>
! 86: #include <sys/kcore.h>
! 87:
! 88: #include <uvm/uvm_extern.h>
! 89:
! 90: #include <dev/cons.h>
! 91:
! 92: #include <sh/bscreg.h>
! 93: #include <sh/cpgreg.h>
! 94: #include <sh/trap.h>
! 95:
! 96: #include <sh/cache.h>
! 97: #include <sh/cache_sh4.h>
! 98: #include <sh/mmu_sh4.h>
! 99:
! 100: #include <machine/cpu.h>
! 101: #include <machine/kcore.h>
! 102:
! 103: #include <landisk/landisk/landiskreg.h>
! 104:
! 105: #ifdef DDB
! 106: #include <machine/db_machdep.h>
! 107: #include <ddb/db_extern.h>
! 108: #include <ddb/db_interface.h>
! 109: #endif
! 110:
! 111: /* the following is used externally (sysctl_hw) */
! 112: char machine[] = MACHINE; /* landisk */
! 113:
! 114: __dead void landisk_startup(int, char *);
! 115: __dead void main(void);
! 116: void cpu_init_kcore_hdr(void);
! 117: void blink_led(void *);
! 118:
! 119: int kbd_reset;
! 120: int led_blink;
! 121:
! 122: extern u_int32_t getramsize(void);
! 123:
! 124: void
! 125: cpu_startup(void)
! 126: {
! 127: extern char cpu_model[120];
! 128:
! 129: /* XXX: show model (LANDISK/USL-5P) */
! 130: strlcpy(cpu_model, "I-O DATA USL-5P", sizeof cpu_model);
! 131:
! 132: sh_startup();
! 133: }
! 134:
! 135: vaddr_t kernend; /* used by /dev/mem too */
! 136: char *esym;
! 137:
! 138: __dead void
! 139: landisk_startup(int howto, char *_esym)
! 140: {
! 141: u_int32_t ramsize;
! 142:
! 143: /* Start to determine heap area */
! 144: esym = _esym;
! 145: kernend = (vaddr_t)round_page((vaddr_t)esym);
! 146:
! 147: boothowto = howto;
! 148:
! 149: ramsize = getramsize();
! 150:
! 151: /* Initialize CPU ops. */
! 152: sh_cpu_init(CPU_ARCH_SH4, CPU_PRODUCT_7751R);
! 153:
! 154: /* Initialize early console */
! 155: consinit();
! 156:
! 157: /* Load memory to UVM */
! 158: if (ramsize == 0 || ramsize > 512 * 1024 * 1024)
! 159: ramsize = IOM_RAM_SIZE;
! 160: physmem = atop(ramsize);
! 161: kernend = atop(round_page(SH3_P1SEG_TO_PHYS(kernend)));
! 162: uvm_page_physload(atop(IOM_RAM_BEGIN),
! 163: atop(IOM_RAM_BEGIN + ramsize), kernend,
! 164: atop(IOM_RAM_BEGIN + ramsize), VM_FREELIST_DEFAULT);
! 165: cpu_init_kcore_hdr(); /* need to be done before pmap_bootstrap */
! 166:
! 167: /* Initialize proc0 u-area */
! 168: sh_proc0_init();
! 169:
! 170: /* Initialize pmap and start to address translation */
! 171: pmap_bootstrap();
! 172:
! 173: #ifdef RAMDISK_HOOKS
! 174: boothowto |= RB_DFLTROOT;
! 175: #endif /* RAMDISK_HOOKS */
! 176:
! 177: #if defined(DDB)
! 178: db_machine_init();
! 179: ddb_init();
! 180: if (boothowto & RB_KDB) {
! 181: Debugger();
! 182: }
! 183: #endif
! 184:
! 185: /* Jump to main */
! 186: __asm volatile(
! 187: "jmp @%0\n\t"
! 188: " mov %1, sp"
! 189: :: "r" (main), "r" (proc0.p_md.md_pcb->pcb_sf.sf_r7_bank));
! 190: /* NOTREACHED */
! 191: for (;;) ;
! 192: }
! 193:
! 194: void
! 195: boot(int howto)
! 196: {
! 197:
! 198: if (cold) {
! 199: if ((howto & RB_USERREQ) == 0)
! 200: howto |= RB_HALT;
! 201: goto haltsys;
! 202: }
! 203:
! 204: boothowto = howto;
! 205: if ((howto & RB_NOSYNC) == 0) {
! 206: vfs_shutdown();
! 207: /*
! 208: * If we've been adjusting the clock, the todr
! 209: * will be out of synch; adjust it now.
! 210: */
! 211: if ((howto & RB_TIMEBAD) == 0)
! 212: resettodr();
! 213: else
! 214: printf("WARNING: not updating battery clock\n");
! 215: }
! 216:
! 217: /* Disable interrupts. */
! 218: splhigh();
! 219:
! 220: /* Do a dump if requested. */
! 221: if (howto & RB_DUMP)
! 222: dumpsys();
! 223:
! 224: haltsys:
! 225: doshutdownhooks();
! 226:
! 227: if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
! 228: _reg_write_1(LANDISK_PWRMNG, PWRMNG_POWEROFF);
! 229: delay(1 * 1000 * 1000);
! 230: printf("POWEROFF FAILED!\n");
! 231: howto |= RB_HALT;
! 232: }
! 233:
! 234: if (howto & RB_HALT) {
! 235: printf("\n");
! 236: printf("The operating system has halted.\n");
! 237: printf("Please press any key to reboot.\n\n");
! 238: cngetc();
! 239: }
! 240:
! 241: printf("rebooting...\n");
! 242: machine_reset();
! 243:
! 244: /*NOTREACHED*/
! 245: for (;;) {
! 246: continue;
! 247: }
! 248: }
! 249:
! 250: void
! 251: machine_reset(void)
! 252: {
! 253: _cpu_exception_suspend();
! 254: _reg_write_4(SH_(EXPEVT), EXPEVT_RESET_MANUAL);
! 255: (void)*(volatile uint32_t *)0x80000001; /* CPU shutdown */
! 256:
! 257: /*NOTREACHED*/
! 258: for (;;) {
! 259: continue;
! 260: }
! 261: }
! 262:
! 263: #if !defined(DONT_INIT_BSC)
! 264: /*
! 265: * InitializeBsc
! 266: * : BSC(Bus State Controller)
! 267: */
! 268: void InitializeBsc(void);
! 269:
! 270: void
! 271: InitializeBsc(void)
! 272: {
! 273:
! 274: /*
! 275: * Drive RAS,CAS in stand by mode and bus release mode
! 276: * Area0 = Normal memory, Area5,6=Normal(no burst)
! 277: * Area2 = Normal memory, Area3 = SDRAM, Area5 = Normal memory
! 278: * Area4 = Normal Memory
! 279: * Area6 = Normal memory
! 280: */
! 281: _reg_write_4(SH4_BCR1, BSC_BCR1_VAL);
! 282:
! 283: /*
! 284: * Bus Width
! 285: * Area4: Bus width = 16bit
! 286: * Area6,5 = 16bit
! 287: * Area1 = 8bit
! 288: * Area2,3: Bus width = 32bit
! 289: */
! 290: _reg_write_2(SH4_BCR2, BSC_BCR2_VAL);
! 291:
! 292: #if defined(SH4) && defined(SH7751R)
! 293: if (cpu_product == CPU_PRODUCT_7751R) {
! 294: #ifdef BSC_BCR3_VAL
! 295: _reg_write_2(SH4_BCR3, BSC_BCR3_VAL);
! 296: #endif
! 297: #ifdef BSC_BCR4_VAL
! 298: _reg_write_4(SH4_BCR4, BSC_BCR4_VAL);
! 299: #endif
! 300: }
! 301: #endif /* SH4 && SH7751R */
! 302:
! 303: /*
! 304: * Idle cycle number in transition area and read to write
! 305: * Area6 = 3, Area5 = 3, Area4 = 3, Area3 = 3, Area2 = 3
! 306: * Area1 = 3, Area0 = 3
! 307: */
! 308: _reg_write_4(SH4_WCR1, BSC_WCR1_VAL);
! 309:
! 310: /*
! 311: * Wait cycle
! 312: * Area 6 = 6
! 313: * Area 5 = 2
! 314: * Area 4 = 10
! 315: * Area 3 = 3
! 316: * Area 2,1 = 3
! 317: * Area 0 = 6
! 318: */
! 319: _reg_write_4(SH4_WCR2, BSC_WCR2_VAL);
! 320:
! 321: #ifdef BSC_WCR3_VAL
! 322: _reg_write_4(SH4_WCR3, BSC_WCR3_VAL);
! 323: #endif
! 324:
! 325: /*
! 326: * RAS pre-charge = 2cycle, RAS-CAS delay = 3 cycle,
! 327: * write pre-charge=1cycle
! 328: * CAS before RAS refresh RAS assert time = 3 cycle
! 329: * Disable burst, Bus size=32bit, Column Address=10bit, Refresh ON
! 330: * CAS before RAS refresh ON, EDO DRAM
! 331: */
! 332: _reg_write_4(SH4_MCR, BSC_MCR_VAL);
! 333:
! 334: #ifdef BSC_SDMR2_VAL
! 335: _reg_write_1(BSC_SDMR2_VAL, 0);
! 336: #endif
! 337:
! 338: #ifdef BSC_SDMR3_VAL
! 339: _reg_write_1(BSC_SDMR3_VAL, 0);
! 340: #endif /* BSC_SDMR3_VAL */
! 341:
! 342: /*
! 343: * PCMCIA Control Register
! 344: * OE/WE assert delay 3.5 cycle
! 345: * OE/WE negate-address delay 3.5 cycle
! 346: */
! 347: #ifdef BSC_PCR_VAL
! 348: _reg_write_2(SH4_PCR, BSC_PCR_VAL);
! 349: #endif
! 350:
! 351: /*
! 352: * Refresh Timer Control/Status Register
! 353: * Disable interrupt by CMF, closk 1/16, Disable OVF interrupt
! 354: * Count Limit = 1024
! 355: * In following statement, the reason why high byte = 0xa5(a4 in RFCR)
! 356: * is the rule of SH3 in writing these register.
! 357: */
! 358: _reg_write_2(SH4_RTCSR, BSC_RTCSR_VAL);
! 359:
! 360: /*
! 361: * Refresh Timer Counter
! 362: * Initialize to 0
! 363: */
! 364: #ifdef BSC_RTCNT_VAL
! 365: _reg_write_2(SH4_RTCNT, BSC_RTCNT_VAL);
! 366: #endif
! 367:
! 368: /* set Refresh Time Constant Register */
! 369: _reg_write_2(SH4_RTCOR, BSC_RTCOR_VAL);
! 370:
! 371: /* init Refresh Count Register */
! 372: #ifdef BSC_RFCR_VAL
! 373: _reg_write_2(SH4_RFCR, BSC_RFCR_VAL);
! 374: #endif
! 375:
! 376: /*
! 377: * Clock Pulse Generator
! 378: */
! 379: /* Set Clock mode (make internal clock double speed) */
! 380: _reg_write_2(SH4_FRQCR, FRQCR_VAL);
! 381: }
! 382: #endif /* !DONT_INIT_BSC */
! 383:
! 384: /*
! 385: * Dump the machine-dependent dump header.
! 386: */
! 387: u_int
! 388: cpu_dump(int (*dump)(dev_t, daddr64_t, caddr_t, size_t), daddr64_t *blknop)
! 389: {
! 390: extern cpu_kcore_hdr_t cpu_kcore_hdr;
! 391: char buf[dbtob(1)];
! 392: cpu_kcore_hdr_t *h;
! 393: kcore_seg_t *kseg;
! 394: int rc;
! 395:
! 396: #ifdef DIAGNOSTIC
! 397: if (cpu_dumpsize() > btodb(sizeof buf)) {
! 398: printf("buffer too small in cpu_dump, ");
! 399: return (EINVAL); /* "aborted" */
! 400: }
! 401: #endif
! 402:
! 403: bzero(buf, sizeof buf);
! 404: kseg = (kcore_seg_t *)buf;
! 405: h = (cpu_kcore_hdr_t *)(buf + ALIGN(sizeof(kcore_seg_t)));
! 406:
! 407: /* Create the segment header */
! 408: CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
! 409: kseg->c_size = dbtob(1) - ALIGN(sizeof(kcore_seg_t));
! 410:
! 411: bcopy(&cpu_kcore_hdr, h, sizeof(*h));
! 412: /* We can now fill kptp in the header... */
! 413: h->kcore_kptp = SH3_P1SEG_TO_PHYS((vaddr_t)pmap_kernel()->pm_ptp);
! 414:
! 415: rc = (*dump)(dumpdev, *blknop, buf, sizeof buf);
! 416: *blknop += btodb(sizeof buf);
! 417: return (rc);
! 418: }
! 419:
! 420: /*
! 421: * Return the size of the machine-dependent dump header, in disk blocks.
! 422: */
! 423: u_int
! 424: cpu_dumpsize()
! 425: {
! 426: u_int size;
! 427:
! 428: size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t));
! 429: return (btodb(roundup(size, dbtob(1))));
! 430: }
! 431:
! 432: /*
! 433: * Fill the machine-dependent dump header.
! 434: */
! 435: void
! 436: cpu_init_kcore_hdr()
! 437: {
! 438: extern cpu_kcore_hdr_t cpu_kcore_hdr;
! 439: cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
! 440: phys_ram_seg_t *seg = cpu_kcore_hdr.kcore_segs;
! 441: struct vm_physseg *physseg = vm_physmem;
! 442: u_int i;
! 443:
! 444: bzero(h, sizeof(*h));
! 445:
! 446: h->kcore_nsegs = min(NPHYS_RAM_SEGS, (u_int)vm_nphysseg);
! 447: for (i = h->kcore_nsegs; i != 0; i--) {
! 448: seg->start = ptoa(physseg->start);
! 449: seg->size = (psize_t)ptoa(physseg->end - physseg->start);
! 450: seg++;
! 451: physseg++;
! 452: }
! 453: }
! 454:
! 455: int
! 456: cpu_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
! 457: size_t newlen, struct proc *p)
! 458: {
! 459: int oldval, ret;
! 460:
! 461: /* all sysctl names at this level are terminal */
! 462: if (namelen != 1)
! 463: return (ENOTDIR); /* overloaded */
! 464:
! 465: switch (name[0]) {
! 466: case CPU_CONSDEV: {
! 467: dev_t consdev;
! 468: if (cn_tab != NULL)
! 469: consdev = cn_tab->cn_dev;
! 470: else
! 471: consdev = NODEV;
! 472: return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
! 473: sizeof consdev));
! 474: }
! 475:
! 476: case CPU_KBDRESET:
! 477: if (securelevel > 0)
! 478: return (sysctl_rdint(oldp, oldlenp, newp, kbd_reset));
! 479: return (sysctl_int(oldp, oldlenp, newp, newlen, &kbd_reset));
! 480:
! 481: case CPU_LED_BLINK:
! 482: oldval = led_blink;
! 483: ret = sysctl_int(oldp, oldlenp, newp, newlen, &led_blink);
! 484: if (oldval != led_blink)
! 485: blink_led(NULL);
! 486: return (ret);
! 487:
! 488: default:
! 489: return (EOPNOTSUPP);
! 490: }
! 491: /* NOTREACHED */
! 492: }
! 493:
! 494: void
! 495: blink_led(void *whatever)
! 496: {
! 497: static struct timeout blink_tmo;
! 498: u_int8_t ledctrl;
! 499:
! 500: if (led_blink == 0) {
! 501: _reg_write_1(LANDISK_LEDCTRL,
! 502: LED_POWER_CHANGE | LED_POWER_VALUE);
! 503: return;
! 504: }
! 505:
! 506: ledctrl = (u_int8_t)_reg_read_1(LANDISK_LEDCTRL) & LED_POWER_VALUE;
! 507: ledctrl ^= (LED_POWER_CHANGE | LED_POWER_VALUE);
! 508: _reg_write_1(LANDISK_LEDCTRL, ledctrl);
! 509:
! 510: timeout_set(&blink_tmo, blink_led, NULL);
! 511: timeout_add(&blink_tmo,
! 512: ((averunnable.ldavg[0] + FSCALE) * hz) >> FSHIFT);
! 513: }
CVSweb