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: * @(#)mch_KScall.s 1.1 (2.10BSD Berkeley) 4/3/88 7: */ 8: 9: #include "DEFS.h" 10: #include "../machine/mch_iopage.h" 11: 12: /* 13: * Inter-address-space procedure call subroutines. 14: * KScall -- kernel to supervisor 15: */ 16: 17: /* 18: * KScall(func, nbytes, a1, ..., aN) 19: * 20: * C-call from kernel to supervisor. 21: * Calls func(a1, ..., aN) in supervisor mode. 22: */ 23: ENTRY(KScall) 24: mov r5,-(sp) 25: mov PS,-(sp) / Save current PS 26: mov 010(sp),r0 / r0: # bytes of arguments to copy 27: 28: /* 29: * Allocate enough space on the supervisor stack to hold 30: * the call frame. We must allocate space to hold all the 31: * arguments, plus: 32: * a null R5 entry as a marker 33: * a return address (Sretu) 34: * 35: * We assume here that the supervisor stack pointer is always 36: * in seg6 and further that both supervisor and kernel addresses 37: * in this region are mapped to the same physical memory. 38: * 39: * This means that it is NOT ok for the network code to move the 40: * supervisor SP outside of seg6, or for it to remap SDSA6 to 41: * point to something other than the stack, unless it can guarantee 42: * that KScall will not be called for the duration of the stack 43: * fiddling. 44: */ 45: mov $010340,PS / Current KERN, prev SUPV, spl7 (paranoia) 46: mfpd sp / Supervisor stack pointer 47: mov (sp),r1 / Pointer to base of call frame 48: 49: #ifdef CHECKSTACK 50: /* 51: * The following is just to make sure that the supervisor stack 52: * pointer looks reasonable and a check that *SDSA6 == *KDSA6 53: */ 54: cmp r1,$_u 55: blos 8f 56: cmp r1,$USIZE\<6.+_u 57: bhis 8f 58: cmp SDSA6,KDSA6 59: beq 9f 60: 8: 61: spl 7 / lock out interrupts 62: halt / drop dead so people can see where we are 63: br . / go no further 64: 9: 65: #endif /* CHECKSTACK */ 66: 67: sub r0,(sp) 68: sub $4.,(sp) / New SP. 69: mtpd sp / Set up alternate stack ptr 70: mov (sp),PS / Restore current PS 71: mov r5,-(r1) / Old frame ptr 72: mov r1,r5 / New frame ptr for other mode 73: 74: /* 75: * Copy arguments. 76: * Note that the stack offsets here are one word deeper than 77: * after we saved the PS. 78: */ 79: 80: mov r2,-(sp) / Save 81: mov r0,r2 / r2: number of bytes of arguments to copy 82: beq 2f / None to copy? if so, skip loop 83: asr r2 / r2: number of words of arguments to copy 84: add sp,r0 85: add $12.,r0 / r0: ptr to argN+1 86: 1: 87: mov -(r0),-(r1) 88: sob r2,1b 89: 2: 90: mov (sp)+,r2 / Restore 91: 92: /* 93: * Build the remainder of the frame on the 94: * supervisor stack. 95: */ 96: mov $Sretu,-(r1) / Return address in supervisor space 97: 98: /* 99: * Push the iothndlr <PS, PC> pair, and the 100: * <PS, PC> pair for calling the supervisor function 101: * on the kernel stack. 102: */ 103: mov PS,r0 / To get current priority 104: bic $170000,r0 / Clear out current/previous modes 105: bis $050000,r0 / Current SUPV, previous SUPV 106: mov $ret,-(sp) / Stack kernel PC to go with saved kernel PS 107: mov r0,-(sp) / Stack the new PS 108: mov 10.(sp),-(sp) / Stack the address of function being called 109: 110: /* 111: * At this point, the stacks look like the following: 112: * 113: * KERNEL SUPERVISOR 114: * ------ ---------- 115: *KSP-> <SUPV func address> <Sretu> <-SSP 116: * <SUPV PS> <arg0> 117: * <KERN "ret"> ... 118: * <KERN saved PS> <argN> 119: * <R5> <0> 120: * <caller's rtnaddr> 121: * <SUPV func address> 122: * <# bytes of args> 123: * <arg0> 124: * ... 125: * <argN> 126: * 127: * "<SUPV func address>" is the address in supervisor address 128: * space of the function being called. 129: */ 130: rtt / Call the function 131: 132: /* 133: * Return to caller of KScall. 134: * We arrive here with the same PS as that with which we were 135: * called, via the rtt in iothndlr. 136: */ 137: ret: 138: mov (sp)+,r5 139: rts pc 140: 141: 142: /* 143: * Kretu is the exit point in kernel code that cleans up 144: * the kernel stack for return to supervisor mode from a 145: * net-to-kernel procedure call. 146: */ 147: ASENTRY(Kretu) 148: mov r5,sp / Throw away arguments from stack 149: tst (sp)+ / Discard old frame pointer 150: /* 151: * At this point, the stacks look like the following: 152: * 153: * SUPERVISOR KERNEL 154: * ---------- ------ 155: *SSP-> <R5> 156: * <caller's rtnaddr> <_Kretu> 157: * <KERN func address> <arg0> 158: * <# bytes of args> ... 159: * <arg0> <argN> 160: * ... <0> 161: * <argN> <ret in SUPV space> <-KSP 162: * <PS for SUPV mode> 163: */ 164: rtt / Back to previous address space