1/* $NetBSD: bsd_fdintr.s,v 1.2 2000/04/15 03:08:13 mrg Exp $ */ 2 3/* 4 * Copyright (c) 1995 Paul Kranenburg 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Paul Kranenburg. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 */ 33 34#ifndef FDC_C_HANDLER 35#include "assym.h" 36#include <sparc64/sparc64/intreg.h> 37#include <sparc64/dev/fdreg.h> 38#include <sparc64/dev/fdvar.h> 39#include <sparc64/dev/auxioreg.h> 40#include <machine/asm.h> 41/* XXX this goes in a header file -- currently, it's hidden in locore.s */ 42#define INTREG_ADDR 0xf8002000 43 44/* Timeout waiting for chip ready */ 45#define POLL_TIMO 100000 46 47/* 48 * register mnemonics. note overlapping assignments. 49 */ 50#define R_fdc %l0 51#define R_msr %l1 52#define R_fifo %l2 53#define R_buf %l3 54#define R_tc %l4 55#define R_stat %l3 56#define R_nstat %l4 57#define R_stcnt %l5 58/* use %l6 and %l7 as short term temporaries */ 59 60 61 .seg "data" 62 .align 8 63 .global _C_LABEL(fdciop) 64/* A save haven for three precious registers */ 65save_l: 66 .word 0 67 .word 0 68 .word 0 69/* Pointer to a `struct fdcio', set in fd.c */ 70_C_LABEL(fdciop): 71 .word 0 72 73 .seg "text" 74 .align 4 75 .global _C_LABEL(fdchwintr) 76 77_C_LABEL(fdchwintr): 78 set save_l, %l7 79 std %l0, [%l7] 80 st %l2, [%l7 + 8] 81 82 ! tally interrupt 83 sethi %hi(_C_LABEL(cnt)+V_INTR), %l7 84 ld [%l7 + %lo(_C_LABEL(cnt)+V_INTR)], %l6 85 inc %l6 86 st %l6, [%l7 + %lo(_C_LABEL(cnt)+V_INTR)] 87 88 ! load fdc, if it's NULL there's nothing to do: schedule soft interrupt 89 sethi %hi(_C_LABEL(fdciop)), %l7 90 ld [%l7 + %lo(_C_LABEL(fdciop))], R_fdc 91 92 ! tally interrupt 93 ld [R_fdc + FDC_EVCNT], %l6 94 inc %l6 95 st %l6, [R_fdc + FDC_EVCNT] 96 97 ! load chips register addresses 98 ld [R_fdc + FDC_REG_MSR], R_msr ! get chip MSR reg addr 99 ld [R_fdc + FDC_REG_FIFO], R_fifo ! get chip FIFO reg addr 100 !!ld [R_fdc + FDC_REG_DOR], R_dor ! get chip DOR reg addr 101 102 ! find out what we are supposed to do 103 ld [R_fdc + FDC_ISTATE], %l7 ! examine flags 104 cmp %l7, ISTATE_SENSEI 105 be sensei 106 nop 107 cmp %l7, ISTATE_DMA 108 bne spurious 109 nop 110 111 ! pseudo DMA 112 ld [R_fdc + FDC_TC], R_tc ! residual count 113 ld [R_fdc + FDC_DATA], R_buf ! IO buffer 114 115 ldub [R_msr], %l7 ! get MSR value 116nextc: 117 btst NE7_RQM, %l7 ! room in fifo? 118 bnz,a 0f 119 btst NE7_NDM, %l7 ! overrun? 120 121 ! we filled/emptied the FIFO; update fdc->sc_buf & fdc->sc_tc 122 st R_tc, [R_fdc + FDC_TC] 123 b x 124 st R_buf, [R_fdc + FDC_DATA] 125 1260: 127 bz resultphase ! overrun/underrun 128 btst NE7_DIO, %l7 ! IO direction 129 bz 1f 130 deccc R_tc 131 ldub [R_fifo], %l7 ! reading: 132 b 2f 133 stb %l7, [R_buf] ! *fdc->sc_bufp = *reg_fifo 134 1351: 136 ldub [R_buf], %l7 ! writing: 137 stb %l7, [R_fifo] ! *reg_fifo = *fdc->sc_bufp 1382: 139 inc R_buf ! fdc->sc_bufp++ 140 bne,a nextc ! if (--fdc->sc_tc) goto ... 141 ldub [R_msr], %l7 ! get MSR value 142 143 ! xfer done: update fdc->sc_buf & fdc->sc_tc, mark istate IDLE 144 st R_tc, [R_fdc + FDC_TC] 145 st R_buf, [R_fdc + FDC_DATA] 146 147 ! flip TC bit in auxreg 148 sethi %hi(_C_LABEL(auxio_reg)), %l6 149 ld [%l6 + %lo(_C_LABEL(auxio_reg))], %l6 150 ldub [%l6], %l7 151 or %l7, AUXIO_LED_MB1|AUXIO_LED_FTC, %l7 152 stb %l7, [%l6] 153 154 ! we have some time to kill; anticipate on upcoming 155 ! result phase. 156 add R_fdc, FDC_STATUS, R_stat ! &fdc->sc_status[0] 157 mov -1, %l7 158 st %l7, [R_fdc + FDC_NSTAT] ! fdc->sc_nstat = -1; 159 160 ldub [%l6], %l7 161 andn %l7, AUXIO_LED_FTC, %l7 162 or %l7, AUXIO_LED_MB1, %l7 163 stb %l7, [%l6] 164 b resultphase1 165 nop 166 167spurious: 168 mov ISTATE_SPURIOUS, %l7 169 st %l7, [R_fdc + FDC_ISTATE] 170 b,a ssi 171 172sensei: 173 ldub [R_msr], %l7 174 set POLL_TIMO, %l6 1751: deccc %l6 ! timeout? 176 be ssi 177 and %l7, (NE7_RQM | NE7_DIO | NE7_CB), %l7 178 cmp %l7, NE7_RQM 179 bne,a 1b ! loop till chip ready 180 ldub [R_msr], %l7 181 mov NE7CMD_SENSEI, %l7 182 stb %l7, [R_fifo] 183 184resultphase: 185 ! prepare for result phase 186 add R_fdc, FDC_STATUS, R_stat ! &fdc->sc_status[0] 187 mov -1, %l7 188 st %l7, [R_fdc + FDC_NSTAT] ! fdc->sc_nstat = -1; 189 190resultphase1: 191 clr R_stcnt 192 ldub [R_msr], %l7 193 set POLL_TIMO, %l6 1941: deccc %l6 ! timeout? 195 be ssi 196 and %l7, (NE7_RQM | NE7_DIO | NE7_CB), %l7 197 cmp %l7, NE7_RQM 198 be 3f ! done 199 cmp %l7, (NE7_RQM | NE7_DIO | NE7_CB) 200 bne,a 1b ! loop till chip ready 201 ldub [R_msr], %l7 202 203 cmp R_stcnt, FDC_NSTATUS ! status overrun? 204 bge 2f ! if so, load but dont store 205 ldub [R_fifo], %l7 ! load the status byte 206 stb %l7, [R_stat] 207 inc R_stat 208 inc R_stcnt 2092: b 1b 210 ldub [R_msr], %l7 211 2123: 213 ! got status, update sc_nstat and mark istate IDLE 214 st R_stcnt, [R_fdc + FDC_NSTAT] 215 mov ISTATE_IDLE, %l7 216 st %l7, [R_fdc + FDC_ISTATE] 217 218ssi: 219 ! set software interrupt 220 sethi %hi(INTREG_ADDR), %l7 221 ldsb [%l7 + %lo(INTREG_ADDR)], %l6 222 or %l6, IE_L4, %l6 223 stb %l6, [%l7 + %lo(INTREG_ADDR)] 224 225x: 226 /* 227 * Restore psr -- note: psr delay honored by pc restore loads. 228 */ 229 set save_l, %l7 230 ldd [%l7], %l0 231 mov %l0, %psr 232 nop 233 ld [%l7 + 8], %l2 234 jmp %l1 235 rett %l2 236#endif 237