📄 atmtxbyte.c
字号:
/***************************************************************************** * Copyright (c) 1999, 2000, 2001, 2002 C-Port Corporation, a Motorola Company * * All Rights Reserved * * * * The information contained in this file is C-Port Corporation confidential * * and proprietary. * * Any reproduction, use or disclosure, in whole or in part, of this * * program, including any attempt to obtain a human-readable version of this * * program, without the express, prior written consent of C-Port * * Corporation or Motorola Incorporated is strictly prohibited. * *****************************************************************************//********************************************************************** * TxByte Functionality * * The ATM TxByte code reads the first 4 bytes cell header from merge space * once obtaining the scope from the RC. It transmits these to the transmit * large FIFO and adds the HEC. The payload is DMA-ed normally. If the * txByte processor does not have a cell to transmit from the RC when it * checks for scope, it sends an idle cell. This is because cells must * constantly be transmitted on the line to maintain cell synchronization * at the far end. * * Need to Add: * 1. Any additional support required for OC12c, token passing, etc... **********************************************************************/#define TXBYTE#include "sdpUcode.h"#include "dcpRegistersCp.h"#include "rcSdpAtmApiIf.h"#include <stdio.h>#define TXBYTECTL ((int) &((SdpTxCregs*)NULL)->txCtl.byte)#define MERGE ((int) &((SdpTxCregs*)NULL)->merge)#define TXSTATUS ((int) &((SdpTxCregs*)NULL)->txStatus)#define TXMSG0 ((int) &((SdpTxCregs*)NULL)->txMsg[0])#define TXMSG1 ((int) &((SdpTxCregs*)NULL)->txMsg[1])#define ATMMERGE (MERGE + (int) &((MergeSpc*)NULL)->atmMergeSpc)#define HEC_COSET 0x55#define IDLE_PAYLD 0x6A#define P1_FLG (TXSTATUS_P1DONE >> 8)#define P2_FLG (TXSTATUS_P2DONE >> 8)#define RC_OWN_FLG (TXSTATUS_OWN >> 8)voidSDPmain(){ Description = ("ATM Ucode for the SDP TX Byte Processor.");#define CellByteCnt Ireg0/* ireg1 used for idle cell generation and sending last byte of cell *//* ireg2/3 used for CRC10 transmit temp variable and aal5 */#define LastByteMinus2 Ireg4 /* < D0 */#define LastByteMinus1 Ireg5 /* < D0 */#define LastByte Ireg6 /* < D0 */LabelDef(PROCESS_CELL_START); CregsAddrWrite(TXSTATUS); Branch(ALWAYS, Upc+1); /* clock 0 */ /* * One-Time Setup of Status Register as follows: * CONCAT1: Concatenate Ireg2 and Ireg3 into a 16 bit counter. * SIG_TXBIT: Raise signal to TxBit and leave it high throughout operation * to prevent the insertion of 0x7E flags by the TxSonet block * ~SCRAM: Off! Scrambling is disabled for the cell header. */ IregInit(STATUSreg, CONCAT1 | SIG_TXBIT, UseAbus); Branch(ALWAYS, Upc+1); /* clock 1 */ /* clear Ireg1 */ Abus(IregsA(Ireg1)); Bbus(IregsB(Ireg1)); ALU(XOR); Actions(IregsAwrite); Branch(ALWAYS, Label(MERGE_POLL)); /* clock 2 */LabelDef(GIVE_MERGE_TO_RC); DCPSIM_MESSAGE(GIVE_MERGE_TO_RC); Abus(Creg); Bbus(Literal(RC_OWN_FLG)); ALU(OR); Pbus(ALUout); Actions(CregsWrite); Branch(ALWAYS, Upc+1); /* clock 0/3 */#if DCP_CHIP_REV < DCP_C5_D0LabelDef(NOT_D0); IregInit(Ireg1, -3, UseAbus); Branch(ALWAYS, Upc+1); /* clock 1/4 */ Actions(IregIncr(Ireg1) + RepeatUntil); Branch(AllOnes(Ireg1), Upc+1); /* clock 234/567 */ Abus(IregsA(LastByteMinus1)); ALU(PassA); Pbus(ALUout); Actions(DataOutValid); Branch(ALWAYS, Upc+1); /* clock 5/0 */ IregInit(Ireg1, -6, UseAbus); Branch(ALWAYS, Upc+1); /* clock 6/1 */ Actions(IregIncr(Ireg1) + RepeatUntil); Branch(AllOnes(Ireg1), Upc+1); /* clock 7 8 9 10 11 12/234567 */ Abus(IregsA(LastByte)); ALU(PassA); Pbus(ALUout); Actions(DataOutValid + Merge9); Branch(ALWAYS, Upc+1); /* clock 13/0 */#endif /* * Disable scrambling for the cell header. */ IregANDlit(STATUSreg, ~SCRAM); Branch(ALWAYS, Upc+1); /* clock 14/1 */ Branch(ALWAYS, Upc+1); /* clock 15/2 */LabelDef(MERGE_POLL); //Wait for Merge space to be written Abus(Creg); ALU(PassA); Branch(ALWAYS, Upc+1); /* clock 0/3 */#ifdef SIM BranchNot(ALUzero,Label(IDLE_CELL_GEN));#else BranchNot(ALUzero, Upc-1);#endif DCPSIM_MESSAGE(MERGE_POLL); /* Set the creg address to the txType in preparation for switching on this value * down below in READ_MERGE_SPACE. This is loaded here because there will be a * big wait here for RxDataValid to become true, so we do this setup while we wait. */ CregsAddrWrite(ATMMERGE + (int) &((AtmMergeSpc*)NULL)->txType); Branch(ALWAYS, Upc+1); /* clock 16/3 */ /* * Do not attempt to send a cell until data is ready to * go. A DCP_C5_C0 bug causes the scrambling logic to * fail if the fifo transitions from full to not full * without a byte ready and waiting to enter the fifo. * This implies that we must transmit a byte every 8 clocks * for OC3. If we start to send a cell header when the * RC indicates that merge space is ready, we may wait for * many clocks while the DMA for the cell data is ready. * Waiting here for RxDataValid makes sure cell data is * ready to go when we start transmitting. * * This problem is fixed in the DCP_C5_D0 chip. ATM * on OC12c will not work prior to DCP_C5_D0 so this * is not an issue. * * Checking for RxDataValid too early after switching scope * is a problem. It takes 9-16 clocks for data to be available * after the txByte processor switches scopes. To ensure that * we don't check dataValid too early, we buffer up the last 3 * bytes of the cell (OAM and switched only - AAL5 runs on D0 only) * switch scopes, then send the last 3 bytes. This ensures that * we check for dataValid after 14 clocks have passed since it takes * 8 clocks to put a byte in the large FIFO - so 3 bytes affords us 24 * clocks. If we don't wait these clocks, we will be forced to * send an idle cell out in between every user cell. This problem * (and code) is not required in the DCP_C5_D0 version of the C-5 DCP. * * The following DCP_C5_D0 and later code assumes that * idle cell insertion is enabled in the hardware (sdpMode5). * In this case, simply spin here waiting for data to send. * The hardware will insert idle cells as needed. * * For DCP_C5_C0 and earlier, the hardware did not support * automatic idle cell insertion. If there isn't any data * valid, send another idle cell. * * Note: There is a safe assumption being made here that * if the payload data is ready, then the CpRc program has * already prepared the merge space and set the TxStatus * register to SDP-owns. */#if DCP_CHIP_REV >= DCP_C5_D0 && #ifndef SIM Actions(RepeatUntil); Branch(RxDataValid, Label(READ_MERGE_SPACE));#elseLabelDef(IDLE_CELL_GEN); Branch(RxDataValid, Label(READ_MERGE_SPACE)); /* clock 17/4 */ DCPSIM_MESSAGE(SEND_IDLE); IregInit(CellByteCnt, -(ATM_CELL_HDR_SZ-2), UseAbus); Actions(HECinit); Branch(ALWAYS, Upc+1); /* clock 5 */ Abus(IregsA(Ireg1)); Bbus(IregsB(Ireg1)); ALU(XOR); PayloadOut(ALUout); Actions(IregIncr(CellByteCnt) + RepeatUntil); Branch(AllOnes(CellByteCnt), Upc+1); /* clock 0 */ Bbus(Literal(0x01)); ALU(PassB); Actions(IregIncr(CellByteCnt)); PayloadOut(ALUout); Branch(ALWAYS, Upc+1); /* clock 0 */ /* delay slot to let HEC setup */ CregsAddrWrite(TXSTATUS); Branch(ALWAYS, Upc+1); /* clock 1 */ Bbus(HEC); Abus(Literal(HEC_COSET)); ALU(XOR); PayloadOut(ALUout); Branch(ALWAYS, Upc+1); /* clock 0 */ IregInit(CellByteCnt, -(ATM_CELL_PAYLD_SZ), UseAbus); Branch(ALWAYS, Upc+1); /* clock 1 */ IregORlit(STATUSreg, SCRAM); Branch(ALWAYS, Upc+1); /* clock 2 */ /* payload 1-48 = 0x6A */ IregInit(Ireg1, IDLE_PAYLD, UseAbus); Branch(ALWAYS, Upc+1); /* clock 3 */ Abus(IregsA(Ireg1)); ALU(PassA); Actions(IregIncr(CellByteCnt) + RepeatUntil); PayloadOut(ALUout); Branch(AllOnes(CellByteCnt), Upc+1); /* clock 0 */ IregANDlit(STATUSreg, ~SCRAM); Branch(ALWAYS, Upc+1); /* clock 1 */ Branch(ALWAYS, Label(MERGE_POLL)); /* clock 2 */#endifLabelDef(READ_MERGE_SPACE); /* get txtype from merge space and pass through ALU */ DCPSIM_MESSAGE(READ_MERGE_SPACE); CregsAddrWrite(ATMMERGE + (int) &((AtmMergeSpc*)NULL)->cellHeader); Abus(Creg); ALU(PassA); Branch(ALWAYS, Upc+1); /* clock 5 */ Abus(Creg); ALU(PassA); Actions(HECinit); Branch(ALUzero, Label(SWITCHED_CELL_PAYLOAD_PROCESS)); /* clock 6 */ BranchNot(ALUneg, Label(OAM_CELL_PAYLOAD_PROCESS)); /* clock 7 */ Branch(ALWAYS, Label(AAL5_CPCS_PDU_PAYLOAD_PROCESS));LabelDef(SWITCHED_CELL_PAYLOAD_PROCESS); Abus(Creg); ALU(PassA); Pbus(ALUout); Actions(DataOutValid+CregAddrIncr); Branch(ALWAYS, Upc+1); /* clock 0 */ Branch(ALWAYS, Upc+1); Abus(Creg); /* hdr2 */ ALU(PassA); Pbus(ALUout); Actions(DataOutValid+CregAddrIncr); Branch(ALWAYS, Upc+1); Branch(ALWAYS, Upc+1); Abus(Creg); /* hdr3 */ ALU(PassA); Pbus(ALUout); Actions(DataOutValid+CregAddrIncr); Branch(ALWAYS, Upc+1); Branch(ALWAYS, Upc+1); CregsAddrWrite(TXSTATUS); /* hdr4 */ Abus(Creg); ALU(PassA); Pbus(ALUout); Actions(DataOutValid); Branch(ALWAYS, Upc+1); DCPSIM_MESSAGE(TRANSMIT_HEC); Branch(ALWAYS, Upc+1); Bbus(HEC); Abus(Literal(HEC_COSET)); ALU(XOR); PayloadOut(ALUout); Branch(ALWAYS, Upc+1); /* * Turn on scrambling for the rest of the cell. * Allow one clock delay slot for the scrambler to * turn on. */ DCPSIM_MESSAGE(TRANSMIT_NON_OAM_PAYLOAD); IregORlit(STATUSreg, SCRAM); Branch(ALWAYS, Upc+1);#if DCP_CHIP_REV >= DCP_C5_D0 /* Initialize CellByteCnt to -47, we stop one short of payload end * so the merge9 bit can be added to the last byte. */ IregInit(CellByteCnt, -(ATM_CELL_PAYLD_SZ-1), UseAbus); Branch(ALWAYS, Upc+1); /* * Send the cell - less the last byte */ Pbus(Payload); Actions(UnloadFIFO + DataOutValid + IregIncr(CellByteCnt) + RepeatUntil); Branch(AllOnes(CellByteCnt), Upc+1); Pbus(Payload); Actions(DataOutValid+UnloadFIFO+Merge9); Branch(ALWAYS, Label(GIVE_MERGE_TO_RC)); /* clock 0 */#else /* * Scope switch/data ready fix due to FIFO scrambler action. */ IregInit(CellByteCnt, -(ATM_CELL_PAYLD_SZ-2), UseAbus); Branch(ALWAYS, Upc+1); /* * Send the cell - less the last 2 bytes */ Pbus(Payload); Actions(UnloadFIFO + DataOutValid + IregIncr(CellByteCnt) + RepeatUntil); Branch(AllOnes(CellByteCnt), Upc+1); /* clock 0 */ IregsA(LastByteMinus1); Bbus(Payload); ALU(PassB); Actions(UnloadFIFO + IregsAwrite); Branch(ALWAYS, Upc+1); /* clock 1 */ IregsA(LastByte);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -