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