// ========== Copyright Header Begin ========================================== // // OpenSPARC T2 Processor File: niu_txport_cb.vr // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved // 4150 Network Circle, Santa Clara, California 95054, U.S.A. // // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // For the avoidance of doubt, and except that if any non-GPL license // choice is available it will apply instead, Sun elects to use only // the General Public License version 2 (GPLv2) at this time for any // software where a choice of GPL license versions is made // available with the language indicating that GPLv2 or any later version // may be used, or where a choice of which version of the GPL is applied is // otherwise unspecified. // // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, // CA 95054 USA or visit www.sun.com if you need additional information or // have any questions. // // ========== Copyright Header End ============================================ #include "niu_tx_descp.vrh" #include "dmc_memory_map.vri" #include "txc_memory_map.vri" extern mbox_class mbox_id; #include "cMesg.vrh" extern Mesg be_msg; // To Support MAC Loop back mode #include "niu_rxtoken.vrh" #include "niu_cbclass.vrh" #include "niu_txcbmgr.vrh" #include "hostRdCbMgr.vrh" extern CHostRdCbMgr hostRdCbMgr; #define TIME {get_time(HI), get_time(LO)} #define HOSTMTU 64 // TMP ONLY class CTxSemId { integer id; integer port_id; integer noOfReqs; integer noOfResp; integer trans_id; bit[63:0] address[15]; // 15 gathers integer length[15]; // 15 gathers integer NoofGathers; task SetCb() ; task spawm_mini_cbs(bit[63:0] address, integer no_of_chunks, integer semId); task WaitForRelease(integer semId, integer InitialNoOfReqs); task new(integer i) { noOfReqs = -1; port_id = i; } } task CTxSemId::spawm_mini_cbs(bit[63:0] address, integer no_of_chunks, integer semId){ CcbMem cb; integer i; bit[63:0] address_incr; for(i=0;i>6 )<<6; // 64 bytes aligned adjusted_length[i] = length[i] + ( address[i] & 6'h3f ); // extra offset due to alignment } noOfReqs = 0; for(i=0;i>6 )<<6; // 64 bytes aligned cb.set(address,READ_REQUEST) ; hostRdCbMgr.setCallBack(cb); while(semaphore_get(WAIT,semId,1) != 1 ) { repeat(100) @(posedge CLOCK); } txtoken = TxTokenReqs[trans_id]; txtoken.pgToken.tx_request_seen = 1; printf("CheckReqCbs:: TX REQUEST SEEN FOR ADDRESS - %x ID - %d\n", address,txtoken.pgToken.gId); free_req_transid(trans_id); } join none } } task CTxPortCbMgr::FreezeCurrentTokenList() { VeraListIterator_CTxToken item, next_item; CTxToken Entry; integer i; sync(ALL,lock_for_mark); trigger(OFF,freeze_token_list); if(PortTxTokenList.size() ==1) { Entry = PortTxTokenList.back(); Entry.CannotTouch = 1; PortTxTokenList.pop_back(); PortTxTokenList.push_back(Entry); } else if(PortTxTokenList.size() >1) { item = PortTxTokenList.start(); while( item.neq(PortTxTokenList.finish())) { Entry = item.data(); printf("CTxPortCbMgr::FreezeCurrentTokenList Freezing Entry: Token id - %d Size - %d Address - %x \n",Entry.id,PortTxTokenList.size(),Entry.xlate_gather_address[0]); next_item = PortTxTokenList.erase(item); Entry.CannotTouch = 1; PortTxTokenList.insert(next_item,Entry); item = next_item; } } trigger(ON,freeze_token_list); } task CTxPortCbMgr::pushToPortTokenList(CTxToken TxToken) { // Look at the addresses, length set the call back table etc here CTxToken tmp; // TxToken.port_data_valid = 0; if(TxToken.CallBackPending) { printf("DEBUG Added : cb pending pushToPortTokenList id - %d Size - %d Time - %d \n",TxToken.id,PortTxTokenList.size(),TIME); } else { printf("DEBUG Added : cb to be set pushToPortTokenList id - %d Size - %d Time - %d \n",TxToken.id,PortTxTokenList.size(),TIME); } if(TxToken.CallBackPending==0) { fork { SetCb(TxToken); } join none TxToken.CallBackPending = 1; } sync(ALL,lock_for_mark); PortTxTokenList.push_back(TxToken); tmp = PortTxTokenList.back(); printf("DEBUG trans_id Added Address - %x Size - %d Time - %d \n",tmp.xlate_gather_address[0],PortTxTokenList.size(),TIME); } function integer CTxPortCbMgr::PullPortTokenList(var CTxToken TxToken) { sync(ALL,lock_for_mark); sync(ALL,freeze_token_list); if(PortTxTokenList.size()==0) { PullPortTokenList = 0; } else { TxToken = PortTxTokenList.back(); if(TxToken.CannotTouch) { PullPortTokenList = 0; } else { printf("PullPortTokenList: DEBUG trans_id - Size -%d Address - %x Time - %d id - %d \n",PortTxTokenList.size(),TxToken.xlate_gather_address[0],TIME,TxToken.id); PortTxTokenList.pop_back(); PullPortTokenList = 1; } } } task CTxPortCbMgr::SetCb(CTxToken TxToken) { CTxSemId TxSemIdlocal; integer i; integer trans_id; while(!cbTxIdMgr.isAvailable() ) { repeat(10) @(posedge CLOCK); } TxToken.call_back_set = 1; TxSemIdlocal= new(port_id); // TxSemIdlocal.semId = cbTxIdMgr.getSemId(); // trans_id = cbTxIdMgr.getTransId(); trans_id = cbTxIdMgr.getTransId(); // tmp for now TxSemIdlocal.trans_id = trans_id; // TxSemId.NoofGathers = TxToken.getNoofGathers(); TxSemIdlocal.NoofGathers = TxToken.NoofGathers; for(i=0;i