⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wanxlfw.s

📁 linux-2.6.15.6
💻 S
📖 第 1 页 / 共 2 页
字号:
.psize 0/*  wanXL serial card driver for Linux  card firmware part  Copyright (C) 2003 Krzysztof Halasa <khc@pm.waw.pl>  This program is free software; you can redistribute it and/or modify it  under the terms of version 2 of the GNU General Public License  as published by the Free Software Foundation.	DPRAM BDs:	0x000 - 0x050 TX#0	0x050 - 0x140 RX#0	0x140 - 0x190 TX#1	0x190 - 0x280 RX#1	0x280 - 0x2D0 TX#2	0x2D0 - 0x3C0 RX#2	0x3C0 - 0x410 TX#3	0x410 - 0x500 RX#3	000 5FF 1536 Bytes Dual-Port RAM User Data / BDs	600 6FF 256 Bytes Dual-Port RAM User Data / BDs	700 7FF 256 Bytes Dual-Port RAM User Data / BDs	C00 CBF 192 Bytes Dual-Port RAM Parameter RAM Page 1	D00 DBF 192 Bytes Dual-Port RAM Parameter RAM Page 2	E00 EBF 192 Bytes Dual-Port RAM Parameter RAM Page 3	F00 FBF 192 Bytes Dual-Port RAM Parameter RAM Page 4	local interrupts		    level	NMI					7	PIT timer, CPM (RX/TX complete)		4	PCI9060	DMA and PCI doorbells		3	Cable - not used			1*/#include <linux/hdlc.h>#include "wanxl.h"/* memory addresses and offsets */MAX_RAM_SIZE	= 16 * 1024 * 1024	// max RAM supported by hardwarePCI9060_VECTOR	= 0x0000006CCPM_IRQ_BASE	= 0x40ERROR_VECTOR	= CPM_IRQ_BASE * 4SCC1_VECTOR	= (CPM_IRQ_BASE + 0x1E) * 4SCC2_VECTOR	= (CPM_IRQ_BASE + 0x1D) * 4SCC3_VECTOR	= (CPM_IRQ_BASE + 0x1C) * 4SCC4_VECTOR	= (CPM_IRQ_BASE + 0x1B) * 4CPM_IRQ_LEVEL	= 4TIMER_IRQ	= 128TIMER_IRQ_LEVEL = 4PITR_CONST	= 0x100 + 16		// 1 Hz timerMBAR		= 0x0003FF00VALUE_WINDOW	= 0x40000000ORDER_WINDOW	= 0xC0000000PLX		= 0xFFF90000CSRA		= 0xFFFB0000CSRB		= 0xFFFB0002CSRC		= 0xFFFB0004CSRD		= 0xFFFB0006STATUS_CABLE_LL		= 0x2000STATUS_CABLE_DTR	= 0x1000DPRBASE		= 0xFFFC0000SCC1_BASE	= DPRBASE + 0xC00MISC_BASE	= DPRBASE + 0xCB0SCC2_BASE	= DPRBASE + 0xD00SCC3_BASE	= DPRBASE + 0xE00SCC4_BASE	= DPRBASE + 0xF00// offset from SCCx_BASE// SCC_xBASE contain offsets from DPRBASE and must be divisible by 8SCC_RBASE	= 0		// 16-bit RxBD base addressSCC_TBASE	= 2		// 16-bit TxBD base addressSCC_RFCR	= 4		// 8-bit Rx function codeSCC_TFCR	= 5		// 8-bit Tx function codeSCC_MRBLR	= 6		// 16-bit maximum Rx buffer lengthSCC_C_MASK	= 0x34		// 32-bit CRC constantSCC_C_PRES	= 0x38		// 32-bit CRC presetSCC_MFLR	= 0x46		// 16-bit max Rx frame length (without flags)REGBASE		= DPRBASE + 0x1000PICR		= REGBASE + 0x026	// 16-bit periodic irq controlPITR		= REGBASE + 0x02A	// 16-bit periodic irq timingOR1		= REGBASE + 0x064	// 32-bit RAM bank #1 optionsCICR		= REGBASE + 0x540	// 32(24)-bit CP interrupt configCIMR		= REGBASE + 0x548	// 32-bit CP interrupt maskCISR		= REGBASE + 0x54C	// 32-bit CP interrupts in-servicePADIR		= REGBASE + 0x550	// 16-bit PortA data direction bitmapPAPAR		= REGBASE + 0x552	// 16-bit PortA pin assignment bitmapPAODR		= REGBASE + 0x554	// 16-bit PortA open drain bitmapPADAT		= REGBASE + 0x556	// 16-bit PortA data registerPCDIR		= REGBASE + 0x560	// 16-bit PortC data direction bitmapPCPAR		= REGBASE + 0x562	// 16-bit PortC pin assignment bitmapPCSO		= REGBASE + 0x564	// 16-bit PortC special optionsPCDAT		= REGBASE + 0x566	// 16-bit PortC data registerPCINT		= REGBASE + 0x568	// 16-bit PortC interrupt controlCR		= REGBASE + 0x5C0	// 16-bit Command registerSCC1_REGS	= REGBASE + 0x600SCC2_REGS	= REGBASE + 0x620SCC3_REGS	= REGBASE + 0x640SCC4_REGS	= REGBASE + 0x660SICR		= REGBASE + 0x6EC	// 32-bit SI clock route// offset from SCCx_REGSSCC_GSMR_L	= 0x00	// 32 bitsSCC_GSMR_H	= 0x04	// 32 bitsSCC_PSMR	= 0x08	// 16 bitsSCC_TODR	= 0x0C	// 16 bitsSCC_DSR		= 0x0E	// 16 bitsSCC_SCCE	= 0x10	// 16 bitsSCC_SCCM	= 0x14	// 16 bitsSCC_SCCS	= 0x17	// 8 bits#if QUICC_MEMCPY_USES_PLX	.macro memcpy_from_pci src, dest, len // len must be < 8 MB	addl #3, \len	andl #0xFFFFFFFC, \len		// always copy n * 4 bytes	movel \src, PLX_DMA_0_PCI	movel \dest, PLX_DMA_0_LOCAL	movel \len, PLX_DMA_0_LENGTH	movel #0x0103, PLX_DMA_CMD_STS	// start channel 0 transfer	bsr memcpy_from_pci_run	.endm	.macro memcpy_to_pci src, dest, len	addl #3, \len	andl #0xFFFFFFFC, \len		// always copy n * 4 bytes	movel \src, PLX_DMA_1_LOCAL	movel \dest, PLX_DMA_1_PCI	movel \len, PLX_DMA_1_LENGTH	movel #0x0301, PLX_DMA_CMD_STS	// start channel 1 transfer	bsr memcpy_to_pci_run	.endm#else	.macro memcpy src, dest, len	// len must be < 65536 bytes	movel %d7, -(%sp)		// src and dest must be < 256 MB	movel \len, %d7			// bits 0 and 1	lsrl #2, \len	andl \len, \len	beq 99f				// only 0 - 3 bytes	subl #1, \len			// for dbf98:	movel (\src)+, (\dest)+	dbfw \len, 98b99:	movel %d7, \len	btstl #1, \len	beq 99f	movew (\src)+, (\dest)+99:	btstl #0, \len	beq 99f	moveb (\src)+, (\dest)+99:	movel (%sp)+, %d7	.endm	.macro memcpy_from_pci src, dest, len	addl #VALUE_WINDOW, \src	memcpy \src, \dest, \len	.endm	.macro memcpy_to_pci src, dest, len	addl #VALUE_WINDOW, \dest	memcpy \src, \dest, \len	.endm#endif	.macro wait_for_command99:	btstl #0, CR	bne 99b	.endm/****************************** card initialization *******************/	.text	.global _start_start:	bra init	.org _start + 4ch_status_addr:	.long 0, 0, 0, 0rx_descs_addr:	.long 0init:#if DETECT_RAM	movel OR1, %d0	andl #0xF00007FF, %d0		// mask AMxx bits	orl #0xFFFF800 & ~(MAX_RAM_SIZE - 1), %d0 // update RAM bank size	movel %d0, OR1#endif	addl #VALUE_WINDOW, rx_descs_addr // PCI addresses of shared data	clrl %d0			// D0 = 4 * portinit_1:	tstl ch_status_addr(%d0)	beq init_2	addl #VALUE_WINDOW, ch_status_addr(%d0)init_2:	addl #4, %d0	cmpl #4 * 4, %d0	bne init_1	movel #pci9060_interrupt, PCI9060_VECTOR	movel #error_interrupt, ERROR_VECTOR	movel #port_interrupt_1, SCC1_VECTOR	movel #port_interrupt_2, SCC2_VECTOR	movel #port_interrupt_3, SCC3_VECTOR	movel #port_interrupt_4, SCC4_VECTOR	movel #timer_interrupt, TIMER_IRQ * 4	movel #0x78000000, CIMR		// only SCCx IRQs from CPM	movew #(TIMER_IRQ_LEVEL << 8) + TIMER_IRQ, PICR	// interrupt from PIT	movew #PITR_CONST, PITR	// SCC1=SCCa SCC2=SCCb SCC3=SCCc SCC4=SCCd prio=4 HP=-1 IRQ=64-79	movel #0xD41F40 + (CPM_IRQ_LEVEL << 13), CICR	movel #0x543, PLX_DMA_0_MODE	// 32-bit, Ready, Burst, IRQ	movel #0x543, PLX_DMA_1_MODE	movel #0x0, PLX_DMA_0_DESC	// from PCI to local	movel #0x8, PLX_DMA_1_DESC	// from local to PCI	movel #0x101, PLX_DMA_CMD_STS	// enable both DMA channels	// enable local IRQ, DMA, doorbells and PCI IRQ	orl #0x000F0300, PLX_INTERRUPT_CS#if DETECT_RAM	bsr ram_test#else	movel #1, PLX_MAILBOX_5		// non-zero value = init complete#endif	bsr check_csr	movew #0xFFFF, PAPAR		// all pins are clocks/data	clrw PADIR			// first function	clrw PCSO			// CD and CTS always active/****************************** main loop *****************************/main:	movel channel_stats, %d7	// D7 = doorbell + irq status	clrl channel_stats	tstl %d7	bne main_1	// nothing to do - wait for next event	stop #0x2200			// supervisor + IRQ level 2	movew #0x2700, %sr		// disable IRQs again	bra mainmain_1:	clrl %d0			// D0 = 4 * port	clrl %d6			// D6 = doorbell to host valuemain_l: btstl #DOORBELL_TO_CARD_CLOSE_0, %d7	beq main_op	bclrl #DOORBELL_TO_CARD_OPEN_0, %d7 // in case both bits are set	bsr close_portmain_op:	btstl #DOORBELL_TO_CARD_OPEN_0, %d7	beq main_cl	bsr open_portmain_cl:	btstl #DOORBELL_TO_CARD_TX_0, %d7	beq main_txend	bsr txmain_txend:	btstl #TASK_SCC_0, %d7	beq main_next	bsr tx_end	bsr rxmain_next:	lsrl #1, %d7			// port status for next port	addl #4, %d0			// D0 = 4 * next port	cmpl #4 * 4, %d0	bne main_l	movel %d6, PLX_DOORBELL_FROM_CARD // signal the host	bra main/****************************** open port *****************************/open_port:				// D0 = 4 * port, D6 = doorbell to host	movel ch_status_addr(%d0), %a0	// A0 = port status address	tstl STATUS_OPEN(%a0)	bne open_port_ret		// port already open	movel #1, STATUS_OPEN(%a0)	// confirm the port is open// setup BDs	clrl tx_in(%d0)	clrl tx_out(%d0)	clrl tx_count(%d0)	clrl rx_in(%d0)	movel SICR, %d1			// D1 = clock settings in SICR	andl clocking_mask(%d0), %d1	cmpl #CLOCK_TXFROMRX, STATUS_CLOCKING(%a0)	bne open_port_clock_ext	orl clocking_txfromrx(%d0), %d1	bra open_port_set_clockopen_port_clock_ext:	orl clocking_ext(%d0), %d1open_port_set_clock:	movel %d1, SICR			// update clock settings in SICR	orw #STATUS_CABLE_DTR, csr_output(%d0)	// DTR on	bsr check_csr			// call with disabled timer interrupt// Setup TX descriptors	movel first_buffer(%d0), %d1	// D1 = starting buffer address	movel tx_first_bd(%d0), %a1	// A1 = starting TX BD address	movel #TX_BUFFERS - 2, %d2	// D2 = TX_BUFFERS - 1 counter	movel #0x18000000, %d3		// D3 = initial TX BD flags: Int + Last	cmpl #PARITY_NONE, STATUS_PARITY(%a0)	beq open_port_tx_loop	bsetl #26, %d3			// TX BD flag: Transmit CRCopen_port_tx_loop:	movel %d3, (%a1)+		// TX flags + length	movel %d1, (%a1)+		// buffer address	addl #BUFFER_LENGTH, %d1	dbfw %d2, open_port_tx_loop	bsetl #29, %d3			// TX BD flag: Wrap (last BD)	movel %d3, (%a1)+		// Final TX flags + length	movel %d1, (%a1)+		// buffer address// Setup RX descriptors			// A1 = starting RX BD address	movel #RX_BUFFERS - 2, %d2	// D2 = RX_BUFFERS - 1 counteropen_port_rx_loop:	movel #0x90000000, (%a1)+	// RX flags + length	movel %d1, (%a1)+		// buffer address	addl #BUFFER_LENGTH, %d1	dbfw %d2, open_port_rx_loop	movel #0xB0000000, (%a1)+	// Final RX flags + length	movel %d1, (%a1)+		// buffer address// Setup port parameters	movel scc_base_addr(%d0), %a1	// A1 = SCC_BASE address	movel scc_reg_addr(%d0), %a2	// A2 = SCC_REGS address	movel #0xFFFF, SCC_SCCE(%a2)	// clear status bits	movel #0x0000, SCC_SCCM(%a2)	// interrupt mask	movel tx_first_bd(%d0), %d1	movew %d1, SCC_TBASE(%a1)	// D1 = offset of first TxBD	addl #TX_BUFFERS * 8, %d1	movew %d1, SCC_RBASE(%a1)	// D1 = offset of first RxBD	moveb #0x8, SCC_RFCR(%a1)	// Intel mode, 1000	moveb #0x8, SCC_TFCR(%a1)// Parity settings	cmpl #PARITY_CRC16_PR1_CCITT, STATUS_PARITY(%a0)	bne open_port_parity_1	clrw SCC_PSMR(%a2)		// CRC16-CCITT	movel #0xF0B8, SCC_C_MASK(%a1)	movel #0xFFFF, SCC_C_PRES(%a1)	movew #HDLC_MAX_MRU + 2, SCC_MFLR(%a1) // 2 bytes for CRC	movew #2, parity_bytes(%d0)	bra open_port_2open_port_parity_1:	cmpl #PARITY_CRC32_PR1_CCITT, STATUS_PARITY(%a0)	bne open_port_parity_2	movew #0x0800, SCC_PSMR(%a2)	// CRC32-CCITT	movel #0xDEBB20E3, SCC_C_MASK(%a1)	movel #0xFFFFFFFF, SCC_C_PRES(%a1)	movew #HDLC_MAX_MRU + 4, SCC_MFLR(%a1) // 4 bytes for CRC	movew #4, parity_bytes(%d0)	bra open_port_2open_port_parity_2:	cmpl #PARITY_CRC16_PR0_CCITT, STATUS_PARITY(%a0)	bne open_port_parity_3	clrw SCC_PSMR(%a2)		// CRC16-CCITT preset 0	movel #0xF0B8, SCC_C_MASK(%a1)	clrl SCC_C_PRES(%a1)	movew #HDLC_MAX_MRU + 2, SCC_MFLR(%a1) // 2 bytes for CRC	movew #2, parity_bytes(%d0)	bra open_port_2open_port_parity_3:	cmpl #PARITY_CRC32_PR0_CCITT, STATUS_PARITY(%a0)	bne open_port_parity_4	movew #0x0800, SCC_PSMR(%a2)	// CRC32-CCITT preset 0	movel #0xDEBB20E3, SCC_C_MASK(%a1)	clrl SCC_C_PRES(%a1)	movew #HDLC_MAX_MRU + 4, SCC_MFLR(%a1) // 4 bytes for CRC	movew #4, parity_bytes(%d0)	bra open_port_2open_port_parity_4:	clrw SCC_PSMR(%a2)		// no parity	movel #0xF0B8, SCC_C_MASK(%a1)	movel #0xFFFF, SCC_C_PRES(%a1)	movew #HDLC_MAX_MRU, SCC_MFLR(%a1) // 0 bytes for CRC	clrw parity_bytes(%d0)open_port_2:	movel #0x00000003, SCC_GSMR_H(%a2) // RTSM	cmpl #ENCODING_NRZI, STATUS_ENCODING(%a0)	bne open_port_nrz	movel #0x10040900, SCC_GSMR_L(%a2) // NRZI: TCI Tend RECN+TENC=1	bra open_port_3open_port_nrz:	movel #0x10040000, SCC_GSMR_L(%a2) // NRZ: TCI Tend RECN+TENC=0open_port_3:	movew #BUFFER_LENGTH, SCC_MRBLR(%a1)	movel %d0, %d1	lsll #4, %d1			// D1 bits 7 and 6 = port	orl #1, %d1	movew %d1, CR			// Init SCC RX and TX params	wait_for_command	// TCI Tend ENR ENT	movew #0x001F, SCC_SCCM(%a2)	// TXE RXF BSY TXB RXB interrupts	orl #0x00000030, SCC_GSMR_L(%a2) // enable SCCopen_port_ret:	rts/****************************** close port ****************************/close_port:				// D0 = 4 * port, D6 = doorbell to host	movel scc_reg_addr(%d0), %a0	// A0 = SCC_REGS address	clrw SCC_SCCM(%a0)		// no SCC interrupts	andl #0xFFFFFFCF, SCC_GSMR_L(%a0) // Disable ENT and ENR	andw #~STATUS_CABLE_DTR, csr_output(%d0) // DTR off	bsr check_csr			// call with disabled timer interrupt	movel ch_status_addr(%d0), %d1	clrl STATUS_OPEN(%d1)		// confirm the port is closed	rts/****************************** transmit packet ***********************/// queue packets for transmissiontx:					// D0 = 4 * port, D6 = doorbell to host

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -