[BACK]Return to bsd_fdintr.s CVS log [TXT][DIR] Up to [local] / sys / arch / sparc / sparc

Annotation of sys/arch/sparc/sparc/bsd_fdintr.s, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: bsd_fdintr.s,v 1.11 2004/09/29 07:35:13 miod Exp $    */
                      2: /*     $NetBSD: bsd_fdintr.s,v 1.11 1997/04/07 21:00:36 pk Exp $ */
                      3:
                      4: /*
                      5:  * Copyright (c) 1995 Paul Kranenburg
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *      This product includes software developed by Paul Kranenburg.
                     19:  * 4. The name of the author may not be used to endorse or promote products
                     20:  *    derived from this software without specific prior written permission
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     23:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     24:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     25:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     26:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     27:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     28:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     29:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     30:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     31:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     32:  *
                     33:  */
                     34:
                     35: #ifndef FDC_C_HANDLER
                     36: #include "assym.h"
                     37: #include <machine/param.h>
                     38: #include <machine/psl.h>
                     39: #include <machine/asm.h>
                     40: #include <sparc/sparc/intreg.h>
                     41: #include <sparc/sparc/auxioreg.h>
                     42: #include <sparc/sparc/vaddrs.h>
                     43: #include <sparc/dev/fdreg.h>
                     44: #include <sparc/dev/fdvar.h>
                     45:
                     46: #define FD_SET_SWINTR_4C                               \
                     47:        sethi   %hi(INTRREG_VA), %l5;                   \
                     48:        ldub    [%l5 + %lo(INTRREG_VA)], %l6;           \
                     49:        or      %l6, IE_L4, %l6;                        \
                     50:        stb     %l6, [%l5 + %lo(INTRREG_VA)]
                     51:
                     52: ! raise(0,IPL_FDSOFT)  ! NOTE: CPU#0 and IPL_FDSOFT=4
                     53: #define FD_SET_SWINTR_4M                               \
                     54:        sethi   %hi(1 << (16 + 4)), %l5;                \
                     55:        set     ICR_PI_SET, %l6;                        \
                     56:        st      %l5, [%l6]
                     57:
                     58: /* set software interrupt */
                     59: #if (defined(SUN4) || defined(SUN4C)) && !defined(SUN4M)
                     60: #define FD_SET_SWINTR  FD_SET_SWINTR_4C
                     61: #elif !(defined(SUN4) || defined(SUN4C)) && defined(SUN4M)
                     62: #define FD_SET_SWINTR  FD_SET_SWINTR_4M
                     63: #else
                     64: #define FD_SET_SWINTR                                  \
                     65:        sethi   %hi(_C_LABEL(cputyp)), %l5;             \
                     66:        ld      [%l5 + %lo(_C_LABEL(cputyp))], %l5;     \
                     67:        cmp     %l5, CPU_SUN4M;                         \
                     68:        be      8f;                                     \
                     69:        FD_SET_SWINTR_4C;                               \
                     70:        ba,a    9f;                                     \
                     71: 8:                                                     \
                     72:        FD_SET_SWINTR_4M;                               \
                     73: 9:
                     74: #endif
                     75:
                     76: ! flip TC bit in auxreg
                     77: ! assumes %l6 remains unchanged between ASSERT and DEASSERT
                     78: #define FD_ASSERT_TC_4C                                        \
                     79:        sethi   %hi(AUXREG_VA), %l6;                    \
                     80:        ldub    [%l6 + %lo(AUXREG_VA) + 3], %l7;        \
                     81:        or      %l7, AUXIO4C_MB1|AUXIO4C_FTC, %l7;      \
                     82:        stb     %l7, [%l6 + %lo(AUXREG_VA) + 3];
                     83:
                     84: #define FD_DEASSERT_TC_4C                              \
                     85:        ldub    [%l6 + %lo(AUXREG_VA) + 3], %l7;        \
                     86:        andn    %l7, AUXIO4C_FTC, %l7;                  \
                     87:        or      %l7, AUXIO4C_MB1, %l7;                  \
                     88:        stb     %l7, [%l6 + %lo(AUXREG_VA) + 3];
                     89:
                     90: ! flip TC bit in auxreg
                     91: #define FD_ASSERT_TC_4M                                        \
                     92:        sethi   %hi(AUXREG_VA), %l6;                    \
                     93:        ldub    [%l6 + %lo(AUXREG_VA) + 3], %l7;        \
                     94:        or      %l7, AUXIO4M_MB1|AUXIO4M_FTC, %l7;      \
                     95:        stb     %l7, [%l6 + %lo(AUXREG_VA) + 3];
                     96:
                     97: #define FD_DEASSERT_TC_4M
                     98:
                     99: /*
                    100:  * flip TC bit in auxreg
                    101:  * assumes %l5 remains unchanged between ASSERT and DEASSERT
                    102:  */
                    103: #if (defined(SUN4) || defined(SUN4C)) && !defined(SUN4M)
                    104: #define FD_ASSERT_TC           FD_ASSERT_TC_4C
                    105: #define FD_DEASSERT_TC         FD_DEASSERT_TC_4C
                    106: #elif !(defined(SUN4) || defined(SUN4C)) && defined(SUN4M)
                    107: #define FD_ASSERT_TC           FD_ASSERT_TC_4M
                    108: #define FD_DEASSERT_TC         FD_DEASSERT_TC_4M
                    109: #else
                    110: #define FD_ASSERT_TC                                   \
                    111:        sethi   %hi(_C_LABEL(cputyp)), %l5;             \
                    112:        ld      [%l5 + %lo(_C_LABEL(cputyp))], %l5;     \
                    113:        cmp     %l5, CPU_SUN4M;                         \
                    114:        be      8f;                                     \
                    115:         nop;                                           \
                    116:        FD_ASSERT_TC_4C;                                \
                    117:        ba,a    9f;                                     \
                    118: 8:                                                     \
                    119:        FD_ASSERT_TC_4M;                                \
                    120: 9:
                    121: #define FD_DEASSERT_TC                                 \
                    122:        cmp     %l5, CPU_SUN4M;                         \
                    123:        be      8f;                                     \
                    124:         nop;                                           \
                    125:        FD_DEASSERT_TC_4C;                              \
                    126:        ba,a    9f;                                     \
                    127: 8:                                                     \
                    128:        FD_DEASSERT_TC_4M;                              \
                    129: 9:
                    130: #endif
                    131:
                    132:
                    133: /* Timeout waiting for chip ready */
                    134: #define POLL_TIMO      100000
                    135:
                    136: /*
                    137:  * register mnemonics. note overlapping assignments.
                    138:  */
                    139: #define R_fdc  %l0
                    140: #define R_msr  %l1
                    141: #define R_fifo %l2
                    142: #define R_buf  %l3
                    143: #define R_tc   %l4
                    144: #define R_stat %l3
                    145: #define R_nstat        %l4
                    146: #define R_stcnt        %l5
                    147: /* use %l6 and %l7 as short term temporaries */
                    148:
                    149:
                    150:        .seg    "data"
                    151:        .align  8
                    152:        .global _C_LABEL(fdciop)
                    153: /* A save haven for three precious registers */
                    154: save_l:
                    155:        .word   0
                    156:        .word   0
                    157:        .word   0
                    158: /* Pointer to a `struct fdcio', set in fd.c */
                    159: _C_LABEL(fdciop):
                    160:        .word   0
                    161:
                    162:        .seg    "text"
                    163:        .align  4
                    164:        .global _C_LABEL(fdchwintr)
                    165:
                    166: _C_LABEL(fdchwintr):
                    167:        set     save_l, %l7
                    168:        std     %l0, [%l7]
                    169:        st      %l2, [%l7 + 8]
                    170:
                    171:        ! tally interrupt
                    172:        sethi   %hi(_C_LABEL(uvmexp)+V_INTR), %l7
                    173:        ld      [%l7 + %lo(_C_LABEL(uvmexp)+V_INTR)], %l6
                    174:        inc     %l6
                    175:        st      %l6, [%l7 + %lo(_C_LABEL(uvmexp)+V_INTR)]
                    176:
                    177:        ! load fdc, if it's NULL there's nothing to do: schedule soft interrupt
                    178:        sethi   %hi(_C_LABEL(fdciop)), %l7
                    179:        ld      [%l7 + %lo(_C_LABEL(fdciop))], R_fdc
                    180:
                    181:        ! tally interrupt
                    182:        ldd     [R_fdc + FDC_COUNT], %l4
                    183:        inccc   %l4
                    184:        addx    %l4, 0, %l4
                    185:        std     %l4, [R_fdc + FDC_COUNT]
                    186:
                    187:        ! load chips register addresses
                    188:        ld      [R_fdc + FDC_REG_MSR], R_msr    ! get chip MSR reg addr
                    189:        ld      [R_fdc + FDC_REG_FIFO], R_fifo  ! get chip FIFO reg addr
                    190:        !!ld    [R_fdc + FDC_REG_DOR], R_dor    ! get chip DOR reg addr
                    191:
                    192:        ! find out what we are supposed to do
                    193:        ld      [R_fdc + FDC_ITASK], %l7        ! get task from fdc
                    194:        cmp     %l7, FDC_ITASK_SENSEI
                    195:        be      sensei
                    196:         !nop
                    197:        cmp     %l7, FDC_ITASK_RESULT
                    198:        be      resultphase
                    199:         !nop
                    200:        cmp     %l7, FDC_ITASK_DMA
                    201:        bne,a   ssi                             ! a spurious interrupt
                    202:         mov    FDC_ISTATUS_SPURIOUS, %l7       ! set status and post sw intr
                    203:
                    204:        ! pseudo DMA
                    205:        ld      [R_fdc + FDC_TC], R_tc          ! residual count
                    206:        ld      [R_fdc + FDC_DATA], R_buf       ! IO buffer
                    207:
                    208:        ldub    [R_msr], %l7                    ! get MSR value
                    209: nextc:
                    210:        btst    NE7_RQM, %l7                    ! room in fifo?
                    211:        bnz,a   0f
                    212:         btst   NE7_NDM, %l7                    ! overrun?
                    213:
                    214:        ! we filled/emptied the FIFO; update fdc->sc_buf & fdc->sc_tc
                    215:        st      R_tc, [R_fdc + FDC_TC]
                    216:        b       x
                    217:        st      R_buf, [R_fdc + FDC_DATA]
                    218:
                    219: 0:
                    220:        bz      resultphase                     ! overrun/underrun
                    221:        btst    NE7_DIO, %l7                    ! IO direction
                    222:        bz      1f
                    223:         deccc  R_tc
                    224:        ldub    [R_fifo], %l7                   ! reading:
                    225:        b       2f
                    226:        stb     %l7, [R_buf]                    !    *fdc->sc_bufp = *reg_fifo
                    227:
                    228: 1:
                    229:        ldub    [R_buf], %l7                    ! writing:
                    230:        stb     %l7, [R_fifo]                   !    *reg_fifo = *fdc->sc_bufp
                    231: 2:
                    232:        inc     R_buf                           ! fdc->sc_bufp++
                    233:        bne,a   nextc                           ! if (--fdc->sc_tc) goto ...
                    234:         ldub   [R_msr], %l7                    ! get MSR value
                    235:
                    236:        ! xfer done: update fdc->sc_buf & fdc->sc_tc, mark istate DONE
                    237:        st      R_tc, [R_fdc + FDC_TC]
                    238:        st      R_buf, [R_fdc + FDC_DATA]
                    239:
                    240:        ! flip TC bit in auxreg
                    241:        FD_ASSERT_TC
                    242:
                    243:        ! we have some time to kill; anticipate on upcoming
                    244:        ! result phase.
                    245:        add     R_fdc, FDC_STATUS, R_stat       ! &fdc->sc_status[0]
                    246:        mov     -1, %l7
                    247:        st      %l7, [R_fdc + FDC_NSTAT]        ! fdc->sc_nstat = -1;
                    248:
                    249:        FD_DEASSERT_TC
                    250:        b,a     resultphase1
                    251:
                    252: sensei:
                    253:        ldub    [R_msr], %l7
                    254:        set     POLL_TIMO, %l6
                    255: 1:     deccc   %l6                             ! timeout?
                    256:        be,a    ssi                             ! if so, set status
                    257:         mov    FDC_ISTATUS_ERROR, %l7          ! and post sw interrupt
                    258:        and     %l7, (NE7_RQM | NE7_DIO | NE7_CB), %l7
                    259:        cmp     %l7, NE7_RQM
                    260:        bne,a   1b                              ! loop till chip ready
                    261:         ldub   [R_msr], %l7
                    262:        mov     NE7CMD_SENSEI, %l7
                    263:        stb     %l7, [R_fifo]
                    264:
                    265: resultphase:
                    266:        ! prepare for result phase
                    267:        add     R_fdc, FDC_STATUS, R_stat       ! &fdc->sc_status[0]
                    268:        mov     -1, %l7
                    269:        st      %l7, [R_fdc + FDC_NSTAT]        ! fdc->sc_nstat = -1;
                    270:
                    271: resultphase1:
                    272:        clr     R_stcnt
                    273:        ldub    [R_msr], %l7
                    274:        set     POLL_TIMO, %l6
                    275: 1:     deccc   %l6                             ! timeout?
                    276:        be,a    ssi                             ! if so, set status
                    277:         mov    FDC_ISTATUS_ERROR, %l7          ! and post sw interrupt
                    278:        and     %l7, (NE7_RQM | NE7_DIO | NE7_CB), %l7
                    279:        cmp     %l7, NE7_RQM
                    280:        be      3f                              ! done
                    281:        cmp     %l7, (NE7_RQM | NE7_DIO | NE7_CB)
                    282:        bne,a   1b                              ! loop till chip ready
                    283:         ldub   [R_msr], %l7
                    284:
                    285:        cmp     R_stcnt, FDC_NSTATUS            ! status overrun?
                    286:        bge     2f                              ! if so, load but dont store
                    287:        ldub    [R_fifo], %l7                   ! load the status byte
                    288:        stb     %l7, [R_stat]
                    289:        inc     R_stat
                    290:        inc     R_stcnt
                    291: 2:     b       1b
                    292:         ldub   [R_msr], %l7
                    293:
                    294: 3:
                    295:        ! got status, update sc_nstat and mark istate DONE
                    296:        st      R_stcnt, [R_fdc + FDC_NSTAT]
                    297:        mov     FDC_ISTATUS_DONE, %l7
                    298:
                    299: ssi:
                    300:        ! set software interrupt
                    301:        ! enter here with status in %l7
                    302:        st      %l7, [R_fdc + FDC_ISTATUS]
                    303:        FD_SET_SWINTR
                    304:
                    305: x:
                    306:        /*
                    307:         * Restore psr -- note: psr delay honored by pc restore loads.
                    308:         */
                    309:        set     save_l, %l7
                    310:        ldd     [%l7], %l0
                    311:        mov     %l0, %psr
                    312:         nop
                    313:        ld      [%l7 + 8], %l2
                    314:        jmp     %l1
                    315:        rett    %l2
                    316: #endif

CVSweb