Annotation of src/sys/arch/sh3/sh3/sh3_machdep.c, Revision 1.29
1.29 ! uch 1: /* $NetBSD: sh3_machdep.c,v 1.28 2002/02/28 16:54:32 uch Exp $ */
1.1 tsubai 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:
1.14 lukem 78: #include "opt_kgdb.h"
1.26 uch 79: #include "opt_memsize.h"
1.1 tsubai 80: #include "opt_compat_netbsd.h"
81:
82: #include <sys/param.h>
83: #include <sys/buf.h>
84: #include <sys/exec.h>
85: #include <sys/kernel.h>
86: #include <sys/malloc.h>
87: #include <sys/mbuf.h>
88: #include <sys/mount.h>
89: #include <sys/signalvar.h>
90: #include <sys/syscallargs.h>
91: #include <sys/systm.h>
92: #include <sys/user.h>
1.19 chs 93: #include <sys/proc.h>
1.1 tsubai 94:
95: #ifdef KGDB
96: #include <sys/kgdb.h>
97: #endif
1.7 mrg 98:
1.1 tsubai 99: #include <uvm/uvm_extern.h>
100:
1.29 ! uch 101: #include <sh3/trapreg.h>
1.22 uch 102: #include <sh3/cache.h>
1.24 uch 103: #include <sh3/mmu.h>
1.25 uch 104: #include <sh3/clock.h>
1.22 uch 105:
1.1 tsubai 106: char cpu_model[120];
1.20 uch 107:
108: /*
109: * if PCLOCK isn't defined in config file, use this.
110: */
1.24 uch 111: int cpu_arch;
112: int cpu_product;
1.6 thorpej 113:
114: /* Our exported CPU info; we can have only one. */
115: struct cpu_info cpu_info_store;
1.1 tsubai 116:
1.15 chs 117: struct vm_map *exec_map = NULL;
118: struct vm_map *mb_map = NULL;
119: struct vm_map *phys_map = NULL;
1.1 tsubai 120:
121: extern int physmem;
122:
1.26 uch 123: #ifndef IOM_RAM_BEGIN
124: #error "define IOM_RAM_BEGIN"
125: #endif
126: #define VBR (u_int8_t *)IOM_RAM_BEGIN
127: vaddr_t ram_start = IOM_RAM_BEGIN;
128: /* exception handler holder (sh3/sh3/exception_vector.S) */
129: extern char sh_vector_generic[], sh_vector_generic_end[];
130: extern char sh_vector_interrupt[], sh_vector_interrupt_end[];
131: extern char sh_vector_tlbmiss[], sh_vector_tlbmiss_end[];
132:
1.28 uch 133: /*
134: * These variables are needed by /sbin/savecore
135: */
136: u_long dumpmag = 0x8fca0101; /* magic number */
137: int dumpsize = 0; /* pages */
138: long dumplo = 0; /* blocks */
139:
1.1 tsubai 140: void
1.24 uch 141: sh_cpu_init(int arch, int product)
142: {
143: /* CPU type */
144: cpu_arch = arch;
145: cpu_product = product;
146:
1.27 uch 147: #if defined(SH3) && defined(SH4)
148: /* Set register addresses */
149: sh_devreg_init();
150: #endif
1.24 uch 151: /* Cache access ops. */
152: sh_cache_init();
153:
154: /* MMU access ops. */
155: sh_mmu_init();
1.25 uch 156:
157: /* Hardclock, RTC initialize. */
158: machine_clock_init();
1.26 uch 159:
160: /* Exception vector. */
161: memcpy(VBR + 0x100, sh_vector_generic,
162: sh_vector_generic_end - sh_vector_generic);
163: memcpy(VBR + 0x400, sh_vector_tlbmiss,
164: sh_vector_tlbmiss_end - sh_vector_tlbmiss);
165: memcpy(VBR + 0x600, sh_vector_interrupt,
166: sh_vector_interrupt_end - sh_vector_interrupt);
167: __asm__ __volatile__ ("ldc %0, vbr" :: "r"(VBR));
1.24 uch 168: }
169:
170: void
1.1 tsubai 171: sh3_startup()
172: {
173: unsigned i;
174: caddr_t v;
175: int sz;
176: int base, residual;
177: vaddr_t minaddr, maxaddr;
178: vsize_t size;
179: struct pcb *pcb;
180: char pbuf[9];
1.22 uch 181:
1.1 tsubai 182: printf(version);
1.26 uch 183:
184: /* Check exception vector size here. */
185: KDASSERT(sh_vector_generic_end - sh_vector_generic < 0x300);
186: KDASSERT(sh_vector_tlbmiss_end - sh_vector_tlbmiss < 0x200);
1.1 tsubai 187:
1.25 uch 188: #define MHZ(x) ((x) / 1000000), (((x) % 1000000) / 1000)
189: sprintf(cpu_model, "HITACHI SH%d %d.%02dMHz PCLOCK %d.%02d MHz",
190: CPU_IS_SH3 ? 3 : 4, MHZ(sh_clock_get_cpuclock()),
191: MHZ(sh_clock_get_pclock()));
192: #undef MHZ
1.1 tsubai 193:
194: format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
195: printf("total memory = %s\n", pbuf);
196:
197: /*
198: * Find out how much space we need, allocate it,
199: * and then give everything true virtual addresses.
200: */
201: sz = (int)allocsys(NULL, NULL);
202: if ((v = (caddr_t)uvm_km_zalloc(kernel_map, round_page(sz))) == 0)
203: panic("startup: no room for tables");
204: if (allocsys(v, NULL) - v != sz)
205: panic("startup: table size inconsistency");
206:
207: /*
208: * Now allocate buffers proper. They are different than the above
209: * in that they usually occupy more virtual memory than physical.
210: */
211: size = MAXBSIZE * nbuf;
212: buffers = 0;
213: if (uvm_map(kernel_map, (vaddr_t *) &buffers, round_page(size),
1.9 thorpej 214: NULL, UVM_UNKNOWN_OFFSET, 0,
1.1 tsubai 215: UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE,
1.11 chs 216: UVM_ADV_NORMAL, 0)) != 0)
1.17 msaitoh 217: panic("sh3_startup: cannot allocate VM for buffers");
1.1 tsubai 218: minaddr = (vaddr_t)buffers;
219: if ((bufpages / nbuf) >= btoc(MAXBSIZE)) {
220: /* don't want to alloc more physical mem than needed */
221: bufpages = btoc(MAXBSIZE) * nbuf;
222: }
223:
224: base = bufpages / nbuf;
225: residual = bufpages % nbuf;
226: for (i = 0; i < nbuf; i++) {
227: vsize_t curbufsize;
228: vaddr_t curbuf;
229: struct vm_page *pg;
230:
231: /*
232: * Each buffer has MAXBSIZE bytes of VM space allocated. Of
233: * that MAXBSIZE space, we allocate and map (base+1) pages
234: * for the first "residual" buffers, and then we allocate
235: * "base" pages for the rest.
236: */
237: curbuf = (vaddr_t) buffers + (i * MAXBSIZE);
1.2 ragge 238: curbufsize = NBPG * ((i < residual) ? (base+1) : base);
1.1 tsubai 239:
240: while (curbufsize) {
241: pg = uvm_pagealloc(NULL, 0, NULL, 0);
242: if (pg == NULL)
1.17 msaitoh 243: panic("sh3_startup: not enough memory for "
1.1 tsubai 244: "buffer cache");
245: pmap_kenter_pa(curbuf, VM_PAGE_TO_PHYS(pg),
246: VM_PROT_READ|VM_PROT_WRITE);
247: curbuf += PAGE_SIZE;
248: curbufsize -= PAGE_SIZE;
249: }
250: }
1.18 chris 251: pmap_update(pmap_kernel());
1.1 tsubai 252:
253: /*
254: * Allocate a submap for exec arguments. This map effectively
255: * limits the number of processes exec'ing at any time.
256: */
257: exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
1.5 tsubai 258: 16*NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
1.1 tsubai 259:
260: /*
261: * Allocate a submap for physio
262: */
263: phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
1.5 tsubai 264: VM_PHYS_SIZE, 0, FALSE, NULL);
1.1 tsubai 265:
266: format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free));
267: printf("avail memory = %s\n", pbuf);
1.2 ragge 268: format_bytes(pbuf, sizeof(pbuf), bufpages * NBPG);
1.1 tsubai 269: printf("using %d buffers containing %s of memory\n", nbuf, pbuf);
270:
1.22 uch 271: /*
272: * Print cache configuration.
273: */
274: sh_cache_information();
1.25 uch 275: /*
276: * Print MMU configuration.
277: */
278: sh_mmu_information();
1.22 uch 279:
1.1 tsubai 280: /*
281: * Set up buffers, so they can be used to read disk labels.
282: */
283: bufinit();
284:
285: curpcb = pcb = &proc0.p_addr->u_pcb;
286: pcb->r15 = (int)proc0.p_addr + USPACE - 16;
287:
288: proc0.p_md.md_regs = (struct trapframe *)pcb->r15 - 1;
289: }
290:
291: /*
1.28 uch 292: * This is called by main to set dumplo and dumpsize.
293: * Dumps always skip the first CLBYTES of disk space
294: * in case there might be a disk label stored there.
295: * If there is extra space, put dump at the end to
296: * reduce the chance that swapping trashes it.
297: */
298: void
299: cpu_dumpconf()
300: {
301: }
302:
303: /*
304: * Doadump comes here after turning off memory management and
305: * getting on the dump stack, either when called above, or by
306: * the auto-restart code.
307: */
308: #define BYTES_PER_DUMP NBPG /* must be a multiple of pagesize XXX small */
309: static vaddr_t dumpspace;
310:
311: vaddr_t
312: reserve_dumppages(p)
313: vaddr_t p;
314: {
315:
316: dumpspace = p;
317: return (p + BYTES_PER_DUMP);
318: }
319:
320: void
321: dumpsys()
322: {
323: }
324:
325: /*
1.1 tsubai 326: * Send an interrupt to process.
327: *
328: * Stack is set up to allow sigcode stored
329: * in u. to call routine, followed by kcall
330: * to sigreturn routine below. After sigreturn
331: * resets the signal mask, the stack, and the
332: * frame pointer, it returns to the user
333: * specified pc, psl.
334: */
335: void
1.23 uch 336: sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
1.1 tsubai 337: {
338: struct proc *p = curproc;
339: struct trapframe *tf;
340: struct sigframe *fp, frame;
341: int onstack;
342:
343: tf = p->p_md.md_regs;
344:
345: /* Do we need to jump onto the signal stack? */
346: onstack =
1.10 jdolecek 347: (p->p_sigctx.ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
348: (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
1.1 tsubai 349:
350: /* Allocate space for the signal handler context. */
351: if (onstack)
1.10 jdolecek 352: fp = (struct sigframe *)((caddr_t)p->p_sigctx.ps_sigstk.ss_sp +
353: p->p_sigctx.ps_sigstk.ss_size);
1.1 tsubai 354: else
355: fp = (struct sigframe *)tf->tf_r15;
356: fp--;
357:
358: /* Build stack frame for signal trampoline. */
359: frame.sf_signum = sig;
360: frame.sf_code = code;
361: frame.sf_scp = &fp->sf_sc;
362: frame.sf_handler = catcher;
363:
364: /* Save register context. */
365: frame.sf_sc.sc_ssr = tf->tf_ssr;
366: frame.sf_sc.sc_spc = tf->tf_spc;
367: frame.sf_sc.sc_pr = tf->tf_pr;
368: frame.sf_sc.sc_r15 = tf->tf_r15;
369: frame.sf_sc.sc_r14 = tf->tf_r14;
370: frame.sf_sc.sc_r13 = tf->tf_r13;
371: frame.sf_sc.sc_r12 = tf->tf_r12;
372: frame.sf_sc.sc_r11 = tf->tf_r11;
373: frame.sf_sc.sc_r10 = tf->tf_r10;
374: frame.sf_sc.sc_r9 = tf->tf_r9;
375: frame.sf_sc.sc_r8 = tf->tf_r8;
376: frame.sf_sc.sc_r7 = tf->tf_r7;
377: frame.sf_sc.sc_r6 = tf->tf_r6;
378: frame.sf_sc.sc_r5 = tf->tf_r5;
379: frame.sf_sc.sc_r4 = tf->tf_r4;
380: frame.sf_sc.sc_r3 = tf->tf_r3;
381: frame.sf_sc.sc_r2 = tf->tf_r2;
382: frame.sf_sc.sc_r1 = tf->tf_r1;
383: frame.sf_sc.sc_r0 = tf->tf_r0;
384: frame.sf_sc.sc_trapno = tf->tf_trapno;
385: #ifdef TODO
386: frame.sf_sc.sc_err = tf->tf_err;
387: #endif
388:
389: /* Save signal stack. */
1.10 jdolecek 390: frame.sf_sc.sc_onstack = p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK;
1.1 tsubai 391:
392: /* Save signal mask. */
393: frame.sf_sc.sc_mask = *mask;
394:
395: #ifdef COMPAT_13
396: /*
397: * XXX We always have to save an old style signal mask because
398: * XXX we might be delivering a signal to a process which will
399: * XXX escape from the signal in a non-standard way and invoke
400: * XXX sigreturn() directly.
401: */
402: native_sigset_to_sigset13(mask, &frame.sf_sc.__sc_mask13);
403: #endif
404:
405: if (copyout(&frame, fp, sizeof(frame)) != 0) {
406: /*
407: * Process has trashed its stack; give it an illegal
408: * instruction to halt it in its tracks.
409: */
410: sigexit(p, SIGILL);
411: /* NOTREACHED */
412: }
413:
414: /*
415: * Build context to run handler in.
416: */
1.10 jdolecek 417: tf->tf_spc = (int)p->p_sigctx.ps_sigcode;
1.1 tsubai 418: #ifdef TODO
419: tf->tf_ssr &= ~(PSL_T|PSL_VM|PSL_AC);
420: #endif
421: tf->tf_r15 = (int)fp;
422:
423: /* Remember that we're now on the signal stack. */
424: if (onstack)
1.10 jdolecek 425: p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
1.1 tsubai 426: }
427:
428: /*
429: * System call to cleanup state after a signal
430: * has been taken. Reset signal mask and
431: * stack state from context left by sendsig (above).
432: * Return to previous pc and psl as specified by
433: * context left by sendsig. Check carefully to
434: * make sure that the user has not modified the
435: * psl to gain improper privileges or to cause
436: * a machine fault.
437: */
438: int
1.23 uch 439: sys___sigreturn14(struct proc *p, void *v, register_t *retval)
1.1 tsubai 440: {
441: struct sys___sigreturn14_args /* {
442: syscallarg(struct sigcontext *) sigcntxp;
443: } */ *uap = v;
444: struct sigcontext *scp, context;
445: struct trapframe *tf;
446:
447: /*
448: * The trampoline code hands us the context.
449: * It is unsafe to keep track of it ourselves, in the event that a
450: * program jumps out of a signal handler.
451: */
452: scp = SCARG(uap, sigcntxp);
453: if (copyin((caddr_t)scp, &context, sizeof(*scp)) != 0)
454: return (EFAULT);
455:
456: /* Restore signal context. */
457: tf = p->p_md.md_regs;
458:
1.13 msaitoh 459: /* Check for security violations. */
460: if (((context.sc_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0)
461: return (EINVAL);
462:
463: tf->tf_ssr = context.sc_ssr;
464:
1.1 tsubai 465: tf->tf_r0 = context.sc_r0;
466: tf->tf_r1 = context.sc_r1;
467: tf->tf_r2 = context.sc_r2;
468: tf->tf_r3 = context.sc_r3;
469: tf->tf_r4 = context.sc_r4;
470: tf->tf_r5 = context.sc_r5;
471: tf->tf_r6 = context.sc_r6;
472: tf->tf_r7 = context.sc_r7;
473: tf->tf_r8 = context.sc_r8;
474: tf->tf_r9 = context.sc_r9;
475: tf->tf_r10 = context.sc_r10;
476: tf->tf_r11 = context.sc_r11;
477: tf->tf_r12 = context.sc_r12;
478: tf->tf_r13 = context.sc_r13;
479: tf->tf_r14 = context.sc_r14;
480: tf->tf_spc = context.sc_spc;
481: tf->tf_r15 = context.sc_r15;
482: tf->tf_pr = context.sc_pr;
483:
484: /* Restore signal stack. */
485: if (context.sc_onstack & SS_ONSTACK)
1.10 jdolecek 486: p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
1.1 tsubai 487: else
1.10 jdolecek 488: p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK;
1.1 tsubai 489: /* Restore signal mask. */
490: (void) sigprocmask1(p, SIG_SETMASK, &context.sc_mask, 0);
491:
492: return (EJUSTRETURN);
493: }
494:
495: /*
496: * Clear registers on exec
497: */
498: void
1.23 uch 499: setregs(struct proc *p, struct exec_package *pack, u_long stack)
1.1 tsubai 500: {
501: register struct pcb *pcb = &p->p_addr->u_pcb;
502: register struct trapframe *tf;
503:
504: p->p_md.md_flags &= ~MDP_USEDFPU;
505: pcb->pcb_flags = 0;
506:
507: tf = p->p_md.md_regs;
508:
509: tf->tf_r0 = 0;
510: tf->tf_r1 = 0;
511: tf->tf_r2 = 0;
512: tf->tf_r3 = 0;
513: tf->tf_r4 = *(int *)stack; /* argc */
514: tf->tf_r5 = stack+4; /* argv */
515: tf->tf_r6 = stack+4*tf->tf_r4 + 8; /* envp */
516: tf->tf_r7 = 0;
517: tf->tf_r8 = 0;
1.21 thorpej 518: tf->tf_r9 = (int)PS_STRINGS;
1.1 tsubai 519: tf->tf_r10 = 0;
520: tf->tf_r11 = 0;
521: tf->tf_r12 = 0;
522: tf->tf_r13 = 0;
523: tf->tf_r14 = 0;
524: tf->tf_spc = pack->ep_entry;
525: tf->tf_ssr = PSL_USERSET;
526: tf->tf_r15 = stack;
1.28 uch 527: }
528:
529: /*
530: * Jump to reset vector.
531: */
532: void
533: cpu_reset()
534: {
535:
536: _cpu_exception_suspend();
1.29 ! uch 537: _reg_write_4(SH_(EXPEVT), 0x020); /* manual reset */
1.28 uch 538:
539: goto *(u_int32_t *)0xa0000000;
1.29 ! uch 540: /* NOTREACHED */
! 541: while (1)
1.28 uch 542: ;
1.1 tsubai 543: }
CVSweb <webmaster@jp.NetBSD.org>