1: /* 2: * Copyright (c) 1988 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: * 6: * @(#)net_SKcall.s 1.1 (2.10BSD Berkeley) 4/3/88 7: */ 8: 9: #include "DEFS.h" 10: #include "../machine/mch_iopage.h" 11: /* 12: * Inter-address-space procedure call subroutines. 13: * SKcall -- supervisor to kernel 14: */ 15: 16: /* 17: * SKcall(func, nbytes, a1, ..., aN) 18: * 19: * C-call from supervisor to kernel. 20: * Calls func(a1, ..., aN) in kernel mode. 21: */ 22: ENTRY(SKcall) 23: mov r5,-(sp) 24: mov PS,-(sp) / Save current PS 25: mov 010(sp),r0 / r0: # bytes of arguments to copy 26: 27: /* 28: * Allocate enough space on the kernel stack to hold 29: * the call frame. We must allocate space to hold all the 30: * arguments, plus: 31: * a PS, PC pair to take us to the function being called 32: * in kernel space. 33: * a return address (Kretu) 34: * a null R5 entry as a marker 35: * a PS, PC pair to take us back to supervisor mode. 36: * 37: * We assume that if the kernel stack pointer is pointing to 38: * an address before the start of seg6, the kernel stack has 39: * been remapped and we must use mtpd instructions instead 40: * of simple mov's. 41: * 42: * WARNING: 43: * ======= 44: * 45: * The reason we use mtpd is to guarantee that we write into 46: * the kernel stack. However, when the kernel stack is remapped 47: * to point outside of seg 6, there may not be enough room for 48: * storing the arguments in the new stack. There is currently no 49: * check made here to prevent overflowing this remapped stack. 50: */ 51: 52: mov $040340,PS / Current SUPV, prev KERN, spl7 (paranoia) 53: mfpd sp / Kernel stack pointer 54: mov (sp),r1 / Pointer to base of new call frame 55: sub r0,(sp) 56: sub $12.,(sp) / New SP. 57: mtpd sp / Set up alternate stack ptr 58: 59: cmp r1,$_u / Is kernel SP pointing in seg6? 60: bhi skmov / Yes: OK to use normal mov instructions 61: jmp skmtpd / No: must use mtpd instead 62: 63: skmov: 64: mov (sp),PS / Restore original PS 65: mov (sp)+,-(r1) / Transfer saved PS to alternate stack 66: mov $ret,-(r1) / Will return to ret below 67: mov r5,-(r1) / Old frame ptr 68: mov r1,r5 / New frame ptr for other mode 69: 70: /* 71: * Copy arguments. 72: * Note that the stack offsets here are the same as they 73: * were right after we saved the PS. 74: */ 75: 76: mov r2,-(sp) / Save 77: mov r0,r2 / r2: number of bytes of arguments to copy 78: beq 2f / None to copy? if so, skip loop 79: asr r2 / r2: number of words of arguments to copy 80: add sp,r0 81: add $10.,r0 / r0: ptr to argN+1 82: 1: 83: mov -(r0),-(r1) 84: sob r2,1b 85: 2: 86: mov (sp)+,r2 / Restore 87: 88: /* 89: * Build the rest of the kernel stack frame. 90: * This consists of a normal return address (Kretu) to which 91: * the kernel function will return, and a <PS, PC> pair used 92: * by Kretu to get back here to supervisor mode. 93: */ 94: 95: mov $Kretu,-(r1) / Address of RTT-er in kernel mode 96: mov $30000,-(r1) / New PS mode: (current KERN, prev USER) 97: bisb PS,(r1) / New PS priority 98: mov 04(sp),-(r1) / Stack address of function to be called 99: 100: skcall: 101: /* 102: * At this point, the stacks look like the following: 103: * 104: * SUPERVISOR KERNEL 105: * ---------- ------ 106: *SSP-> <R5> <KERN func address> <-KSP 107: * <caller's rtnaddr> <KERN PS> 108: * <KERN func address> <Kretu> 109: * <# bytes of args> <arg0> 110: * <arg0> ... 111: * ... <argN> 112: * <argN> <0> 113: * <ret in SUPV space> 114: * <PS for SUPV mode> 115: * 116: * "<KERN func address>" is the address in kernel address 117: * space of the function being called. 118: */ 119: 120: iot 121: 122: /* 123: * Return to caller of SKcall. 124: * We arrive here with the PS being the same as it was on 125: * calling SKcall, via a "rtt" from Kretu in kernel mode. 126: */ 127: ret: 128: mov (sp)+,r5 129: rts pc 130: 131: /* 132: * The kernel stack has been repointed. 133: * Use mtpd to set up the kernel stack for the call. 134: * 135: * We expect that r1 contains the address in kernel space 136: * of the base of the call frame we are about to build. 137: * The word on the top of the stack is the original PS. 138: */ 139: 140: skmtpd: 141: mov (sp),PS / Restore original PS (mainly for priority) 142: bic $30000,PS / Previous mode is kernel 143: mtpd -(r1) / Transfer saved PS to alternate stack 144: mov $ret,-(sp) / Will return to ret below 145: mtpd -(r1) 146: mov r5,-(sp) / Old frame ptr 147: mtpd -(r1) 148: mov r1,r5 / New frame ptr for other mode 149: 150: /* 151: * Copy arguments. 152: * Note that the stack offsets here are the same as they 153: * were right after we saved the PS. 154: */ 155: 156: mov r2,-(sp) / Save 157: mov r0,r2 / r2: number of bytes of arguments to copy 158: beq 2f / None to copy? if so, skip loop 159: asr r2 / r2: number of words of arguments to copy 160: add sp,r0 161: add $10.,r0 / r0: ptr to argN+1 162: 1: 163: mov -(r0),-(sp) 164: mtpd -(r1) 165: sob r2,1b 166: 2: 167: mov (sp)+,r2 / Restore 168: 169: /* 170: * Build the rest of the kernel stack frame. 171: * This consists of a normal return address (Kretu) to which 172: * the kernel function will return, and a <PS, PC> pair used 173: * by Kretu to get back here to supervisor mode. 174: */ 175: 176: mov $Kretu,-(sp) / Address of RTT-er in kernel mode 177: mtpd -(r1) 178: mov $010000,-(sp) / New PS mode: (current KERN, prev SUPV) 179: bisb PS,(sp) / New PS priority 180: mtpd -(r1) 181: mov 04(sp),-(sp) / Stack address of function to be called 182: mtpd -(r1) 183: jmp skcall / Back to complete the call 184: 185: 186: /* 187: * Sretu is the exit point in supervisor code that cleans up 188: * the supervisor stack for return to kernel mode from a 189: * kernel-to-net procedure call. 190: * 191: * We can't use rtt here, so instead we use the a "iot" 192: * in just the same way as we would use to "call" something 193: * in the kernel. 194: */ 195: ASENTRY(Sretu) 196: mov r5,sp / Base of frame area 197: tst (sp)+ / Throw away old frame pointer 198: /* 199: * At this point, the stacks look like the following: 200: * 201: * KERNEL SUPERVISOR 202: * ------ ---------- 203: * <_Sretu> 204: * <arg0> 205: *KSP-> <ret in KERN space> ... 206: * <R5> <argN> 207: * <caller's rtnaddr> <0> 208: * <SUPV func address> <old stack top> <-SSP 209: * <# bytes of args> 210: * <arg0> 211: * ... 212: * <argN> 213: */ 214: iot