1/* $NetBSD: reenter_syscall.s,v 1.7 2021/02/23 16:54:17 tsutsui Exp $ */ 2 3/* 4 * Written by ITOH Yasufumi. 5 * Public domain. 6 */ 7 8#include <m68k/asm.h> 9#include "assym.h" 10 11/* 12 * void reenter_syscall(struct frame *fp, int stkadj) 13 * __attribute__((__noreturn__)); 14 * 15 * Move stack frame by stkadj bytes and re-enter syscall(). 16 * 17 * XXX This is a kludge. 18 */ 19 20ENTRY_NOPROFILE(reenter_syscall) 21 addql #4,%sp | pop PC 22 movel (%sp)+,%a0 | current frame addr 23 movel (%sp),%d1 | stkadj 24 25| The m68k frame (struct trapframe) format: 26| 16:l d0-d7/a0-a6/usp 27| 1:w (pad) 28| 1:w stkadj 29| 1:w sr 30| 1:l pc 31| 1:w format/vector 32 33 moveal %a0,%a1 34 subal %d1,%a1 | new frame address 35 moveal %a1,%sp | set SP 36 37 | copy down frame (16*4 + 2 + 2 + 2 + 4 + 2 = 76 bytes = 19 longs) 38 moveq #19-1,%d0 39.Lcpfr: movel (%a0)+,(%a1)+ 40 dbra %d0,.Lcpfr 41 42 movew %d1,FR_ADJ(%sp) | set stack adjust count 43 movel (%sp),-(%sp) | push syscall no (original d0 value) 44 jbsr _C_LABEL(syscall) | re-enter syscall() 45 addql #4,%sp | pop syscall no 46#ifdef DEBUG 47 tstw FR_ADJ(%sp) | stack adjust must be zero 48 jeq .Ladjzero 49 PANIC("reenter_syscall") 50.Ladjzero: 51#endif 52 moveal FR_SP(%sp),%a0 | grab and restore 53 movel %a0,%usp | user SP 54 movw FR_ADJ(%sp),%d0 | need to adjust stack? 55 jne .Ladjstk | yes, go to it 56 moveml (%sp)+,#0x7FFF | restore user registers 57 addql #8,%sp | pop SP and stack adjust 58 jra _ASM_LABEL(rei) | rte 59.Ladjstk: 60 lea FR_HW(%sp),%a1 | pointer to HW frame 61 addql #8,%a1 | source pointer 62 movl %a1,%a0 | source 63 addw %d0,%a0 | + hole size = dest pointer 64 movl -(%a1),-(%a0) | copy 65 movl -(%a1),-(%a0) | 8 bytes 66 movl %a0,FR_SP(%sp) | new SSP 67 moveml (%sp)+,#0x7FFF | restore user register 68 movl (%sp),%sp | and do real RTE 69 jra _ASM_LABEL(rei) | rte 70