Annotation of coherent/d/286_KERNEL/USRSRC/286/defer.s, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.