Annotation of sys/arch/mvme68k/mvme68k/hpux_machdep.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: hpux_machdep.c,v 1.14 2005/11/06 17:23:41 miod Exp $ */
2: /* $NetBSD: hpux_machdep.c,v 1.9 1997/03/16 10:00:45 thorpej Exp $ */
3:
4: /*
5: * Copyright (c) 1995, 1996, 1997 Jason R. Thorpe. All rights reserved.
6: * Copyright (c) 1988 University of Utah.
7: * Copyright (c) 1990, 1993
8: * The Regents of the University of California. All rights reserved.
9: *
10: * This code is derived from software contributed to Berkeley by
11: * the Systems Programming Group of the University of Utah Computer
12: * Science Department.
13: *
14: * Redistribution and use in source and binary forms, with or without
15: * modification, are permitted provided that the following conditions
16: * are met:
17: * 1. Redistributions of source code must retain the above copyright
18: * notice, this list of conditions and the following disclaimer.
19: * 2. Redistributions in binary form must reproduce the above copyright
20: * notice, this list of conditions and the following disclaimer in the
21: * documentation and/or other materials provided with the distribution.
22: * 3. The name of the author may not be used to endorse or promote products
23: * derived from this software without specific prior written permission.
24: *
25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35: * SUCH DAMAGE.
36: */
37:
38: /*
39: * Machine-dependent bits for HP-UX binary compatibility.
40: */
41:
42: #include <sys/param.h>
43: #include <sys/systm.h>
44: #include <sys/signalvar.h>
45: #include <sys/kernel.h>
46: #include <sys/filedesc.h>
47: #include <sys/proc.h>
48: #include <sys/buf.h>
49: #include <sys/wait.h>
50: #include <sys/file.h>
51: #include <sys/exec.h>
52: #include <sys/namei.h>
53: #include <sys/vnode.h>
54: #include <sys/ioctl.h>
55: #include <sys/ptrace.h>
56: #include <sys/stat.h>
57: #include <sys/syslog.h>
58: #include <sys/malloc.h>
59: #include <sys/mount.h>
60: #include <sys/ipc.h>
61: #include <sys/namei.h>
62: #include <sys/user.h>
63: #include <sys/mman.h>
64: #include <sys/conf.h>
65:
66: #include <machine/cpu.h>
67: #include <machine/reg.h>
68: #include <machine/psl.h>
69: #include <machine/vmparam.h>
70:
71: #include <uvm/uvm_extern.h>
72:
73: #include <machine/reg.h>
74:
75: #include <sys/syscallargs.h>
76:
77: #include <compat/hpux/hpux.h>
78: #include <compat/hpux/hpux_sig.h>
79: #include <compat/hpux/hpux_util.h>
80: #include <compat/hpux/hpux_syscall.h>
81: #include <compat/hpux/hpux_syscallargs.h>
82:
83: #include <machine/hpux_machdep.h>
84:
85: extern short exframesize[];
86:
87: struct valtostr {
88: int val;
89: const char *str;
90: };
91:
92: static struct valtostr machine_table[] = {
93: /* We approximate based on cputype. */
94: { CPU_68020, "350" }, /* 68020 == 350. */
95: { CPU_68030, "370" }, /* 68030 == 370. */
96: { CPU_68040, "380" }, /* 68040 == 380. */
97: { -1, "3?0" }, /* unknown system (???) */
98: };
99:
100: /*
101: * 6.0 and later context.
102: * XXX what are the HP-UX "localroot" semantics? Should we handle
103: * XXX diskless systems here?
104: */
105: static struct valtostr context_table[] = {
106: { FPU_68040,
107: "standalone HP-MC68040 HP-MC68881 HP-MC68020 HP-MC68010 localroot default"
108: },
109: { FPU_68881,
110: "standalone HP-MC68881 HP-MC68020 HP-MC68010 localroot default"
111: },
112: { FPU_NONE,
113: "standalone HP-MC68020 HP-MC68010 localroot default"
114: },
115: { 0, NULL },
116: };
117:
118: #define UOFF(f) ((int)&((struct user *)0)->f)
119: #define HPUOFF(f) ((int)&((struct hpux_user *)0)->f)
120:
121: /* simplified FP structure */
122: struct bsdfp {
123: int save[54];
124: int reg[24];
125: int ctrl[3];
126: };
127:
128: /*
129: * m68k-specific setup for HP-UX executables.
130: * XXX m68k/m68k/hpux_machdep.c?
131: */
132: int
133: hpux_cpu_makecmds(p, epp)
134: struct proc *p;
135: struct exec_package *epp;
136: {
137: /* struct hpux_exec *hpux_ep = epp->ep_hdr; */
138:
139: /* set up command for exec header */
140: NEW_VMCMD(&epp->ep_vmcmds, hpux_cpu_vmcmd,
141: sizeof(struct hpux_exec), (long)epp->ep_hdr, NULLVP, 0, 0);
142: return (0);
143: }
144:
145: /*
146: * We need to stash the exec header in the pcb, so we define
147: * this vmcmd to do it for us, since vmcmds are executed once
148: * we're committed to the exec (i.e. the old program has been unmapped).
149: *
150: * The address of the header is in ev->ev_addr and the length is
151: * in ev->ev_len.
152: */
153: int
154: hpux_cpu_vmcmd(p, ev)
155: struct proc *p;
156: struct exec_vmcmd *ev;
157: {
158: struct hpux_exec *execp = (struct hpux_exec *)ev->ev_addr;
159:
160: /* Make sure we have room. */
161: if (ev->ev_len <= sizeof(p->p_addr->u_md.md_exec))
162: bcopy((caddr_t)ev->ev_addr, p->p_addr->u_md.md_exec,
163: ev->ev_len);
164:
165: /* Deal with misc. HP-UX process attributes. */
166: if (execp->ha_trsize & HPUXM_VALID) {
167: if (execp->ha_trsize & HPUXM_DATAWT)
168: p->p_md.md_flags &= ~MDP_CCBDATA;
169:
170: if (execp->ha_trsize & HPUXM_STKWT)
171: p->p_md.md_flags &= ~MDP_CCBSTACK;
172: }
173:
174: return (0);
175: }
176:
177: /*
178: * Machine-dependent stat structure conversion.
179: */
180: void
181: hpux_cpu_bsd_to_hpux_stat(sb, hsb)
182: struct stat *sb;
183: struct hpux_stat *hsb;
184: {
185: }
186:
187: /*
188: * Machine-dependent uname information.
189: */
190: void
191: hpux_cpu_uname(ut)
192: struct hpux_utsname *ut;
193: {
194: int i;
195:
196: bzero(ut->machine, sizeof(ut->machine));
197:
198: /*
199: * Find the current machine-ID in the table and
200: * copy the string into the uname.
201: */
202: for (i = 0; machine_table[i].val != -1; ++i)
203: if (machine_table[i].val == cputype)
204: break;
205:
206: snprintf(ut->machine, sizeof ut->machine, "9000/%s",
207: machine_table[i].str);
208: }
209:
210: /*
211: * Return arch-type for hpux_sys_sysconf()
212: */
213: int
214: hpux_cpu_sysconf_arch()
215: {
216:
217: switch (cputype) {
218: case CPU_68020:
219: return (HPUX_SYSCONF_CPUM020);
220:
221: case CPU_68030:
222: return (HPUX_SYSCONF_CPUM030);
223:
224: case CPU_68040:
225: return (HPUX_SYSCONF_CPUM040);
226:
227: default:
228: return (HPUX_SYSCONF_CPUM020); /* ??? */
229: }
230: /* NOTREACHED */
231: }
232:
233: /*
234: * HP-UX advise(2) system call.
235: */
236: int
237: hpux_sys_advise(p, v, retval)
238: struct proc *p;
239: void *v;
240: register_t *retval;
241: {
242: struct hpux_sys_advise_args *uap = v;
243: int error = 0;
244:
245: switch (SCARG(uap, arg)) {
246: case 0:
247: p->p_md.md_flags |= MDP_HPUXMMAP;
248: break;
249:
250: case 1:
251: ICIA();
252: break;
253:
254: case 2:
255: DCIA();
256: break;
257:
258: default:
259: error = EINVAL;
260: break;
261: }
262:
263: return (error);
264: }
265:
266: /*
267: * HP-UX getcontext(2) system call.
268: * Man page lies, behaviour here is based on observed behaviour.
269: */
270: int
271: hpux_sys_getcontext(p, v, retval)
272: struct proc *p;
273: void *v;
274: register_t *retval;
275: {
276: struct hpux_sys_getcontext_args *uap = v;
277: int l, i, error = 0;
278: register int len;
279:
280: for (i = 0; context_table[i].str != NULL; i++)
281: if (context_table[i].val == fputype)
282: break;
283: if (context_table[i].str == NULL) {
284: /*
285: * XXX What else? It's not like this can happen...
286: */
287: return (EINVAL);
288: }
289:
290: /* + 1 ... count the terminating \0. */
291: l = strlen(context_table[i].str) + 1;
292: len = min(SCARG(uap, len), l);
293:
294: if (len)
295: error = copyout(context_table[i].str, SCARG(uap, buf), len);
296: if (error == 0)
297: *retval = l;
298: return (0);
299: }
300:
301: /*
302: * Brutal hack! Map HP-UX u-area offsets into BSD k-stack offsets.
303: * XXX This probably doesn't work anymore, BTW. --thorpej
304: */
305: int
306: hpux_to_bsd_uoff(off, isps, p)
307: int *off, *isps;
308: struct proc *p;
309: {
310: register int *ar0 = p->p_md.md_regs;
311: struct hpux_fp *hp;
312: struct bsdfp *bp;
313: register u_int raddr;
314:
315: *isps = 0;
316:
317: /* u_ar0 field; procxmt puts in U_ar0 */
318: if ((int)off == HPUOFF(hpuxu_ar0))
319: return(UOFF(U_ar0));
320:
321: if (fputype) {
322: /* FP registers from PCB */
323: hp = (struct hpux_fp *)HPUOFF(hpuxu_fp);
324: bp = (struct bsdfp *)UOFF(u_pcb.pcb_fpregs);
325:
326: if (off >= hp->hpfp_ctrl && off < &hp->hpfp_ctrl[3])
327: return((int)&bp->ctrl[off - hp->hpfp_ctrl]);
328:
329: if (off >= hp->hpfp_reg && off < &hp->hpfp_reg[24])
330: return((int)&bp->reg[off - hp->hpfp_reg]);
331: }
332:
333: /*
334: * Everything else we recognize comes from the kernel stack,
335: * so we convert off to an absolute address (if not already)
336: * for simplicity.
337: */
338: if (off < (int *)ctob(UPAGES))
339: off = (int *)((u_int)off + (u_int)p->p_addr); /* XXX */
340:
341: /*
342: * General registers.
343: * We know that the HP-UX registers are in the same order as ours.
344: * The only difference is that their PS is 2 bytes instead of a
345: * padded 4 like ours throwing the alignment off.
346: */
347: if (off >= ar0 && off < &ar0[18]) {
348: /*
349: * PS: return low word and high word of PC as HP-UX would
350: * (e.g. &u.u_ar0[16.5]).
351: *
352: * XXX we don't do this since HP-UX adb doesn't rely on
353: * it and passing such an offset to procxmt will cause
354: * it to fail anyway. Instead, we just set the offset
355: * to PS and let hpux_ptrace() shift up the value returned.
356: */
357: if (off == &ar0[PS]) {
358: #if 0
359: raddr = (u_int) &((short *)ar0)[PS*2+1];
360: #else
361: raddr = (u_int) &ar0[(int)(off - ar0)];
362: #endif
363: *isps = 1;
364: }
365: /*
366: * PC: off will be &u.u_ar0[16.5] since HP-UX saved PS
367: * is only 16 bits.
368: */
369: else if (off == (int *)&(((short *)ar0)[PS*2+1]))
370: raddr = (u_int) &ar0[PC];
371: /*
372: * D0-D7, A0-A7: easy
373: */
374: else
375: raddr = (u_int) &ar0[(int)(off - ar0)];
376: return((int)(raddr - (u_int)p->p_addr)); /* XXX */
377: }
378:
379: /* everything else */
380: return (-1);
381: }
382:
383: #define HSS_RTEFRAME 0x01
384: #define HSS_FPSTATE 0x02
385: #define HSS_USERREGS 0x04
386:
387: struct hpuxsigstate {
388: int hss_flags; /* which of the following are valid */
389: struct frame hss_frame; /* original exception frame */
390: struct fpframe hss_fpstate; /* 68881/68882 state info */
391: };
392:
393: /*
394: * WARNING: code in locore.s assumes the layout shown here for hsf_signum
395: * thru hsf_handler so... don't screw with them!
396: */
397: struct hpuxsigframe {
398: int hsf_signum; /* signo for handler */
399: int hsf_code; /* additional info for handler */
400: struct hpuxsigcontext *hsf_scp; /* context ptr for handler */
401: sig_t hsf_handler; /* handler addr for u_sigc */
402: struct hpuxsigstate hsf_sigstate; /* state of the hardware */
403: struct hpuxsigcontext hsf_sc; /* actual context */
404: };
405:
406: #ifdef DEBUG
407: int hpuxsigdebug = 0;
408: int hpuxsigpid = 0;
409: #define SDB_FOLLOW 0x01
410: #define SDB_KSTACK 0x02
411: #define SDB_FPSTATE 0x04
412: #endif
413:
414: /*
415: * Send an interrupt to process.
416: */
417: /* ARGSUSED */
418: void
419: hpux_sendsig(catcher, sig, mask, code, type, val)
420: sig_t catcher;
421: int sig, mask;
422: u_long code;
423: int type;
424: union sigval val;
425: {
426: register struct proc *p = curproc;
427: register struct hpuxsigframe *kfp, *fp;
428: register struct frame *frame;
429: register struct sigacts *psp = p->p_sigacts;
430: register short ft;
431: int oonstack, fsize;
432:
433: frame = (struct frame *)p->p_md.md_regs;
434: ft = frame->f_format;
435: oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
436:
437: /*
438: * Allocate and validate space for the signal handler
439: * context. Note that if the stack is in P0 space, the
440: * call to grow() is a nop, and the useracc() check
441: * will fail if the process has not already allocated
442: * the space with a `brk'.
443: */
444: fsize = sizeof(struct hpuxsigframe);
445: if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
446: (psp->ps_sigonstack & sigmask(sig))) {
447: fp = (struct hpuxsigframe *)(psp->ps_sigstk.ss_sp +
448: psp->ps_sigstk.ss_size - fsize);
449: psp->ps_sigstk.ss_flags |= SS_ONSTACK;
450: } else
451: fp = (struct hpuxsigframe *)(frame->f_regs[SP] - fsize);
452: if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
453: (void)uvm_grow(p, (unsigned)fp);
454:
455: #ifdef DEBUG
456: if ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid)
457: printf("hpux_sendsig(%d): sig %d ssp %x usp %x scp %x ft %d\n",
458: p->p_pid, sig, &oonstack, fp, &fp->sf_sc, ft);
459: #endif
460:
461: kfp = (struct hpuxsigframe *)malloc((u_long)fsize, M_TEMP, M_WAITOK);
462:
463: /*
464: * Build the argument list for the signal handler.
465: */
466: kfp->hsf_signum = bsdtohpuxsig(sig);
467: kfp->hsf_code = code;
468: kfp->hsf_scp = &fp->hsf_sc;
469: kfp->hsf_handler = catcher;
470:
471: /*
472: * Save necessary hardware state. Currently this includes:
473: * - general registers
474: * - original exception frame (if not a "normal" frame)
475: * - FP coprocessor state
476: */
477: kfp->hsf_sigstate.hss_flags = HSS_USERREGS;
478: bcopy((caddr_t)frame->f_regs,
479: (caddr_t)kfp->hsf_sigstate.hss_frame.f_regs, sizeof frame->f_regs);
480: if (ft >= FMT7) {
481: #ifdef DEBUG
482: if (ft > 15 || exframesize[ft] < 0)
483: panic("hpux_sendsig: bogus frame type");
484: #endif
485: kfp->hsf_sigstate.hss_flags |= HSS_RTEFRAME;
486: kfp->hsf_sigstate.hss_frame.f_format = frame->f_format;
487: kfp->hsf_sigstate.hss_frame.f_vector = frame->f_vector;
488: bcopy((caddr_t)&frame->F_u,
489: (caddr_t)&kfp->hsf_sigstate.hss_frame.F_u, exframesize[ft]);
490:
491: /*
492: * Leave an indicator that we need to clean up the kernel
493: * stack. We do this by setting the "pad word" above the
494: * hardware stack frame to the amount the stack must be
495: * adjusted by.
496: *
497: * N.B. we increment rather than just set f_stackadj in
498: * case we are called from syscall when processing a
499: * sigreturn. In that case, f_stackadj may be non-zero.
500: */
501: frame->f_stackadj += exframesize[ft];
502: frame->f_format = frame->f_vector = 0;
503: #ifdef DEBUG
504: if (hpuxsigdebug & SDB_FOLLOW)
505: printf("hpux_sendsig(%d): copy out %d of frame %d\n",
506: p->p_pid, exframesize[ft], ft);
507: #endif
508: }
509: if (fputype) {
510: kfp->hsf_sigstate.hss_flags |= HSS_FPSTATE;
511: m68881_save(&kfp->hsf_sigstate.hss_fpstate);
512: }
513:
514: #ifdef DEBUG
515: if ((hpuxsigdebug & SDB_FPSTATE) && *(char *)&kfp->sf_state.ss_fpstate)
516: printf("hpux_sendsig(%d): copy out FP state (%x) to %x\n",
517: p->p_pid, *(u_int *)&kfp->sf_state.ss_fpstate,
518: &kfp->sf_state.ss_fpstate);
519: #endif
520:
521: /*
522: * Build the signal context to be used by hpux_sigreturn.
523: */
524: kfp->hsf_sc.hsc_syscall = 0; /* XXX */
525: kfp->hsf_sc.hsc_action = 0; /* XXX */
526: kfp->hsf_sc.hsc_pad1 = kfp->hsf_sc.hsc_pad2 = 0;
527: kfp->hsf_sc.hsc_onstack = oonstack;
528: kfp->hsf_sc.hsc_mask = mask;
529: kfp->hsf_sc.hsc_sp = frame->f_regs[SP];
530: kfp->hsf_sc.hsc_ps = frame->f_sr;
531: kfp->hsf_sc.hsc_pc = frame->f_pc;
532:
533: /* How amazingly convenient! */
534: kfp->hsf_sc._hsc_pad = 0;
535: kfp->hsf_sc._hsc_ap = (int)&fp->hsf_sigstate;
536:
537: if (copyout((caddr_t)kfp, (caddr_t)fp, fsize) != 0) {
538: #ifdef DEBUG
539: if ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid)
540: printf("hpux_sendsig(%d): copyout failed on sig %d\n",
541: p->p_pid, sig);
542: #endif
543: /*
544: * Process has trashed its stack; give it an illegal
545: * instruction to halt it in its tracks.
546: */
547: free((caddr_t)kfp, M_TEMP);
548: sigexit(p, SIGILL);
549: /* NOTREACHED */
550: }
551: frame->f_regs[SP] = (int)fp;
552:
553: #ifdef DEBUG
554: if (hpuxsigdebug & SDB_FOLLOW) {
555: printf(
556: "hpux_sendsig(%d): sig %d scp %x fp %x sc_sp %x sc_ap %x\n",
557: p->p_pid, sig, kfp->sf_scp, fp,
558: kfp->sf_sc.sc_sp, kfp->sf_sc.sc_ap);
559: }
560: #endif
561:
562: /*
563: * Signal trampoline code is at base of user stack.
564: */
565: frame->f_pc = p->p_sigcode;
566: #ifdef DEBUG
567: if ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid)
568: printf("hpux_sendsig(%d): sig %d returns\n",
569: p->p_pid, sig);
570: #endif
571: free((caddr_t)kfp, M_TEMP);
572: }
573:
574: /*
575: * System call to cleanup state after a signal
576: * has been taken. Reset signal mask and
577: * stack state from context left by sendsig (above).
578: * Return to previous pc and psl as specified by
579: * context left by sendsig. Check carefully to
580: * make sure that the user has not modified the
581: * psl to gain improper privileges or to cause
582: * a machine fault.
583: */
584: /* ARGSUSED */
585: int
586: hpux_sys_sigreturn(p, v, retval)
587: struct proc *p;
588: void *v;
589: register_t *retval;
590: {
591: struct hpux_sys_sigreturn_args /* {
592: syscallarg(struct hpuxsigcontext *) sigcntxp;
593: } */ *uap = v;
594: register struct hpuxsigcontext *scp;
595: register struct frame *frame;
596: register int rf;
597: struct hpuxsigcontext tsigc;
598: struct hpuxsigstate tstate;
599: int flags;
600:
601: scp = SCARG(uap, sigcntxp);
602: #ifdef DEBUG
603: if (hpuxsigdebug & SDB_FOLLOW)
604: printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp);
605: #endif
606: if ((int)scp & 1)
607: return (EINVAL);
608:
609: /*
610: * Fetch and test the HP-UX context structure.
611: * We grab it all at once for speed.
612: */
613: if (copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc))
614: return (EINVAL);
615: scp = &tsigc;
616: if ((scp->hsc_ps & PSL_USERCLR) != 0 ||
617: (scp->hsc_ps & PSL_USERSET) != PSL_USERSET)
618: return (EINVAL);
619:
620: /*
621: * Restore the user supplied information
622: */
623: if (scp->hsc_onstack & 01)
624: p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
625: else
626: p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
627: p->p_sigmask = scp->hsc_mask &~ sigcantmask;
628: frame = (struct frame *) p->p_md.md_regs;
629: frame->f_regs[SP] = scp->hsc_sp;
630: frame->f_pc = scp->hsc_pc;
631: frame->f_sr = scp->hsc_ps;
632:
633: /*
634: * Grab a pointer to the hpuxsigstate.
635: * If zero, the user is probably doing a longjmp.
636: * (This will never happen, really, since HP-UX doesn't
637: * know/care about the state pointer.)
638: */
639: if ((rf = scp->_hsc_ap) == 0)
640: return (EJUSTRETURN);
641:
642: /*
643: * See if there is anything to do before we go to the
644: * expense of copying in close to 1/2K of data
645: */
646: if (copyin((caddr_t)rf, &flags, sizeof(int)) != 0)
647: return (EINVAL);
648: #ifdef DEBUG
649: if (hpuxsigdebug & SDB_FOLLOW)
650: printf("sigreturn(%d): sc_ap %x flags %x\n",
651: p->p_pid, rf, flags);
652: #endif
653: if (flags == 0 || copyin((caddr_t)rf, (caddr_t)&tstate, sizeof tstate))
654: return (EJUSTRETURN);
655: #ifdef DEBUG
656: if ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid)
657: printf("sigreturn(%d): ssp %x usp %x scp %x ft %d\n",
658: p->p_pid, &flags, scp->sc_sp, SCARG(uap, sigcntxp),
659: (flags & HSS_RTEFRAME) ? tstate.ss_frame.f_format : -1);
660: #endif
661: /*
662: * Restore most of the users registers except for A6 and SP
663: * which were handled above.
664: */
665: if (flags & HSS_USERREGS)
666: bcopy((caddr_t)tstate.hss_frame.f_regs,
667: (caddr_t)frame->f_regs, sizeof(frame->f_regs)-2*NBPW);
668:
669: /*
670: * Restore long stack frames. Note that we do not copy
671: * back the saved SR or PC, they were picked up above from
672: * the sigcontext structure.
673: */
674: if (flags & HSS_RTEFRAME) {
675: register int sz;
676:
677: /* grab frame type and validate */
678: sz = tstate.hss_frame.f_format;
679: if (sz > 15 || (sz = exframesize[sz]) < 0)
680: return (EINVAL);
681: frame->f_stackadj -= sz;
682: frame->f_format = tstate.hss_frame.f_format;
683: frame->f_vector = tstate.hss_frame.f_vector;
684: bcopy((caddr_t)&tstate.hss_frame.F_u,
685: (caddr_t)&frame->F_u, sz);
686: #ifdef DEBUG
687: if (hpuxsigdebug & SDB_FOLLOW)
688: printf("sigreturn(%d): copy in %d of frame type %d\n",
689: p->p_pid, sz, tstate.ss_frame.f_format);
690: #endif
691: }
692:
693: /*
694: * Finally we restore the original FP context
695: */
696: if (flags & HSS_FPSTATE)
697: m68881_restore(&tstate.hss_fpstate);
698:
699: #ifdef DEBUG
700: if ((hpuxsigdebug & SDB_FPSTATE) && *(char *)&tstate.ss_fpstate)
701: printf("sigreturn(%d): copied in FP state (%x) at %x\n",
702: p->p_pid, *(u_int *)&tstate.ss_fpstate,
703: &tstate.ss_fpstate);
704:
705: if ((hpuxsigdebug & SDB_FOLLOW) ||
706: ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid))
707: printf("sigreturn(%d): returns\n", p->p_pid);
708: #endif
709: return (EJUSTRETURN);
710: }
711:
712: /*
713: * Set registers on exec.
714: * XXX Should clear registers except sp, pc.
715: */
716: void
717: hpux_setregs(p, pack, stack, retval)
718: register struct proc *p;
719: struct exec_package *pack;
720: u_long stack;
721: register_t *retval;
722: {
723: struct frame *frame = (struct frame *)p->p_md.md_regs;
724:
725: frame->f_pc = pack->ep_entry & ~1;
726: frame->f_regs[SP] = stack;
727: frame->f_regs[A2] = (int)PS_STRINGS;
728:
729: /* restore a null state frame */
730: p->p_addr->u_pcb.pcb_fpregs.fpf_null = 0;
731: if (fputype)
732: m68881_restore(&p->p_addr->u_pcb.pcb_fpregs);
733:
734: p->p_md.md_flags &= ~MDP_HPUXMMAP;
735: frame->f_regs[A0] = 0; /* not 68010 (bit 31), no FPA (30) */
736: retval[0] = 0; /* no float card */
737: if (fputype)
738: retval[1] = 1; /* yes 68881 */
739: else
740: retval[1] = 0; /* no 68881 */
741: }
CVSweb