📄 wanxlfw.s
字号:
cmpl #TX_BUFFERS, tx_count(%d0) beq tx_ret // all DB's = descs in use movel tx_out(%d0), %d1 movel %d1, %d2 // D1 = D2 = tx_out BD# = desc# mulul #DESC_LENGTH, %d2 // D2 = TX desc offset addl ch_status_addr(%d0), %d2 addl #STATUS_TX_DESCS, %d2 // D2 = TX desc address cmpl #PACKET_FULL, (%d2) // desc status bne tx_ret// queue it movel 4(%d2), %a0 // PCI address lsll #3, %d1 // BD is 8-bytes long addl tx_first_bd(%d0), %d1 // D1 = current tx_out BD addr movel 4(%d1), %a1 // A1 = dest address movel 8(%d2), %d2 // D2 = length movew %d2, 2(%d1) // length into BD memcpy_from_pci %a0, %a1, %d2 bsetl #31, (%d1) // CP go ahead// update tx_out and tx_count movel tx_out(%d0), %d1 addl #1, %d1 cmpl #TX_BUFFERS, %d1 bne tx_1 clrl %d1tx_1: movel %d1, tx_out(%d0) addl #1, tx_count(%d0) bra txtx_ret: rts/****************************** packet received ***********************/// Service receive buffers // D0 = 4 * port, D6 = doorbell to hostrx: movel rx_in(%d0), %d1 // D1 = rx_in BD# lsll #3, %d1 // BD is 8-bytes long addl rx_first_bd(%d0), %d1 // D1 = current rx_in BD address movew (%d1), %d2 // D2 = RX BD flags btstl #15, %d2 bne rx_ret // BD still empty btstl #1, %d2 bne rx_overrun tstw parity_bytes(%d0) bne rx_parity bclrl #2, %d2 // do not test for CRC errorsrx_parity: andw #0x0CBC, %d2 // mask status bits cmpw #0x0C00, %d2 // correct frame bne rx_bad_frame clrl %d3 movew 2(%d1), %d3 subw parity_bytes(%d0), %d3 // D3 = packet length cmpw #HDLC_MAX_MRU, %d3 bgt rx_bad_framerx_good_frame: movel rx_out, %d2 mulul #DESC_LENGTH, %d2 addl rx_descs_addr, %d2 // D2 = RX desc address cmpl #PACKET_EMPTY, (%d2) // desc stat bne rx_overrun movel %d3, 8(%d2) movel 4(%d1), %a0 // A0 = source address movel 4(%d2), %a1 tstl %a1 beq rx_ignore_data memcpy_to_pci %a0, %a1, %d3rx_ignore_data: movel packet_full(%d0), (%d2) // update desc stat// update D6 and rx_out bsetl #DOORBELL_FROM_CARD_RX, %d6 // signal host that RX completed movel rx_out, %d2 addl #1, %d2 cmpl #RX_QUEUE_LENGTH, %d2 bne rx_1 clrl %d2rx_1: movel %d2, rx_outrx_free_bd: andw #0xF000, (%d1) // clear CM and error bits bsetl #31, (%d1) // free BD// update rx_in movel rx_in(%d0), %d1 addl #1, %d1 cmpl #RX_BUFFERS, %d1 bne rx_2 clrl %d1rx_2: movel %d1, rx_in(%d0) bra rxrx_overrun: movel ch_status_addr(%d0), %d2 addl #1, STATUS_RX_OVERRUNS(%d2) bra rx_free_bdrx_bad_frame: movel ch_status_addr(%d0), %d2 addl #1, STATUS_RX_FRAME_ERRORS(%d2) bra rx_free_bdrx_ret: rts/****************************** packet transmitted ********************/// Service transmit buffers // D0 = 4 * port, D6 = doorbell to hosttx_end: tstl tx_count(%d0) beq tx_end_ret // TX buffers already empty movel tx_in(%d0), %d1 movel %d1, %d2 // D1 = D2 = tx_in BD# = desc# lsll #3, %d1 // BD is 8-bytes long addl tx_first_bd(%d0), %d1 // D1 = current tx_in BD address movew (%d1), %d3 // D3 = TX BD flags btstl #15, %d3 bne tx_end_ret // BD still being transmitted// update D6, tx_in and tx_count orl bell_tx(%d0), %d6 // signal host that TX desc freed subl #1, tx_count(%d0) movel tx_in(%d0), %d1 addl #1, %d1 cmpl #TX_BUFFERS, %d1 bne tx_end_1 clrl %d1tx_end_1: movel %d1, tx_in(%d0)// free host's descriptor mulul #DESC_LENGTH, %d2 // D2 = TX desc offset addl ch_status_addr(%d0), %d2 addl #STATUS_TX_DESCS, %d2 // D2 = TX desc address btstl #1, %d3 bne tx_end_underrun movel #PACKET_SENT, (%d2) bra tx_endtx_end_underrun: movel #PACKET_UNDERRUN, (%d2) bra tx_endtx_end_ret: rts/****************************** PLX PCI9060 DMA memcpy ****************/#if QUICC_MEMCPY_USES_PLX// called with interrupts disabledmemcpy_from_pci_run: movel %d0, -(%sp) movew %sr, -(%sp)memcpy_1: movel PLX_DMA_CMD_STS, %d0 // do not btst PLX register directly btstl #4, %d0 // transfer done? bne memcpy_end stop #0x2200 // enable PCI9060 interrupts movew #0x2700, %sr // disable interrupts again bra memcpy_1memcpy_to_pci_run: movel %d0, -(%sp) movew %sr, -(%sp)memcpy_2: movel PLX_DMA_CMD_STS, %d0 // do not btst PLX register directly btstl #12, %d0 // transfer done? bne memcpy_end stop #0x2200 // enable PCI9060 interrupts movew #0x2700, %sr // disable interrupts again bra memcpy_2memcpy_end: movew (%sp)+, %sr movel (%sp)+, %d0 rts#endif/****************************** PLX PCI9060 interrupt *****************/pci9060_interrupt: movel %d0, -(%sp) movel PLX_DOORBELL_TO_CARD, %d0 movel %d0, PLX_DOORBELL_TO_CARD // confirm all requests orl %d0, channel_stats movel #0x0909, PLX_DMA_CMD_STS // clear DMA ch #0 and #1 interrupts movel (%sp)+, %d0 rte/****************************** SCC interrupts ************************/port_interrupt_1: orl #0, SCC1_REGS + SCC_SCCE; // confirm SCC events orl #1 << TASK_SCC_0, channel_stats movel #0x40000000, CISR rteport_interrupt_2: orl #0, SCC2_REGS + SCC_SCCE; // confirm SCC events orl #1 << TASK_SCC_1, channel_stats movel #0x20000000, CISR rteport_interrupt_3: orl #0, SCC3_REGS + SCC_SCCE; // confirm SCC events orl #1 << TASK_SCC_2, channel_stats movel #0x10000000, CISR rteport_interrupt_4: orl #0, SCC4_REGS + SCC_SCCE; // confirm SCC events orl #1 << TASK_SCC_3, channel_stats movel #0x08000000, CISR rteerror_interrupt: rte/****************************** cable and PM routine ******************/// modified registers: nonecheck_csr: movel %d0, -(%sp) movel %d1, -(%sp) movel %d2, -(%sp) movel %a0, -(%sp) movel %a1, -(%sp) clrl %d0 // D0 = 4 * port movel #CSRA, %a0 // A0 = CSR addresscheck_csr_loop: movew (%a0), %d1 // D1 = CSR input bits andl #0xE7, %d1 // PM and cable sense bits (no DCE bit) cmpw #STATUS_CABLE_V35 * (1 + 1 << STATUS_CABLE_PM_SHIFT), %d1 bne check_csr_1 movew #0x0E08, %d1 bra check_csr_validcheck_csr_1: cmpw #STATUS_CABLE_X21 * (1 + 1 << STATUS_CABLE_PM_SHIFT), %d1 bne check_csr_2 movew #0x0408, %d1 bra check_csr_validcheck_csr_2: cmpw #STATUS_CABLE_V24 * (1 + 1 << STATUS_CABLE_PM_SHIFT), %d1 bne check_csr_3 movew #0x0208, %d1 bra check_csr_validcheck_csr_3: cmpw #STATUS_CABLE_EIA530 * (1 + 1 << STATUS_CABLE_PM_SHIFT), %d1 bne check_csr_disable movew #0x0D08, %d1 bra check_csr_validcheck_csr_disable: movew #0x0008, %d1 // D1 = disable everything movew #0x80E7, %d2 // D2 = input mask: ignore DSR bra check_csr_writecheck_csr_valid: // D1 = mode and IRQ bits movew csr_output(%d0), %d2 andw #0x3000, %d2 // D2 = requested LL and DTR bits orw %d2, %d1 // D1 = all requested output bits movew #0x80FF, %d2 // D2 = input mask: include DSRcheck_csr_write: cmpw old_csr_output(%d0), %d1 beq check_csr_input movew %d1, old_csr_output(%d0) movew %d1, (%a0) // Write CSR output bitscheck_csr_input: movew (PCDAT), %d1 andw dcd_mask(%d0), %d1 beq check_csr_dcd_on // DCD and CTS signals are negated movew (%a0), %d1 // D1 = CSR input bits andw #~STATUS_CABLE_DCD, %d1 // DCD off bra check_csr_previouscheck_csr_dcd_on: movew (%a0), %d1 // D1 = CSR input bits orw #STATUS_CABLE_DCD, %d1 // DCD oncheck_csr_previous: andw %d2, %d1 // input mask movel ch_status_addr(%d0), %a1 cmpl STATUS_CABLE(%a1), %d1 // check for change beq check_csr_next movel %d1, STATUS_CABLE(%a1) // update status movel bell_cable(%d0), PLX_DOORBELL_FROM_CARD // signal the hostcheck_csr_next: addl #2, %a0 // next CSR register addl #4, %d0 // D0 = 4 * next port cmpl #4 * 4, %d0 bne check_csr_loop movel (%sp)+, %a1 movel (%sp)+, %a0 movel (%sp)+, %d2 movel (%sp)+, %d1 movel (%sp)+, %d0 rts/****************************** timer interrupt ***********************/timer_interrupt: bsr check_csr rte/****************************** RAM sizing and test *******************/#if DETECT_RAMram_test: movel #0x12345678, %d1 // D1 = test value movel %d1, (128 * 1024 - 4) movel #128 * 1024, %d0 // D0 = RAM size testedram_test_size: cmpl #MAX_RAM_SIZE, %d0 beq ram_test_size_found movel %d0, %a0 addl #128 * 1024 - 4, %a0 cmpl (%a0), %d1 beq ram_test_size_checkram_test_next_size: lsll #1, %d0 bra ram_test_sizeram_test_size_check: eorl #0xFFFFFFFF, %d1 movel %d1, (128 * 1024 - 4) cmpl (%a0), %d1 bne ram_test_next_sizeram_test_size_found: // D0 = RAM size movel %d0, %a0 // A0 = fill ptr subl #firmware_end + 4, %d0 lsrl #2, %d0 movel %d0, %d1 // D1 = DBf counterram_test_fill: movel %a0, -(%a0) dbfw %d1, ram_test_fill subl #0x10000, %d1 cmpl #0xFFFFFFFF, %d1 bne ram_test_fillram_test_loop: // D0 = DBf counter cmpl (%a0)+, %a0 dbnew %d0, ram_test_loop bne ram_test_found_bad subl #0x10000, %d0 cmpl #0xFFFFFFFF, %d0 bne ram_test_loop bra ram_test_all_okram_test_found_bad: subl #4, %a0ram_test_all_ok: movel %a0, PLX_MAILBOX_5 rts#endif/****************************** constants *****************************/scc_reg_addr: .long SCC1_REGS, SCC2_REGS, SCC3_REGS, SCC4_REGSscc_base_addr: .long SCC1_BASE, SCC2_BASE, SCC3_BASE, SCC4_BASEtx_first_bd: .long DPRBASE .long DPRBASE + (TX_BUFFERS + RX_BUFFERS) * 8 .long DPRBASE + (TX_BUFFERS + RX_BUFFERS) * 8 * 2 .long DPRBASE + (TX_BUFFERS + RX_BUFFERS) * 8 * 3rx_first_bd: .long DPRBASE + TX_BUFFERS * 8 .long DPRBASE + TX_BUFFERS * 8 + (TX_BUFFERS + RX_BUFFERS) * 8 .long DPRBASE + TX_BUFFERS * 8 + (TX_BUFFERS + RX_BUFFERS) * 8 * 2 .long DPRBASE + TX_BUFFERS * 8 + (TX_BUFFERS + RX_BUFFERS) * 8 * 3first_buffer: .long BUFFERS_ADDR .long BUFFERS_ADDR + (TX_BUFFERS + RX_BUFFERS) * BUFFER_LENGTH .long BUFFERS_ADDR + (TX_BUFFERS + RX_BUFFERS) * BUFFER_LENGTH * 2 .long BUFFERS_ADDR + (TX_BUFFERS + RX_BUFFERS) * BUFFER_LENGTH * 3bell_tx: .long 1 << DOORBELL_FROM_CARD_TX_0, 1 << DOORBELL_FROM_CARD_TX_1 .long 1 << DOORBELL_FROM_CARD_TX_2, 1 << DOORBELL_FROM_CARD_TX_3bell_cable: .long 1 << DOORBELL_FROM_CARD_CABLE_0, 1 << DOORBELL_FROM_CARD_CABLE_1 .long 1 << DOORBELL_FROM_CARD_CABLE_2, 1 << DOORBELL_FROM_CARD_CABLE_3packet_full: .long PACKET_FULL, PACKET_FULL + 1, PACKET_FULL + 2, PACKET_FULL + 3clocking_ext: .long 0x0000002C, 0x00003E00, 0x002C0000, 0x3E000000clocking_txfromrx: .long 0x0000002D, 0x00003F00, 0x002D0000, 0x3F000000clocking_mask: .long 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000dcd_mask: .word 0x020, 0, 0x080, 0, 0x200, 0, 0x800 .ascii "wanXL firmware\n" .asciz "Copyright (C) 2003 Krzysztof Halasa <khc@pm.waw.pl>\n"/****************************** variables *****************************/ .align 4channel_stats: .long 0tx_in: .long 0, 0, 0, 0 // transmittedtx_out: .long 0, 0, 0, 0 // received from host for transmissiontx_count: .long 0, 0, 0, 0 // currently in transmit queuerx_in: .long 0, 0, 0, 0 // received from portrx_out: .long 0 // transmitted to hostparity_bytes: .word 0, 0, 0, 0, 0, 0, 0 // only 4 words are usedcsr_output: .word 0old_csr_output: .word 0, 0, 0, 0, 0, 0, 0 .align 4firmware_end: // must be dword-aligned
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -