Annotation of sys/arch/landisk/landisk/machdep.c, Revision 1.1.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