|
|
1.1 root 1: / /usr/src/sys/i8086/src/ldas.s
2: /
3: ////////
4: /
5: / Loadable Driver Interface Routines.
6: /
7: / Loadable drivers execute in separate code segments, and are unable
8: / to directly call kernel service routines.
9: / Loadable drivers call a kernel service stub within their code segment,
10: / which has has the same name as the desired service routine.
11: / The driver service stub performs a far call to one of these routines.
12: / These routines perform a near call to the desired kernel routine,
13: / and then perform a far return to the driver service stub routine.
14: / The driver service stub routine then does a near return to the driver.
15: /
16: / 90/09/11 Hal Snyder
17: / Add ld_call()
18: /
19: / $Log: /usr/src/sys/i8086/src/RCS/ldas.s,v $
20: / Revision 1.2 91/03/01 09:23:04 root
21: / Part of COHERENT 3.1.0 kernel
22: /
23: / Revision 1.1 88/03/24 17:39:39 src
24: / Initial revision
25: /
26: / 87/12/08 Allan Cornish /usr/src/sys/i8086/src/ldas.s
27: / Block device interface added to loadable drivers.
28: / ldtimcall() function added to support timed functions in loadable drivers.
29: /
30: / 87/10/25 Allan Cornish /usr/src/sys/i8086/src/ldas.s
31: / Initial version - interface to/from loadable driver processes.
32: /
33: ////////
34:
35: .globl ld_xcall_
36: .globl ld_call_
37: .globl xcalled
38: .globl ldtimcall_
39: .globl ld_open_
40: .globl ld_close_
41: .globl ld_read_
42: .globl ld_write_
43: .globl ld_block_
44: .globl ld_ioctl_
45: .globl ld_power_
46: .globl ld_time_
47: .globl ld_poll_
48: .globl ldrvint_ / void (*ldrvint[16])();
49:
50: ////////
51: /
52: / Constants
53: /
54: ////////
55:
56: T_LDRV = 12 / Offset(tim,t_ldrv).
57: B_FLAG = 6 / Offset(buf,b_flag).
58: B_DEV = 8 / Offset(buf,b_dev ).
59: BFERR = 4 / buf.b_flag bit set on I/O error.
60: DRV_J = 4 / offset in driver of dispatcher
61:
62: ////////
63: /
64: / External References
65: /
66: ////////
67:
68: .globl nonedev_ / extern void nonedev();
69: .globl ldrvcon_ / extern CON * ldrvcon[NDRV];
70: .globl ldrvsel_ / extern saddr_t ldrvsel[NDRV];
71: .globl ldrvics_ / extern saddr_t ldrvics[16];
72: .globl ldrvipc_ / extern void (*ldrvipc[16])();
73:
74: ////////
75: /
76: / Shared Data
77: /
78: ////////
79: .shrd
80: ldrvint_: / Loadable Driver Interrupt Entry Points.
81: .word ld_intr0
82: .word ld_intr1
83: .word ld_intr2
84: .word ld_intr3
85: .word ld_intr4
86: .word ld_intr5
87: .word ld_intr6
88: .word ld_intr7
89: .word ld_intr8
90: .word ld_intr9
91: .word ld_intr10
92: .word ld_intr11
93: .word ld_intr12
94: .word ld_intr13
95: .word ld_intr14
96: .word ld_intr15
97:
98: ////////
99: /
100: / Private Data
101: /
102: ////////
103:
104: .prvd
105: .shri
106:
107: ////////
108: /
109: / Driver Configuration: Offsets to Function Pointers
110: /
111: ////////
112:
113: C_OPEN=4
114: C_CLOSE=6
115: C_BLOCK=8
116: C_READ=10
117: C_WRITE=12
118: C_IOCTL=14
119: C_POWER=16
120: C_TIMER=18
121: C_LOAD=20
122: C_ULOAD=22
123: C_POLL=24
124:
125: ////////
126: /
127: / ld_xcall( fp ) - invoke far function.
128: / int (far *fp)();
129: /
130: ////////
131:
132: ld_xcall_:
133: cli
134: push bp
135: mov bp, sp
136: xcall 4(bp)
137: pop bp
138: ret
139:
140: ////////
141: /
142: / call a driver function from the kernel
143: / sel - CS selector for the driver
144: / fn - offset in the driver of the function we want
145: / arg[1-3] - optional arguments
146: /
147: / ld_call(sel, fn, arg1, arg2, arg3)
148: / int sel;
149: / int (*fn)(void);
150: / int arg1, arg2, arg3;
151: /
152: ////////
153:
154: / stack when ld_call() is called:
155: / arg3
156: / arg2
157: / arg1
158: / fn
159: / sel
160: / return IP
161:
162: ld_call_: / PARAMETERS (arg[1-3]) MUST BE FOUND AT 4(BP).
163: push bp / DRIVER RESIDENT CODE RELIES ON THIS.
164: / lea bp, 4(sp) / this is what the next 2 instructions do
165: mov bp, sp
166: add bp, $4
167: /
168: push 0(bp) / Push sel to allow far call
169: push $DRV_J /
170: /
171: mov ax, 2(bp) / Push fn
172: /
173: xcall -8(bp) / Invoke driver interface, which will
174: / in turn invoke driver function.
175: /
176: lea sp, -4(bp) /
177: pop bp /
178: ret /
179:
180: ////////
181: /
182: /
183: / ldtimcall( arg, tp ) - service timed far function.
184: /
185: ////////
186:
187: ldtimcall_: /
188: push bp /
189: mov bp, sp /
190: /
191: mov bx, 6(bp) /
192: mov ax, T_LDRV+2(bx) /
193: push ax / Loadable driver code selector.
194: push $DRV_J / Loadable driver invocation offset.
195: mov ax, T_LDRV(bx) / Desired far function.
196: /
197: xcall -4(bp) /
198: /
199: mov sp, bp /
200: pop bp /
201: ret
202:
203: ////////
204: /
205: / xcalled( f, args )
206: / int (*f)();
207: /
208: / Input: AX is pointer to kernel function to be invoked.
209: /
210: / Action: Perform a near call to the specified kernel function,
211: / passing 6 words as optional arguments.
212: / Perform a far return.
213: /
214: / Notes: Invoked by far call from loadable device driver.
215: /
216: ////////
217:
218: xcalled: / 6(bp) = grand-parent IP.
219: push bp / 4(bp) = parent CS
220: mov bp, sp / 2(bp) = parent IP
221: / AX = destination function.
222: push 20(bp) / Arg 7 /
223: push 18(bp) / Arg 6 /
224: push 16(bp) / Arg 5 /
225: push 14(bp) / Arg 4 /
226: push 12(bp) / Arg 3 /
227: push 10(bp) / Arg 2 /
228: push 8(bp) / Arg 1 /
229: icall ax /
230: /
231: mov sp, bp / Return to loadable driver.
232: pop bp /
233: xret /
234:
235: ////////
236: /
237: / ld_open( dev, mode ) - Open Routine.
238: / dev_t dev;
239: / int mode;
240: /
241: ////////
242:
243: ld_open_: / PARAMETERS MUST REMAIN AT 4(BP).
244: push bp / DRIVER RESIDENT CODE RELIES ON THIS.
245: mov bp, sp /
246: /
247: sub bx, bx / Calculate major device number * 2.
248: movb bl, 5(bp) /
249: shl bx, $1 /
250: /
251: mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
252: jcxz 0f /
253: push cx /
254: push $DRV_J / Loadable driver invocation offset.
255: /
256: mov bx, ldrvcon_(bx)/ Identify driver configuration.
257: or bx, bx /
258: je 0f /
259: /
260: mov ax, C_OPEN(bx) / Identify driver function to be invoked.
261: or ax, ax /
262: je 0f /
263: /
264: xcall -4(bp) / Invoke driver interface, which will
265: / in turn invoke driver function.
266: /
267: mov sp, bp / Return to caller.
268: pop bp /
269: ret /
270:
271: 0: mov sp, bp
272: pop bp
273: jmp nonedev_
274:
275: ////////
276: /
277: / ld_close( dev ) - Close Routine.
278: / dev_t dev;
279: /
280: ////////
281:
282: ld_close_: / PARAMETERS MUST REMAIN AT 4(BP).
283: push bp / DRIVER RESIDENT CODE RELIES ON THIS.
284: mov bp, sp /
285: /
286: sub bx, bx / Calculate major device number * 2.
287: movb bl, 5(bp) /
288: shl bx, $1 /
289: /
290: mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
291: jcxz 0f /
292: push cx /
293: push $DRV_J / Loadable driver invocation offset.
294: /
295: mov bx, ldrvcon_(bx)/ Identify driver configuration.
296: or bx, bx /
297: je 0f /
298: /
299: mov ax, C_CLOSE(bx) / Identify driver function to be invoked.
300: or ax, ax /
301: je 0f /
302: /
303: xcall -4(bp) / Invoke driver interface, which will
304: / in turn invoke driver function.
305: /
306: mov sp, bp / Return to caller.
307: pop bp /
308: ret /
309:
310: 0: mov sp, bp
311: pop bp
312: jmp nonedev_
313:
314: ////////
315: /
316: / ld_read( dev, iop ) - Read Routine.
317: / dev_t dev;
318: / IO * iop;
319: /
320: ////////
321:
322: ld_read_: / PARAMETERS MUST REMAIN AT 4(BP).
323: push bp / DRIVER RESIDENT CODE RELIES ON THIS.
324: mov bp, sp /
325: /
326: sub bx, bx / Calculate major device number * 2.
327: movb bl, 5(bp) /
328: shl bx, $1 /
329: /
330: mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
331: jcxz 0f /
332: push cx /
333: push $DRV_J / Loadable driver invocation offset.
334: /
335: mov bx, ldrvcon_(bx)/ Identify driver configuration.
336: or bx, bx /
337: je 0f /
338: /
339: mov ax, C_READ(bx) / Identify driver function to be invoked.
340: or ax, ax /
341: je 0f /
342: /
343: xcall -4(bp) / Invoke driver interface, which will
344: / in turn invoke driver function.
345: /
346: mov sp, bp / Return to caller.
347: pop bp /
348: ret /
349:
350: 0: mov sp, bp
351: pop bp
352: jmp nonedev_
353:
354: ///////
355: /
356: / ld_write( dev, iop ) - Write Routine.
357: / dev_t dev;
358: / IO * iop;
359: /
360: ////////
361:
362: ld_write_: / PARAMETERS MUST REMAIN AT 4(BP).
363: push bp / DRIVER RESIDENT CODE RELIES ON THIS.
364: mov bp, sp /
365: /
366: sub bx, bx / Calculate major device number * 2.
367: movb bl, 5(bp) /
368: shl bx, $1 /
369: /
370: mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
371: jcxz 0f /
372: push cx /
373: push $DRV_J / Loadable driver invocation offset.
374: /
375: mov bx, ldrvcon_(bx)/ Identify driver configuration.
376: or bx, bx /
377: je 0f /
378: /
379: mov ax, C_WRITE(bx) / Identify driver function to be invoked.
380: or ax, ax /
381: je 0f /
382: /
383: xcall -4(bp) / Invoke driver interface, which will
384: / in turn invoke driver function.
385: /
386: mov sp, bp / Return to caller.
387: pop bp /
388: ret /
389:
390: 0: mov sp, bp
391: pop bp
392: jmp nonedev_
393:
394: ///////
395: /
396: / ld_block( bp ) - Block Routine.
397: / BUF * bp;
398: /
399: ////////
400:
401: ld_block_: / PARAMETERS MUST REMAIN AT 4(BP).
402: push bp / DRIVER RESIDENT CODE RELIES ON THIS.
403: mov bp, sp /
404: /
405: mov bx, 4(bp) / Calculate major device number * 2.
406: movb bl, B_DEV+1(bx) /
407: subb bh, bh /
408: shl bx, $1 /
409: /
410: mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
411: jcxz 0f /
412: push cx /
413: push $DRV_J / Loadable driver invocation offset.
414: /
415: mov bx, ldrvcon_(bx)/ Identify driver configuration.
416: or bx, bx /
417: je 0f /
418: /
419: mov ax, C_BLOCK(bx) / Identify driver function to be invoked.
420: or ax, ax /
421: je 0f /
422: /
423: xcall -4(bp) / Invoke driver interface, which will
424: / in turn invoke driver function.
425: /
426: mov sp, bp / Return to caller.
427: pop bp /
428: ret /
429:
430: 0: mov bx, 4(bp) / bp->b_flag |= BFERR.
431: or B_FLAG(bx),$BFERR /
432: mov sp, bp /
433: pop bp /
434: jmp bdone_ / bdone(bp);
435:
436: ////////
437: /
438: / ld_ioctl( dev, iop ) - Ioctl Routine.
439: / dev_t dev;
440: / IO * iop;
441: /
442: ////////
443:
444: ld_ioctl_: / PARAMETERS MUST REMAIN AT 4(BP).
445: push bp / DRIVER RESIDENT CODE RELIES ON THIS.
446: mov bp, sp /
447: /
448: sub bx, bx / Calculate major device number * 2.
449: movb bl, 5(bp) /
450: shl bx, $1 /
451: /
452: mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
453: jcxz 0f /
454: push cx /
455: push $DRV_J / Loadable driver invocation offset.
456: /
457: mov bx, ldrvcon_(bx)/ Identify driver configuration.
458: or bx, bx /
459: je 0f /
460: /
461: mov ax, C_IOCTL(bx) / Identify driver function to be invoked.
462: or ax, ax /
463: je 0f /
464: /
465: xcall -4(bp) / Invoke driver interface, which will
466: / in turn invoke driver function.
467: /
468: mov sp, bp / Return to caller.
469: pop bp /
470: ret /
471:
472: 0: mov sp, bp
473: pop bp
474: jmp nonedev_
475:
476: ////////
477: /
478: / ld_power( dev ) - Powerfail Routine.
479: / dev_t dev;
480: /
481: ////////
482:
483: ld_power_: / PARAMETERS MUST REMAIN AT 4(BP).
484: push bp / DRIVER RESIDENT CODE RELIES ON THIS.
485: mov bp, sp /
486: /
487: sub bx, bx / Calculate major device number * 2.
488: movb bl, 5(bp) /
489: shl bx, $1 /
490: /
491: mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
492: jcxz 0f /
493: push cx /
494: push $DRV_J / Loadable driver invocation offset.
495: /
496: mov bx, ldrvcon_(bx)/ Identify driver configuration.
497: or bx, bx /
498: je 0f /
499: /
500: mov ax, C_POWER(bx) / Identify driver function to be invoked.
501: or ax, ax /
502: je 0f /
503: /
504: xcall -4(bp) / Invoke driver interface, which will
505: / in turn invoke driver function.
506: /
507: mov sp, bp / Return to caller.
508: pop bp /
509: ret /
510:
511: 0: mov sp, bp
512: pop bp
513: jmp nonedev_
514:
515: ////////
516: /
517: / ld_time( dev ) - Timer Routine.
518: / dev_t dev;
519: /
520: ////////
521:
522: ld_time_: / PARAMETERS MUST REMAIN AT 4(BP).
523: push bp / DRIVER RESIDENT CODE RELIES ON THIS.
524: mov bp, sp /
525: /
526: sub bx, bx / Calculate major device number * 2.
527: movb bl, 5(bp) /
528: shl bx, $1 /
529: /
530: mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
531: jcxz 0f /
532: push cx /
533: push $DRV_J / Loadable driver invocation offset.
534: /
535: mov bx, ldrvcon_(bx)/ Identify driver configuration.
536: or bx, bx /
537: je 0f /
538: /
539: mov ax, C_TIMER(bx) / Identify driver function to be invoked.
540: or ax, ax /
541: je 0f /
542: /
543: xcall -4(bp) / Invoke driver interface, which will
544: / in turn invoke driver function.
545: /
546: mov sp, bp / Return to caller.
547: pop bp /
548: ret /
549:
550: 0: mov sp, bp
551: pop bp
552: jmp nonedev_
553:
554: ////////
555: /
556: / ld_poll( dev, ev, msec ) - Poll Routine.
557: / dev_t dev;
558: / int ev;
559: / int msec;
560: /
561: ////////
562:
563: ld_poll_: / PARAMETERS MUST REMAIN AT 4(BP).
564: push bp / DRIVER RESIDENT CODE RELIES ON THIS.
565: mov bp, sp /
566: /
567: sub bx, bx / Calculate major device number * 2.
568: movb bl, 5(bp) /
569: shl bx, $1 /
570: /
571: mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP.
572: jcxz 0f /
573: push cx /
574: push $DRV_J / Loadable driver invocation offset.
575: /
576: mov bx, ldrvcon_(bx)/ Identify driver configuration.
577: or bx, bx /
578: je 0f /
579: /
580: mov ax, C_POLL(bx) / Identify driver function to be invoked.
581: or ax, ax /
582: je 0f /
583: /
584: xcall -4(bp) / Invoke driver interface, which will
585: / in turn invoke driver function.
586: /
587: mov sp, bp / Return to caller.
588: pop bp /
589: ret /
590:
591: 0: mov sp, bp
592: pop bp
593: jmp nonedev_
594:
595: ////////
596: /
597: / Loadable Driver Interrupt Entry Points.
598: /
599: / Invoked by Coherent to service specific interrupt.
600: / Identifies which loadable driver interrupt vector to be used.
601: / Invokes interrupt handler which will do far call to loadable driver.
602: /
603: ////////
604:
605: ld_intr0:
606: mov bx, $0 /
607: jmp ld_intr /
608:
609: ld_intr1:
610: mov bx, $2 /
611: jmp ld_intr /
612:
613: ld_intr2:
614: mov bx, $4 /
615: jmp ld_intr /
616:
617: ld_intr3:
618: mov bx, $6 /
619: jmp ld_intr /
620:
621: ld_intr4:
622: mov bx, $8 /
623: jmp ld_intr /
624:
625: ld_intr5:
626: mov bx, $10 /
627: jmp ld_intr /
628:
629: ld_intr6:
630: mov bx, $12 /
631: jmp ld_intr /
632:
633: ld_intr7:
634: mov bx, $14 /
635: jmp ld_intr /
636:
637: ld_intr8:
638: mov bx, $16 /
639: jmp ld_intr /
640:
641: ld_intr9:
642: mov bx, $18 /
643: jmp ld_intr /
644:
645: ld_intr10:
646: mov bx, $20 /
647: jmp ld_intr /
648:
649: ld_intr11:
650: mov bx, $22 /
651: jmp ld_intr /
652:
653: ld_intr12:
654: mov bx, $24 /
655: jmp ld_intr /
656:
657: ld_intr13:
658: mov bx, $26 /
659: jmp ld_intr /
660:
661: ld_intr14:
662: mov bx, $28 /
663: jmp ld_intr /
664:
665: ld_intr15:
666: mov bx, $30 /
667: jmp ld_intr /
668:
669: ////////
670: /
671: / Loadable driver interrupt handler.
672: /
673: /
674: / Input: bx = interrupt number * 2.
675: /
676: ////////
677:
678: ld_intr:
679: push bp /
680: mov bp, sp /
681: /
682: mov cx,ldrvics_(bx) / Prepare driver interface CS:IP.
683: jcxz 0f /
684: push cx /
685: push $DRV_J / Loadable driver invocation offset.
686: /
687: mov ax,ldrvipc_(bx) / Identify interrupt handler to be invoked.
688: or ax, ax /
689: je 0f /
690: /
691: xcall -4(bp) / Invoke driver interface, which will
692: / in turn invoke driver function.
693: /
694: 0: mov sp, bp /
695: pop bp /
696: ret /
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.