1
0
mirror of synced 2026-02-04 14:53:01 +00:00
Files
andrastantos.cray-sim/simulator/sim_lib/iop_concentrator.h
Kevin Jordan ff5d24af3a Implement front end data communication protocol, in compliance with
"COS FRONT-END PROTOCOL INTERNAL REFERENCE MANUAL SM-0042", and make it
compatible with the implementation in DtCyber, the CDC Cyber 6000 series
emulator.
2021-11-27 17:25:04 -05:00

172 lines
5.1 KiB
C++

#ifndef __IOP_CONCENTRATOR_H__
#define __IOP_CONCENTRATOR_H__
#include "cray_iop.h"
#include <fstream>
#include <stdio.h>
#include <boost/filesystem.hpp>
#include <boost/variant.hpp>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/timer/timer.hpp>
#include "cray_channels.h"
#ifndef _WIN32
#include <unistd.h>
#endif //_WIN32
#include "config_file.h"
class IopConcentratorChannel_c: public IopChannel_i {
public:
explicit IopConcentratorChannel_c(class IopConcentrator_c &aParent, const Configuration_c &aConfig, size_t aChannelIdx, bool aAllowOut, bool aAllowIn);
virtual IopInt_t DoIo(IopIoFunction_t aFunction, IopInt_t aData) override;
virtual IopBit_t GetBusy() override { return mInActive || mOutActive; }
virtual IopBit_t GetDone() override { return mDone; }
virtual IopBit_t GetInterrupt() override;
virtual size_t GetChannelIdx() const override { return mChannelIdx; }
virtual void MasterClear() override {
mDone = false;
mHoldDisconnect = false;
mInActive = false;
mInterruptEnabled = true;
mIoMemoryAddr = 0;
mOutActive = false;
mReadyWaiting = false;
mTransferSize = 0;
mWriteDisconnect = false;
}
virtual void Tick() override;
virtual bool NeedsTick() override { return true; }
virtual void Dump(size_t aIdent=0) override {}
protected:
class IopConcentrator_c &mParent;
IopInt_t mIoMemoryAddr;
IopInt_t mTransferSize;
bool mAllowIn;
bool mAllowOut;
size_t mChannelIdx;
bool mDone;
bool mHoldDisconnect;
bool mInActive;
bool mInterruptEnabled;
bool mOutActive;
bool mReadyWaiting;
size_t mTransferDelay;
size_t mTransferDelayCounter;
bool mWriteDisconnect;
};
#define BytesPerLCP 48
#define MaxTransmitBufs 16
#define WordsPerLCP 6
/*
* Key message codes
*/
#define McLogon 001
#define McStart 004
#define McControl 011
class IopConcentrator_c: public IopPeripheral_i {
public:
enum RcvStates_e {
State_RcvLcpPduLength,
State_RcvLcpPduContent,
State_RcvSegPduLength,
State_RcvSegPduContent
};
enum XmtStates_e {
State_XmtLcpPduStart,
State_XmtLcpPduContent,
State_XmtSegPduStart,
State_XmtSegPduContent
};
explicit IopConcentrator_c(const Configuration_c &aConfig, IopCpu_c &aParent):
mAccepted(false),
mBytesTransmitted(0),
mConnectionSocket(nullptr),
mInputChannel(*this,aConfig,aConfig.get<size_t>("InputChannelIdx"),false,true),
mLastRcvdMessageCode(0),
mLastXmitMessageCode(0),
mListenSocket(nullptr),
mLogger(aConfig, "CONC"),
mOutputChannel(*this,aConfig,aConfig.get<size_t>("OutputChannelIdx"),true,false),
mParent(aParent),
mPduLength(0),
mPort(aConfig.get<uint16_t>("Port",9000)),
mRcvState(State_RcvLcpPduLength),
mSegmentSize(0),
mToCrayIdx(0),
mTransmitBufIdx(0),
mXmtState(State_XmtLcpPduStart)
{
mLogger.SetParent(mParent.GetLogger());
StartListen();
MasterClear();
}
void ClearBuffers();
virtual const IopChannel_i &GetChannel(size_t aIdx) const override {
switch (aIdx) {
case 0: return mInputChannel;
case 1: return mOutputChannel;
default: CRAY_ASSERT(false);
}
throw Generic_x("Unreachable code");
}
virtual size_t GetChannelCnt() const override { return 2; }
CInt_t GetData();
size_t GetDataSize();
CLogger_c &GetLogger() { return mLogger; }
virtual std::string GetName() const override { return "CONC"; }
IopCpu_c &GetParent() { return mParent; }
virtual void GetStatus(StatusReport_c &aStatus, PeripheralType_e aFilter, bool aLongFormat) const override {}
virtual PeripheralType_e GetType() const override { return PeripheralType_e::Other; }
bool HasData();
bool IsReceptionComplete();
void MasterClear();
void ProcessFromCrayData();
virtual void RegisterCommands(CommandHooks_t &aHooks)override {}
void SetData(CInt_t aData);
void Tick();
protected:
void AcceptHandler(const boost::system::error_code& aError);
void ClearReceiveBuffers();
void ClearTransmitBuffers();
void CloseConnSocket();
void Poll();
void ProcessReceivedBytes();
void ReadHandler(const boost::system::error_code& aError, std::size_t bytesTransferred);
void StartAccept();
void StartListen();
void StartReceive();
void StartTransmit();
void WriteHandler(const boost::system::error_code& aError, std::size_t bytesTransferred);
bool mAccepted;
size_t mBytesTransmitted;
std::shared_ptr<boost::asio::ip::tcp::socket> mConnectionSocket;
std::vector<CInt_t> mFromCrayData;
IopConcentratorChannel_c mInputChannel;
static boost::asio::io_service mIoService;
uint8_t mLastRcvdMessageCode;
uint8_t mLastXmitMessageCode;
std::shared_ptr<boost::asio::ip::tcp::acceptor> mListenSocket;
mutable CLogger_c mLogger;
IopConcentratorChannel_c mOutputChannel;
IopCpu_c &mParent;
size_t mPduLength;
size_t mPollCnt;
uint16_t mPort;
boost::asio::streambuf mReceiveBuf;
RcvStates_e mRcvState;
size_t mSegmentSize;
size_t mSubsegmentCount;
std::vector<CInt_t> mToCrayData;
size_t mToCrayIdx;
size_t mTransmitBufIdx;
boost::asio::streambuf mTransmitBufs[MaxTransmitBufs];
XmtStates_e mXmtState;
};
#endif // __IOP_CONCENTRATOR_H__