|
|
1.1 ! root 1: / $Header: /kernel/kersrc/i286/RCS/defer.s,v 1.1 92/07/17 15:21:24 bin Exp Locker: bin $ ! 2: / ! 3: / The information contained herein is a trade secret of INETCO ! 4: / Systems, and is confidential information. It is provided under ! 5: / a license agreement, and may be copied or disclosed only under ! 6: / the terms of that agreement. Any reproduction or disclosure of ! 7: / this material without the express written authorization of ! 8: / INETCO Systems or persuant to the license agreement is unlawful. ! 9: / ! 10: / Copyright (c) 1986 ! 11: / An unpublished work by INETCO Systems, Ltd. ! 12: / All rights reserved. ! 13: / ! 14: ! 15: //////// ! 16: / ! 17: / Defer a function [from interrupt level] for later execution ! 18: / ! 19: / defer( f, a ) - defer a function [usually from interrupt level] ! 20: / defend() - execute deferred functions ! 21: / ! 22: / $Log: defer.s,v $ ! 23: / Revision 1.1 92/07/17 15:21:24 bin ! 24: / Initial revision ! 25: / ! 26: / Revision 1.2 88/04/04 17:05:05 src ! 27: / ldefer/ldefend functions now allow deferred functions from loadable drivers. ! 28: / ! 29: / Revision 1.1 88/03/24 17:39:20 src ! 30: / Initial revision ! 31: / ! 32: / 86/11/19 Allan Cornish /usr/src/sys/i8086/src/defer.s ! 33: / defer(func,arg) and defend() functions ported to Coherent from RTX. ! 34: / ! 35: //////// ! 36: ! 37: .globl defend_ ! 38: .globl defer_ ! 39: .globl ldefer ! 40: ! 41: .bssd ! 42: defunc: .blkw 128 / static void (*defunc[128])(); ! 43: defarg: .blkw 128 / static char * defarg[128]; ! 44: defqix: .blkw 1 / static int defqix; ! 45: defqox: .blkw 1 / static int defqox; ! 46: ldcseg: .blkw 128 / static saddr_t ldcseg[128]; ! 47: ldfunc: .blkw 128 / static void (*ldfunc[128])(); ! 48: .shri ! 49: ! 50: //////// ! 51: / ! 52: / void ! 53: / defer( f, a ) -- defer a function [usually from interrupt level] ! 54: / int (*f)(); ! 55: / char *a; ! 56: / ! 57: / Input: f = pointer to function to be deferred. ! 58: / a = argument to pass to function when it is invoked. ! 59: / ! 60: / Action: Schedule function 'f' to be invoked with argument 'a' ! 61: / during the transition from interrupt service level back ! 62: / to user mode. ! 63: / ! 64: / Return: None. ! 65: / ! 66: / Notes: 13 instructions executed. Interrupt latency = 7 instructions. ! 67: / Only 127 functions can be deferred at any one time. ! 68: / Exceeding this limit will cause loss of ALL deferred functions. ! 69: / ! 70: //////// ! 71: ! 72: defer_: / ! 73: pop ax / Convert IP into PSW,CS,IP to allow iret. ! 74: pushf / ! 75: push cs / ! 76: push ax / ! 77: mov bx, sp / defer( f, a ) ! 78: mov ax, ss:6(bx) / register int (*f)(); /* AX */ ! 79: mov dx, ss:8(bx) / register char *a; /* DX */ ! 80: / { ! 81: / register int x; /* BX */ ! 82: / ! 83: cli / sphi(); ! 84: mov bx, defqix / x = defqix; ! 85: mov defunc(bx), ax / defunc[x] = f; ! 86: mov defarg(bx), dx / defarg[x] = a; ! 87: addb defqix, $2 / defqix++; ! 88: // sti / splo(); ! 89: iret / } ! 90: ! 91: //////// ! 92: / ! 93: / void ! 94: / defend( ) -- evaluate deferred functions ! 95: / ! 96: / Action: Evaluate all deferred functions. ! 97: / ! 98: / Notes: Should be called periodically by busy-wait device drivers. ! 99: / 4 + (n * 7) instructions executed, where n = # deferred func. ! 100: //////// ! 101: ! 102: defend_: / defend() ! 103: / { ! 104: / ! 105: mov bx, defqox / register int x = defqox; /* BX */ ! 106: / ! 107: cmp bx, defqix / if ( x != defqix ) { ! 108: je 1f / ! 109: / do { ! 110: 0: addb defqox, $2 / defqox++; ! 111: / ! 112: push defarg(bx) / (*defunc[x]) ! 113: icall defunc(bx) / (defarg[x]); ! 114: add sp, $2 / ! 115: / ! 116: mov bx, defqox / x = defqox; ! 117: cmp bx, defqix / ! 118: jne 0b / } while ( x != defqix ); ! 119: / } ! 120: 1: ret / } ! 121: ! 122: //////// ! 123: / ! 124: / void ! 125: / ldefer( f, a ) -- defer a far function [usually from interrupt level] ! 126: / int (far*f)(); ! 127: / char *a; ! 128: / ! 129: / Input: f = pointer to loadable driver function to be deferred. ! 130: / a = argument to pass to function when it is invoked. ! 131: / ! 132: / Action: Schedule loadable driver function 'f' to be invoked with ! 133: / argument 'a' during the transition from interrupt service ! 134: / level back to user mode. ! 135: / ! 136: / Return: None. ! 137: / ! 138: / Notes: 16 instructions executed. Interrupt latency = 8 instructions. ! 139: / Only 127 functions can be deferred at any one time. ! 140: / Exceeding this limit will cause loss of ALL deferred functions. ! 141: / ! 142: //////// ! 143: ! 144: ldefer: / ! 145: pop ax / Convert IP into PSW,CS,IP to allow iret. ! 146: pushf / ! 147: push cs / ! 148: push ax / ! 149: mov bx, sp / defer( f, a ) ! 150: mov ax, ss:6(bx) / register int (*f)(); /* CX:AX */ ! 151: mov cx, ss:8(bx) / ! 152: mov dx, ss:10(bx) / register char *a; /* DX */ ! 153: / { ! 154: / register int x; /* BX */ ! 155: / ! 156: cli / sphi(); ! 157: mov bx, defqix / x = defqix; ! 158: mov ldfunc(bx), ax / ldfunc[x] = FP_OFF(f); ! 159: mov ldcseg(bx), cx / ldcseg[x] = FP_SEL(f); ! 160: mov defunc(bx),$ldefend/ defunc[x] = ldefend; ! 161: mov defarg(bx), dx / defarg[x] = a; ! 162: addb defqix, $2 / defqix++; ! 163: // sti / splo(); ! 164: iret / } ! 165: ! 166: //////// ! 167: / ! 168: / static void ! 169: / ldefend( ) -- evaluate deferred far function ! 170: / ! 171: / Action: Evaluate deferred far function. ! 172: / ! 173: / Notes: Only called by defend(). Register BX contains driver's defqox. ! 174: / ! 175: //////// ! 176: ! 177: ldefend: / PARAMETERS MUST REMAIN AT 4(BP). ! 178: push bp / DRIVER RESIDENT CODE RELIES ON THIS. ! 179: mov bp, sp / ! 180: / ! 181: mov ax, ldfunc(bx) / AX = Driver function to be invoked. ! 182: / ! 183: push ldcseg(bx) / Define driver entry point. ! 184: push four / ! 185: / ! 186: xcall -4(bp) / Invoke driver entry point, which will ! 187: / in turn invoke the deferred function. ! 188: / ! 189: mov sp, bp / Return to caller. ! 190: pop bp / ! 191: ret / ! 192: ! 193: .prvd ! 194: four: .word 4 ! 195: .shri
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.