NetBSD/sys/arch/arm26/ioc/if_eca_fiq.S

156 lines
4.7 KiB
ArmAsm

/* $NetBSD: if_eca_fiq.S,v 1.1 2001/09/10 23:41:49 bjh21 Exp $ */
/*-
* Copyright (c) 2001 Ben Harris
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <machine/asm.h>
RCSID("$NetBSD: if_eca_fiq.S,v 1.1 2001/09/10 23:41:49 bjh21 Exp $")
#include <dev/ic/mc6854reg.h>
#include <arch/arm26/ioc/if_ecavar.h>
#include "assym.h"
/*
* Econet Rx FIQ handler registers:
* R8: Address of 6854
* R9: Data buffer address
* R10: Space left in buffer
* R11: struct eca_rxstate pointer
* R12: Scratch
* R13: Scratch
*/
ENTRY(eca_fiqhandler_rx)
/* If there's something in the Rx FIFO, read it now. */
ldrb r12, [r8, #(MC6854_SR2 << 2)]
tst r12, #MC6854_SR2_RDA
beq Leca_rx_nodata
Leca_rx_loop:
ldrb r12, [r8, #(MC6854_RXFIFO << 2)]
strb r12, [r9], #1
subs r10, r10, #1
beq Leca_rx_counter /* Rx buffer full */
ldrb r12, [r8, #(MC6854_SR2 << 2)]
tst r12, #MC6854_SR2_RDA /* More data? */
bne Leca_rx_loop
Leca_rx_nodata:
teq r12, #0 /* No more status? */
subeqs pc, r14, #4 /* Return. */
tst r12, #MC6854_SR2_FV /* End of frame? */
ldrne r12, [r11, #ERX_FLAGS]
tstne r12, #ERXF_FLAGFILL /* Want flag fill? */
movne r12, #(MC6854_CR2_RTS | MC6854_CR2_F_M_IDLE)
strneb r12, [r8, #(MC6854_CR2 << 2)]
Leca_rx_downgrade:
ldr pc, Leca_rx_fiq_downgrade
Leca_rx_fiq_downgrade:
.word fiq_downgrade
Leca_rx_counter:
/* If we've already got the header, this indicates end-of-buffer. */
ldr r12, [r11, #ERX_FLAGS]
tst r12, #ERXF_GOTHDR
bne Leca_rx_full
ldrb r12, [r9, #-2]
ldrb r13, [r11, #ERX_MYADDR]
teq r12, r13 /* Our host */
ldreqb r12, [r9, #-1]
teqeq r12, #0 /* Local network? */
ldr r12, [r11, #ERX_FLAGS]
orrne r12, r12, #ERXF_GOTHDR
orreq r12, r12, #(ERXF_GOTHDR | ERXF_FLAGFILL)
str r12, [r11, #ERX_FLAGS]
ldr r12, [r11, #ERX_CURMBUF]
ldr r10, [r12, #M_LEN]
ldr r12, [r12, #M_DATA]
sub r12, r9, r12 /* Amount got already */
sub r10, r10, r12
subs pc, r14, #4
Leca_rx_full:
/* Rx buffer full. See if there's another mbuf in the chain. */
ldr r12, [r11, #ERX_CURMBUF]
ldr r12, [r12, #M_NEXT]
str r12, [r11, #ERX_CURMBUF]
teq r12, #0
beq Leca_rx_downgrade
ldr r9, [r12, #M_DATA]
ldr r10, [r12, #M_LEN]
subs pc, r14, #4
.global eca_efiqhandler_rx
_C_LABEL(eca_efiqhandler_rx):
/*
* Econet Tx FIQ handler registers:
* R8: Address of 6854
* R9: Data buffer address
* R10: Data left in buffer
* R11: struct eca_txstate pointer
* R12: Scratch
* R13: Scratch
*/
ENTRY(eca_fiqhandler_tx)
ldrb r12, [r8, #(MC6854_SR1 << 2)]
tst r12, #MC6854_SR1_TDRA
beq Leca_tx_nospace
Leca_tx_loop:
ldrb r12, [r9], #1
strb r12, [r8, #(MC6854_TXFIFOFC << 2)]
subs r10, r10, #1
beq Leca_tx_nodata
ldrb r12, [r8, #(MC6854_SR1 << 2)]
tst r12, #MC6854_SR1_TDRA
bne Leca_tx_loop
Leca_tx_nospace:
tst r12, #MC6854_SR1_IRQ /* No more status? */
subeqs pc, r14, #4 /* Return. */
ldr pc, Leca_tx_fiq_downgrade
Leca_tx_nodata:
/* We get here when the current data block is empty. */
ldr r12, [r11, #ETX_CURMBUF]
ldr r12, [r12, #M_NEXT]
str r12, [r11, #ETX_CURMBUF]
teq r12, #0 /* Another mbuf? */
moveq r12, #(MC6854_CR2_TX_LAST) /* If not, finish frame... */
streqb r12, [r8, #(MC6854_CR2 << 2)]
ldreq pc, Leca_tx_fiq_downgrade /* ... and report back. */
ldr r9, [r12, #M_DATA] /* Line up next mbuf. */
ldr r10, [r12, #M_LEN]
subs pc, r14, #4
Leca_tx_fiq_downgrade:
.word fiq_downgrade
.global eca_efiqhandler_tx
_C_LABEL(eca_efiqhandler_tx):