serial_link.hh revision 11551
111185Serfan.azarkhish@unibo.it/* 211185Serfan.azarkhish@unibo.it * Copyright (c) 2011-2013 ARM Limited 311185Serfan.azarkhish@unibo.it * All rights reserved 411185Serfan.azarkhish@unibo.it * 511185Serfan.azarkhish@unibo.it * The license below extends only to copyright in the software and shall 611185Serfan.azarkhish@unibo.it * not be construed as granting a license to any other intellectual 711185Serfan.azarkhish@unibo.it * property including but not limited to intellectual property relating 811185Serfan.azarkhish@unibo.it * to a hardware implementation of the functionality of the software 911185Serfan.azarkhish@unibo.it * licensed hereunder. You may use the software subject to the license 1011185Serfan.azarkhish@unibo.it * terms below provided that you ensure that this notice is replicated 1111185Serfan.azarkhish@unibo.it * unmodified and in its entirety in all distributions of the software, 1211185Serfan.azarkhish@unibo.it * modified or unmodified, in source code or in binary form. 1311185Serfan.azarkhish@unibo.it * 1411185Serfan.azarkhish@unibo.it * Copyright (c) 2006 The Regents of The University of Michigan 1511185Serfan.azarkhish@unibo.it * Copyright (c) 2015 The University of Bologna 1611185Serfan.azarkhish@unibo.it * All rights reserved. 1711185Serfan.azarkhish@unibo.it * 1811185Serfan.azarkhish@unibo.it * Redistribution and use in source and binary forms, with or without 1911185Serfan.azarkhish@unibo.it * modification, are permitted provided that the following conditions are 2011185Serfan.azarkhish@unibo.it * met: redistributions of source code must retain the above copyright 2111185Serfan.azarkhish@unibo.it * notice, this list of conditions and the following disclaimer; 2211185Serfan.azarkhish@unibo.it * redistributions in binary form must reproduce the above copyright 2311185Serfan.azarkhish@unibo.it * notice, this list of conditions and the following disclaimer in the 2411185Serfan.azarkhish@unibo.it * documentation and/or other materials provided with the distribution; 2511185Serfan.azarkhish@unibo.it * neither the name of the copyright holders nor the names of its 2611185Serfan.azarkhish@unibo.it * contributors may be used to endorse or promote products derived from 2711185Serfan.azarkhish@unibo.it * this software without specific prior written permission. 2811185Serfan.azarkhish@unibo.it * 2911185Serfan.azarkhish@unibo.it * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3011185Serfan.azarkhish@unibo.it * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3111185Serfan.azarkhish@unibo.it * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3211185Serfan.azarkhish@unibo.it * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3311185Serfan.azarkhish@unibo.it * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3411185Serfan.azarkhish@unibo.it * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3511185Serfan.azarkhish@unibo.it * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3611185Serfan.azarkhish@unibo.it * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3711185Serfan.azarkhish@unibo.it * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3811185Serfan.azarkhish@unibo.it * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3911185Serfan.azarkhish@unibo.it * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4011185Serfan.azarkhish@unibo.it * 4111185Serfan.azarkhish@unibo.it * Authors: Ali Saidi 4211185Serfan.azarkhish@unibo.it * Steve Reinhardt 4311185Serfan.azarkhish@unibo.it * Andreas Hansson 4411185Serfan.azarkhish@unibo.it * Erfan Azarkhish 4511185Serfan.azarkhish@unibo.it */ 4611185Serfan.azarkhish@unibo.it 4711185Serfan.azarkhish@unibo.it/** 4811185Serfan.azarkhish@unibo.it * @file 4911185Serfan.azarkhish@unibo.it * Declaration of the SerialLink Class, modeling Hybrid-Memory-Cube's serial 5011185Serfan.azarkhish@unibo.it * interface. 5111185Serfan.azarkhish@unibo.it */ 5211185Serfan.azarkhish@unibo.it 5311185Serfan.azarkhish@unibo.it#ifndef __MEM_SERIAL_LINK_HH__ 5411185Serfan.azarkhish@unibo.it#define __MEM_SERIAL_LINK_HH__ 5511185Serfan.azarkhish@unibo.it 5611185Serfan.azarkhish@unibo.it#include <deque> 5711185Serfan.azarkhish@unibo.it 5811185Serfan.azarkhish@unibo.it#include "base/types.hh" 5911185Serfan.azarkhish@unibo.it#include "mem/mem_object.hh" 6011185Serfan.azarkhish@unibo.it#include "params/SerialLink.hh" 6111185Serfan.azarkhish@unibo.it 6211185Serfan.azarkhish@unibo.it/** 6311185Serfan.azarkhish@unibo.it * SerialLink is a simple variation of the Bridge class, with the ability to 6411185Serfan.azarkhish@unibo.it * account for the latency of packet serialization. We assume that the 6511185Serfan.azarkhish@unibo.it * serializer component at the transmitter side does not need to receive the 6611185Serfan.azarkhish@unibo.it * whole packet to start the serialization. But the deserializer waits for the 6711185Serfan.azarkhish@unibo.it * complete packet to check its integrity first. 6811185Serfan.azarkhish@unibo.it */ 6911185Serfan.azarkhish@unibo.itclass SerialLink : public MemObject 7011185Serfan.azarkhish@unibo.it{ 7111185Serfan.azarkhish@unibo.it protected: 7211185Serfan.azarkhish@unibo.it 7311185Serfan.azarkhish@unibo.it /** 7411185Serfan.azarkhish@unibo.it * A deferred packet stores a packet along with its scheduled 7511185Serfan.azarkhish@unibo.it * transmission time 7611185Serfan.azarkhish@unibo.it */ 7711185Serfan.azarkhish@unibo.it class DeferredPacket 7811185Serfan.azarkhish@unibo.it { 7911185Serfan.azarkhish@unibo.it 8011185Serfan.azarkhish@unibo.it public: 8111185Serfan.azarkhish@unibo.it 8211185Serfan.azarkhish@unibo.it const Tick tick; 8311185Serfan.azarkhish@unibo.it const PacketPtr pkt; 8411185Serfan.azarkhish@unibo.it 8511185Serfan.azarkhish@unibo.it DeferredPacket(PacketPtr _pkt, Tick _tick) : tick(_tick), pkt(_pkt) 8611185Serfan.azarkhish@unibo.it { } 8711185Serfan.azarkhish@unibo.it }; 8811185Serfan.azarkhish@unibo.it 8911185Serfan.azarkhish@unibo.it // Forward declaration to allow the slave port to have a pointer 9011185Serfan.azarkhish@unibo.it class SerialLinkMasterPort; 9111185Serfan.azarkhish@unibo.it 9211185Serfan.azarkhish@unibo.it /** 9311185Serfan.azarkhish@unibo.it * The port on the side that receives requests and sends 9411185Serfan.azarkhish@unibo.it * responses. The slave port has a set of address ranges that it 9511185Serfan.azarkhish@unibo.it * is responsible for. The slave port also has a buffer for the 9611185Serfan.azarkhish@unibo.it * responses not yet sent. 9711185Serfan.azarkhish@unibo.it */ 9811185Serfan.azarkhish@unibo.it class SerialLinkSlavePort : public SlavePort 9911185Serfan.azarkhish@unibo.it { 10011185Serfan.azarkhish@unibo.it 10111185Serfan.azarkhish@unibo.it private: 10211185Serfan.azarkhish@unibo.it 10311185Serfan.azarkhish@unibo.it /** The serial_link to which this port belongs. */ 10411185Serfan.azarkhish@unibo.it SerialLink& serial_link; 10511185Serfan.azarkhish@unibo.it 10611185Serfan.azarkhish@unibo.it /** 10711185Serfan.azarkhish@unibo.it * Master port on the other side of the serial_link. 10811185Serfan.azarkhish@unibo.it */ 10911185Serfan.azarkhish@unibo.it SerialLinkMasterPort& masterPort; 11011185Serfan.azarkhish@unibo.it 11111185Serfan.azarkhish@unibo.it /** Minimum request delay though this serial_link. */ 11211185Serfan.azarkhish@unibo.it const Cycles delay; 11311185Serfan.azarkhish@unibo.it 11411185Serfan.azarkhish@unibo.it /** Address ranges to pass through the serial_link */ 11511185Serfan.azarkhish@unibo.it const AddrRangeList ranges; 11611185Serfan.azarkhish@unibo.it 11711185Serfan.azarkhish@unibo.it /** 11811185Serfan.azarkhish@unibo.it * Response packet queue. Response packets are held in this 11911185Serfan.azarkhish@unibo.it * queue for a specified delay to model the processing delay 12011185Serfan.azarkhish@unibo.it * of the serial_link. We use a deque as we need to iterate over 12111185Serfan.azarkhish@unibo.it * the items for functional accesses. 12211185Serfan.azarkhish@unibo.it */ 12311185Serfan.azarkhish@unibo.it std::deque<DeferredPacket> transmitList; 12411185Serfan.azarkhish@unibo.it 12511185Serfan.azarkhish@unibo.it /** Counter to track the outstanding responses. */ 12611185Serfan.azarkhish@unibo.it unsigned int outstandingResponses; 12711185Serfan.azarkhish@unibo.it 12811185Serfan.azarkhish@unibo.it /** If we should send a retry when space becomes available. */ 12911185Serfan.azarkhish@unibo.it bool retryReq; 13011185Serfan.azarkhish@unibo.it 13111185Serfan.azarkhish@unibo.it /** Max queue size for reserved responses. */ 13211185Serfan.azarkhish@unibo.it unsigned int respQueueLimit; 13311185Serfan.azarkhish@unibo.it 13411185Serfan.azarkhish@unibo.it /** 13511185Serfan.azarkhish@unibo.it * Is this side blocked from accepting new response packets. 13611185Serfan.azarkhish@unibo.it * 13711185Serfan.azarkhish@unibo.it * @return true if the reserved space has reached the set limit 13811185Serfan.azarkhish@unibo.it */ 13911185Serfan.azarkhish@unibo.it bool respQueueFull() const; 14011185Serfan.azarkhish@unibo.it 14111185Serfan.azarkhish@unibo.it /** 14211185Serfan.azarkhish@unibo.it * Handle send event, scheduled when the packet at the head of 14311185Serfan.azarkhish@unibo.it * the response queue is ready to transmit (for timing 14411185Serfan.azarkhish@unibo.it * accesses only). 14511185Serfan.azarkhish@unibo.it */ 14611185Serfan.azarkhish@unibo.it void trySendTiming(); 14711185Serfan.azarkhish@unibo.it 14811185Serfan.azarkhish@unibo.it /** Send event for the response queue. */ 14911185Serfan.azarkhish@unibo.it EventWrapper<SerialLinkSlavePort, 15011185Serfan.azarkhish@unibo.it &SerialLinkSlavePort::trySendTiming> sendEvent; 15111185Serfan.azarkhish@unibo.it 15211185Serfan.azarkhish@unibo.it public: 15311185Serfan.azarkhish@unibo.it 15411185Serfan.azarkhish@unibo.it /** 15511185Serfan.azarkhish@unibo.it * Constructor for the SerialLinkSlavePort. 15611185Serfan.azarkhish@unibo.it * 15711185Serfan.azarkhish@unibo.it * @param _name the port name including the owner 15811185Serfan.azarkhish@unibo.it * @param _serial_link the structural owner 15911185Serfan.azarkhish@unibo.it * @param _masterPort the master port on the other side of the 16011185Serfan.azarkhish@unibo.it * serial_link 16111185Serfan.azarkhish@unibo.it * @param _delay the delay in cycles from receiving to sending 16211185Serfan.azarkhish@unibo.it * @param _resp_limit the size of the response queue 16311185Serfan.azarkhish@unibo.it * @param _ranges a number of address ranges to forward 16411185Serfan.azarkhish@unibo.it */ 16511185Serfan.azarkhish@unibo.it SerialLinkSlavePort(const std::string& _name, SerialLink& 16611185Serfan.azarkhish@unibo.it _serial_link, SerialLinkMasterPort& _masterPort, 16711185Serfan.azarkhish@unibo.it Cycles _delay, int _resp_limit, const 16811185Serfan.azarkhish@unibo.it std::vector<AddrRange>& _ranges); 16911185Serfan.azarkhish@unibo.it 17011185Serfan.azarkhish@unibo.it /** 17111185Serfan.azarkhish@unibo.it * Queue a response packet to be sent out later and also schedule 17211185Serfan.azarkhish@unibo.it * a send if necessary. 17311185Serfan.azarkhish@unibo.it * 17411185Serfan.azarkhish@unibo.it * @param pkt a response to send out after a delay 17511185Serfan.azarkhish@unibo.it * @param when tick when response packet should be sent 17611185Serfan.azarkhish@unibo.it */ 17711185Serfan.azarkhish@unibo.it void schedTimingResp(PacketPtr pkt, Tick when); 17811185Serfan.azarkhish@unibo.it 17911185Serfan.azarkhish@unibo.it /** 18011185Serfan.azarkhish@unibo.it * Retry any stalled request that we have failed to accept at 18111185Serfan.azarkhish@unibo.it * an earlier point in time. This call will do nothing if no 18211185Serfan.azarkhish@unibo.it * request is waiting. 18311185Serfan.azarkhish@unibo.it */ 18411185Serfan.azarkhish@unibo.it void retryStalledReq(); 18511185Serfan.azarkhish@unibo.it 18611185Serfan.azarkhish@unibo.it protected: 18711185Serfan.azarkhish@unibo.it 18811185Serfan.azarkhish@unibo.it /** When receiving a timing request from the peer port, 18911185Serfan.azarkhish@unibo.it pass it to the serial_link. */ 19011185Serfan.azarkhish@unibo.it bool recvTimingReq(PacketPtr pkt); 19111185Serfan.azarkhish@unibo.it 19211185Serfan.azarkhish@unibo.it /** When receiving a retry request from the peer port, 19311185Serfan.azarkhish@unibo.it pass it to the serial_link. */ 19411185Serfan.azarkhish@unibo.it void recvRespRetry(); 19511185Serfan.azarkhish@unibo.it 19611185Serfan.azarkhish@unibo.it /** When receiving a Atomic requestfrom the peer port, 19711185Serfan.azarkhish@unibo.it pass it to the serial_link. */ 19811185Serfan.azarkhish@unibo.it Tick recvAtomic(PacketPtr pkt); 19911185Serfan.azarkhish@unibo.it 20011185Serfan.azarkhish@unibo.it /** When receiving a Functional request from the peer port, 20111185Serfan.azarkhish@unibo.it pass it to the serial_link. */ 20211185Serfan.azarkhish@unibo.it void recvFunctional(PacketPtr pkt); 20311185Serfan.azarkhish@unibo.it 20411185Serfan.azarkhish@unibo.it /** When receiving a address range request the peer port, 20511185Serfan.azarkhish@unibo.it pass it to the serial_link. */ 20611185Serfan.azarkhish@unibo.it AddrRangeList getAddrRanges() const; 20711185Serfan.azarkhish@unibo.it }; 20811185Serfan.azarkhish@unibo.it 20911185Serfan.azarkhish@unibo.it 21011185Serfan.azarkhish@unibo.it /** 21111185Serfan.azarkhish@unibo.it * Port on the side that forwards requests and receives 21211185Serfan.azarkhish@unibo.it * responses. The master port has a buffer for the requests not 21311185Serfan.azarkhish@unibo.it * yet sent. 21411185Serfan.azarkhish@unibo.it */ 21511185Serfan.azarkhish@unibo.it class SerialLinkMasterPort : public MasterPort 21611185Serfan.azarkhish@unibo.it { 21711185Serfan.azarkhish@unibo.it 21811185Serfan.azarkhish@unibo.it private: 21911185Serfan.azarkhish@unibo.it 22011185Serfan.azarkhish@unibo.it /** The serial_link to which this port belongs. */ 22111185Serfan.azarkhish@unibo.it SerialLink& serial_link; 22211185Serfan.azarkhish@unibo.it 22311185Serfan.azarkhish@unibo.it /** 22411185Serfan.azarkhish@unibo.it * The slave port on the other side of the serial_link. 22511185Serfan.azarkhish@unibo.it */ 22611185Serfan.azarkhish@unibo.it SerialLinkSlavePort& slavePort; 22711185Serfan.azarkhish@unibo.it 22811185Serfan.azarkhish@unibo.it /** Minimum delay though this serial_link. */ 22911185Serfan.azarkhish@unibo.it const Cycles delay; 23011185Serfan.azarkhish@unibo.it 23111185Serfan.azarkhish@unibo.it /** 23211185Serfan.azarkhish@unibo.it * Request packet queue. Request packets are held in this 23311185Serfan.azarkhish@unibo.it * queue for a specified delay to model the processing delay 23411185Serfan.azarkhish@unibo.it * of the serial_link. We use a deque as we need to iterate over 23511185Serfan.azarkhish@unibo.it * the items for functional accesses. 23611185Serfan.azarkhish@unibo.it */ 23711185Serfan.azarkhish@unibo.it std::deque<DeferredPacket> transmitList; 23811185Serfan.azarkhish@unibo.it 23911185Serfan.azarkhish@unibo.it /** Max queue size for request packets */ 24011185Serfan.azarkhish@unibo.it const unsigned int reqQueueLimit; 24111185Serfan.azarkhish@unibo.it 24211185Serfan.azarkhish@unibo.it /** 24311185Serfan.azarkhish@unibo.it * Handle send event, scheduled when the packet at the head of 24411185Serfan.azarkhish@unibo.it * the outbound queue is ready to transmit (for timing 24511185Serfan.azarkhish@unibo.it * accesses only). 24611185Serfan.azarkhish@unibo.it */ 24711185Serfan.azarkhish@unibo.it void trySendTiming(); 24811185Serfan.azarkhish@unibo.it 24911185Serfan.azarkhish@unibo.it /** Send event for the request queue. */ 25011185Serfan.azarkhish@unibo.it EventWrapper<SerialLinkMasterPort, 25111185Serfan.azarkhish@unibo.it &SerialLinkMasterPort::trySendTiming> sendEvent; 25211185Serfan.azarkhish@unibo.it 25311185Serfan.azarkhish@unibo.it public: 25411185Serfan.azarkhish@unibo.it 25511185Serfan.azarkhish@unibo.it /** 25611185Serfan.azarkhish@unibo.it * Constructor for the SerialLinkMasterPort. 25711185Serfan.azarkhish@unibo.it * 25811185Serfan.azarkhish@unibo.it * @param _name the port name including the owner 25911185Serfan.azarkhish@unibo.it * @param _serial_link the structural owner 26011185Serfan.azarkhish@unibo.it * @param _slavePort the slave port on the other side of the 26111185Serfan.azarkhish@unibo.it * serial_link 26211185Serfan.azarkhish@unibo.it * @param _delay the delay in cycles from receiving to sending 26311185Serfan.azarkhish@unibo.it * @param _req_limit the size of the request queue 26411185Serfan.azarkhish@unibo.it */ 26511185Serfan.azarkhish@unibo.it SerialLinkMasterPort(const std::string& _name, SerialLink& 26611185Serfan.azarkhish@unibo.it _serial_link, SerialLinkSlavePort& _slavePort, Cycles 26711185Serfan.azarkhish@unibo.it _delay, int _req_limit); 26811185Serfan.azarkhish@unibo.it 26911185Serfan.azarkhish@unibo.it /** 27011185Serfan.azarkhish@unibo.it * Is this side blocked from accepting new request packets. 27111185Serfan.azarkhish@unibo.it * 27211185Serfan.azarkhish@unibo.it * @return true if the occupied space has reached the set limit 27311185Serfan.azarkhish@unibo.it */ 27411185Serfan.azarkhish@unibo.it bool reqQueueFull() const; 27511185Serfan.azarkhish@unibo.it 27611185Serfan.azarkhish@unibo.it /** 27711185Serfan.azarkhish@unibo.it * Queue a request packet to be sent out later and also schedule 27811185Serfan.azarkhish@unibo.it * a send if necessary. 27911185Serfan.azarkhish@unibo.it * 28011185Serfan.azarkhish@unibo.it * @param pkt a request to send out after a delay 28111185Serfan.azarkhish@unibo.it * @param when tick when response packet should be sent 28211185Serfan.azarkhish@unibo.it */ 28311185Serfan.azarkhish@unibo.it void schedTimingReq(PacketPtr pkt, Tick when); 28411185Serfan.azarkhish@unibo.it 28511185Serfan.azarkhish@unibo.it /** 28611185Serfan.azarkhish@unibo.it * Check a functional request against the packets in our 28711185Serfan.azarkhish@unibo.it * request queue. 28811185Serfan.azarkhish@unibo.it * 28911185Serfan.azarkhish@unibo.it * @param pkt packet to check against 29011185Serfan.azarkhish@unibo.it * 29111185Serfan.azarkhish@unibo.it * @return true if we find a match 29211185Serfan.azarkhish@unibo.it */ 29311185Serfan.azarkhish@unibo.it bool checkFunctional(PacketPtr pkt); 29411185Serfan.azarkhish@unibo.it 29511185Serfan.azarkhish@unibo.it protected: 29611185Serfan.azarkhish@unibo.it 29711185Serfan.azarkhish@unibo.it /** When receiving a timing request from the peer port, 29811185Serfan.azarkhish@unibo.it pass it to the serial_link. */ 29911185Serfan.azarkhish@unibo.it bool recvTimingResp(PacketPtr pkt); 30011185Serfan.azarkhish@unibo.it 30111185Serfan.azarkhish@unibo.it /** When receiving a retry request from the peer port, 30211185Serfan.azarkhish@unibo.it pass it to the serial_link. */ 30311185Serfan.azarkhish@unibo.it void recvReqRetry(); 30411185Serfan.azarkhish@unibo.it }; 30511185Serfan.azarkhish@unibo.it 30611185Serfan.azarkhish@unibo.it /** Slave port of the serial_link. */ 30711185Serfan.azarkhish@unibo.it SerialLinkSlavePort slavePort; 30811185Serfan.azarkhish@unibo.it 30911185Serfan.azarkhish@unibo.it /** Master port of the serial_link. */ 31011185Serfan.azarkhish@unibo.it SerialLinkMasterPort masterPort; 31111185Serfan.azarkhish@unibo.it 31211185Serfan.azarkhish@unibo.it /** Number of parallel lanes in this serial link */ 31311185Serfan.azarkhish@unibo.it unsigned num_lanes; 31411185Serfan.azarkhish@unibo.it 31511551Sabdul.mutaal@gmail.com /** Speed of each link (Gb/s) in this serial link */ 31611551Sabdul.mutaal@gmail.com uint64_t link_speed; 31711551Sabdul.mutaal@gmail.com 31811185Serfan.azarkhish@unibo.it public: 31911185Serfan.azarkhish@unibo.it 32011185Serfan.azarkhish@unibo.it virtual BaseMasterPort& getMasterPort(const std::string& if_name, 32111185Serfan.azarkhish@unibo.it PortID idx = InvalidPortID); 32211185Serfan.azarkhish@unibo.it virtual BaseSlavePort& getSlavePort(const std::string& if_name, 32311185Serfan.azarkhish@unibo.it PortID idx = InvalidPortID); 32411185Serfan.azarkhish@unibo.it 32511185Serfan.azarkhish@unibo.it virtual void init(); 32611185Serfan.azarkhish@unibo.it 32711185Serfan.azarkhish@unibo.it typedef SerialLinkParams Params; 32811185Serfan.azarkhish@unibo.it 32911185Serfan.azarkhish@unibo.it SerialLink(SerialLinkParams *p); 33011185Serfan.azarkhish@unibo.it}; 33111185Serfan.azarkhish@unibo.it 33211185Serfan.azarkhish@unibo.it#endif //__MEM_SERIAL_LINK_HH__ 333