|
|
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.