|
|
coherent
/ /usr/src/sys/i8086/src/ldas.s / //////// / / Loadable Driver Interface Routines. / / Loadable drivers execute in separate code segments, and are unable / to directly call kernel service routines. / Loadable drivers call a kernel service stub within their code segment, / which has has the same name as the desired service routine. / The driver service stub performs a far call to one of these routines. / These routines perform a near call to the desired kernel routine, / and then perform a far return to the driver service stub routine. / The driver service stub routine then does a near return to the driver. / / 90/09/11 Hal Snyder / Add ld_call() / / $Log: ldas.s,v $ / Revision 1.1.1.1 2019/05/29 04:56:39 root / coherent / / Revision 1.1 92/07/17 15:21:30 bin / Initial revision / / Revision 1.2 91/03/01 09:23:04 root / Part of COHERENT 3.1.0 kernel / / Revision 1.1 88/03/24 17:39:39 src / Initial revision / / 87/12/08 Allan Cornish /usr/src/sys/i8086/src/ldas.s / Block device interface added to loadable drivers. / ldtimcall() function added to support timed functions in loadable drivers. / / 87/10/25 Allan Cornish /usr/src/sys/i8086/src/ldas.s / Initial version - interface to/from loadable driver processes. / //////// .globl ld_xcall_ .globl ld_call_ .globl xcalled .globl ldtimcall_ .globl ld_open_ .globl ld_close_ .globl ld_read_ .globl ld_write_ .globl ld_block_ .globl ld_ioctl_ .globl ld_power_ .globl ld_time_ .globl ld_poll_ .globl ldrvint_ / void (*ldrvint[16])(); //////// / / Constants / //////// T_LDRV = 12 / Offset(tim,t_ldrv). B_FLAG = 6 / Offset(buf,b_flag). B_DEV = 8 / Offset(buf,b_dev ). BFERR = 4 / buf.b_flag bit set on I/O error. DRV_J = 4 / offset in driver of dispatcher //////// / / External References / //////// .globl nonedev_ / extern void nonedev(); .globl ldrvcon_ / extern CON * ldrvcon[NDRV]; .globl ldrvsel_ / extern saddr_t ldrvsel[NDRV]; .globl ldrvics_ / extern saddr_t ldrvics[16]; .globl ldrvipc_ / extern void (*ldrvipc[16])(); //////// / / Shared Data / //////// .shrd ldrvint_: / Loadable Driver Interrupt Entry Points. .word ld_intr0 .word ld_intr1 .word ld_intr2 .word ld_intr3 .word ld_intr4 .word ld_intr5 .word ld_intr6 .word ld_intr7 .word ld_intr8 .word ld_intr9 .word ld_intr10 .word ld_intr11 .word ld_intr12 .word ld_intr13 .word ld_intr14 .word ld_intr15 //////// / / Private Data / //////// .prvd .shri //////// / / Driver Configuration: Offsets to Function Pointers / //////// C_OPEN=4 C_CLOSE=6 C_BLOCK=8 C_READ=10 C_WRITE=12 C_IOCTL=14 C_POWER=16 C_TIMER=18 C_LOAD=20 C_ULOAD=22 C_POLL=24 //////// / / ld_xcall( fp ) - invoke far function. / int (far *fp)(); / //////// ld_xcall_: cli push bp mov bp, sp xcall 4(bp) pop bp ret //////// / / call a driver function from the kernel / sel - CS selector for the driver / fn - offset in the driver of the function we want / arg[1-3] - optional arguments / / ld_call(sel, fn, arg1, arg2, arg3) / int sel; / int (*fn)(void); / int arg1, arg2, arg3; / //////// / stack when ld_call() is called: / arg3 / arg2 / arg1 / fn / sel / return IP ld_call_: / PARAMETERS (arg[1-3]) MUST BE FOUND AT 4(BP). push bp / DRIVER RESIDENT CODE RELIES ON THIS. / lea bp, 4(sp) / this is what the next 2 instructions do mov bp, sp add bp, $4 / push 0(bp) / Push sel to allow far call push $DRV_J / / mov ax, 2(bp) / Push fn / xcall -8(bp) / Invoke driver interface, which will / in turn invoke driver function. / lea sp, -4(bp) / pop bp / ret / //////// / / / ldtimcall( arg, tp ) - service timed far function. / //////// ldtimcall_: / push bp / mov bp, sp / / mov bx, 6(bp) / mov ax, T_LDRV+2(bx) / push ax / Loadable driver code selector. push $DRV_J / Loadable driver invocation offset. mov ax, T_LDRV(bx) / Desired far function. / xcall -4(bp) / / mov sp, bp / pop bp / ret //////// / / xcalled( f, args ) / int (*f)(); / / Input: AX is pointer to kernel function to be invoked. / / Action: Perform a near call to the specified kernel function, / passing 6 words as optional arguments. / Perform a far return. / / Notes: Invoked by far call from loadable device driver. / //////// xcalled: / 6(bp) = grand-parent IP. push bp / 4(bp) = parent CS mov bp, sp / 2(bp) = parent IP / AX = destination function. push 20(bp) / Arg 7 / push 18(bp) / Arg 6 / push 16(bp) / Arg 5 / push 14(bp) / Arg 4 / push 12(bp) / Arg 3 / push 10(bp) / Arg 2 / push 8(bp) / Arg 1 / icall ax / / mov sp, bp / Return to loadable driver. pop bp / xret / //////// / / ld_open( dev, mode ) - Open Routine. / dev_t dev; / int mode; / //////// ld_open_: / PARAMETERS MUST REMAIN AT 4(BP). push bp / DRIVER RESIDENT CODE RELIES ON THIS. mov bp, sp / / sub bx, bx / Calculate major device number * 2. movb bl, 5(bp) / shl bx, $1 / / mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP. jcxz 0f / push cx / push $DRV_J / Loadable driver invocation offset. / mov bx, ldrvcon_(bx)/ Identify driver configuration. or bx, bx / je 0f / / mov ax, C_OPEN(bx) / Identify driver function to be invoked. or ax, ax / je 0f / / xcall -4(bp) / Invoke driver interface, which will / in turn invoke driver function. / mov sp, bp / Return to caller. pop bp / ret / 0: mov sp, bp pop bp jmp nonedev_ //////// / / ld_close( dev ) - Close Routine. / dev_t dev; / //////// ld_close_: / PARAMETERS MUST REMAIN AT 4(BP). push bp / DRIVER RESIDENT CODE RELIES ON THIS. mov bp, sp / / sub bx, bx / Calculate major device number * 2. movb bl, 5(bp) / shl bx, $1 / / mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP. jcxz 0f / push cx / push $DRV_J / Loadable driver invocation offset. / mov bx, ldrvcon_(bx)/ Identify driver configuration. or bx, bx / je 0f / / mov ax, C_CLOSE(bx) / Identify driver function to be invoked. or ax, ax / je 0f / / xcall -4(bp) / Invoke driver interface, which will / in turn invoke driver function. / mov sp, bp / Return to caller. pop bp / ret / 0: mov sp, bp pop bp jmp nonedev_ //////// / / ld_read( dev, iop ) - Read Routine. / dev_t dev; / IO * iop; / //////// ld_read_: / PARAMETERS MUST REMAIN AT 4(BP). push bp / DRIVER RESIDENT CODE RELIES ON THIS. mov bp, sp / / sub bx, bx / Calculate major device number * 2. movb bl, 5(bp) / shl bx, $1 / / mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP. jcxz 0f / push cx / push $DRV_J / Loadable driver invocation offset. / mov bx, ldrvcon_(bx)/ Identify driver configuration. or bx, bx / je 0f / / mov ax, C_READ(bx) / Identify driver function to be invoked. or ax, ax / je 0f / / xcall -4(bp) / Invoke driver interface, which will / in turn invoke driver function. / mov sp, bp / Return to caller. pop bp / ret / 0: mov sp, bp pop bp jmp nonedev_ /////// / / ld_write( dev, iop ) - Write Routine. / dev_t dev; / IO * iop; / //////// ld_write_: / PARAMETERS MUST REMAIN AT 4(BP). push bp / DRIVER RESIDENT CODE RELIES ON THIS. mov bp, sp / / sub bx, bx / Calculate major device number * 2. movb bl, 5(bp) / shl bx, $1 / / mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP. jcxz 0f / push cx / push $DRV_J / Loadable driver invocation offset. / mov bx, ldrvcon_(bx)/ Identify driver configuration. or bx, bx / je 0f / / mov ax, C_WRITE(bx) / Identify driver function to be invoked. or ax, ax / je 0f / / xcall -4(bp) / Invoke driver interface, which will / in turn invoke driver function. / mov sp, bp / Return to caller. pop bp / ret / 0: mov sp, bp pop bp jmp nonedev_ /////// / / ld_block( bp ) - Block Routine. / BUF * bp; / //////// ld_block_: / PARAMETERS MUST REMAIN AT 4(BP). push bp / DRIVER RESIDENT CODE RELIES ON THIS. mov bp, sp / / mov bx, 4(bp) / Calculate major device number * 2. movb bl, B_DEV+1(bx) / subb bh, bh / shl bx, $1 / / mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP. jcxz 0f / push cx / push $DRV_J / Loadable driver invocation offset. / mov bx, ldrvcon_(bx)/ Identify driver configuration. or bx, bx / je 0f / / mov ax, C_BLOCK(bx) / Identify driver function to be invoked. or ax, ax / je 0f / / xcall -4(bp) / Invoke driver interface, which will / in turn invoke driver function. / mov sp, bp / Return to caller. pop bp / ret / 0: mov bx, 4(bp) / bp->b_flag |= BFERR. or B_FLAG(bx),$BFERR / mov sp, bp / pop bp / jmp bdone_ / bdone(bp); //////// / / ld_ioctl( dev, iop ) - Ioctl Routine. / dev_t dev; / IO * iop; / //////// ld_ioctl_: / PARAMETERS MUST REMAIN AT 4(BP). push bp / DRIVER RESIDENT CODE RELIES ON THIS. mov bp, sp / / sub bx, bx / Calculate major device number * 2. movb bl, 5(bp) / shl bx, $1 / / mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP. jcxz 0f / push cx / push $DRV_J / Loadable driver invocation offset. / mov bx, ldrvcon_(bx)/ Identify driver configuration. or bx, bx / je 0f / / mov ax, C_IOCTL(bx) / Identify driver function to be invoked. or ax, ax / je 0f / / xcall -4(bp) / Invoke driver interface, which will / in turn invoke driver function. / mov sp, bp / Return to caller. pop bp / ret / 0: mov sp, bp pop bp jmp nonedev_ //////// / / ld_power( dev ) - Powerfail Routine. / dev_t dev; / //////// ld_power_: / PARAMETERS MUST REMAIN AT 4(BP). push bp / DRIVER RESIDENT CODE RELIES ON THIS. mov bp, sp / / sub bx, bx / Calculate major device number * 2. movb bl, 5(bp) / shl bx, $1 / / mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP. jcxz 0f / push cx / push $DRV_J / Loadable driver invocation offset. / mov bx, ldrvcon_(bx)/ Identify driver configuration. or bx, bx / je 0f / / mov ax, C_POWER(bx) / Identify driver function to be invoked. or ax, ax / je 0f / / xcall -4(bp) / Invoke driver interface, which will / in turn invoke driver function. / mov sp, bp / Return to caller. pop bp / ret / 0: mov sp, bp pop bp jmp nonedev_ //////// / / ld_time( dev ) - Timer Routine. / dev_t dev; / //////// ld_time_: / PARAMETERS MUST REMAIN AT 4(BP). push bp / DRIVER RESIDENT CODE RELIES ON THIS. mov bp, sp / / sub bx, bx / Calculate major device number * 2. movb bl, 5(bp) / shl bx, $1 / / mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP. jcxz 0f / push cx / push $DRV_J / Loadable driver invocation offset. / mov bx, ldrvcon_(bx)/ Identify driver configuration. or bx, bx / je 0f / / mov ax, C_TIMER(bx) / Identify driver function to be invoked. or ax, ax / je 0f / / xcall -4(bp) / Invoke driver interface, which will / in turn invoke driver function. / mov sp, bp / Return to caller. pop bp / ret / 0: mov sp, bp pop bp jmp nonedev_ //////// / / ld_poll( dev, ev, msec ) - Poll Routine. / dev_t dev; / int ev; / int msec; / //////// ld_poll_: / PARAMETERS MUST REMAIN AT 4(BP). push bp / DRIVER RESIDENT CODE RELIES ON THIS. mov bp, sp / / sub bx, bx / Calculate major device number * 2. movb bl, 5(bp) / shl bx, $1 / / mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP. jcxz 0f / push cx / push $DRV_J / Loadable driver invocation offset. / mov bx, ldrvcon_(bx)/ Identify driver configuration. or bx, bx / je 0f / / mov ax, C_POLL(bx) / Identify driver function to be invoked. or ax, ax / je 0f / / xcall -4(bp) / Invoke driver interface, which will / in turn invoke driver function. / mov sp, bp / Return to caller. pop bp / ret / 0: mov sp, bp pop bp jmp nonedev_ //////// / / Loadable Driver Interrupt Entry Points. / / Invoked by Coherent to service specific interrupt. / Identifies which loadable driver interrupt vector to be used. / Invokes interrupt handler which will do far call to loadable driver. / //////// ld_intr0: mov bx, $0 / jmp ld_intr / ld_intr1: mov bx, $2 / jmp ld_intr / ld_intr2: mov bx, $4 / jmp ld_intr / ld_intr3: mov bx, $6 / jmp ld_intr / ld_intr4: mov bx, $8 / jmp ld_intr / ld_intr5: mov bx, $10 / jmp ld_intr / ld_intr6: mov bx, $12 / jmp ld_intr / ld_intr7: mov bx, $14 / jmp ld_intr / ld_intr8: mov bx, $16 / jmp ld_intr / ld_intr9: mov bx, $18 / jmp ld_intr / ld_intr10: mov bx, $20 / jmp ld_intr / ld_intr11: mov bx, $22 / jmp ld_intr / ld_intr12: mov bx, $24 / jmp ld_intr / ld_intr13: mov bx, $26 / jmp ld_intr / ld_intr14: mov bx, $28 / jmp ld_intr / ld_intr15: mov bx, $30 / jmp ld_intr / //////// / / Loadable driver interrupt handler. / / / Input: bx = interrupt number * 2. / //////// ld_intr: push bp / mov bp, sp / / mov cx,ldrvics_(bx) / Prepare driver interface CS:IP. jcxz 0f / push cx / push $DRV_J / Loadable driver invocation offset. / mov ax,ldrvipc_(bx) / Identify interrupt handler to be invoked. or ax, ax / je 0f / / xcall -4(bp) / Invoke driver interface, which will / in turn invoke driver function. / 0: mov sp, bp / pop bp / ret /
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.