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