1
0
mirror of synced 2026-01-28 12:18:43 +00:00
Files
andrastantos.cray-sim/simulator/sim_lib/exchange_packet.h
2021-03-01 16:34:31 +00:00

596 lines
30 KiB
C++

#ifndef __EXCHANGE_PACKET_H__
#define __EXCHANGE_PACKET_H__
#include "utils.h"
#if defined(PARTIAL_DEBUG) && defined(_MSC_VER)
#pragma optimize ("", off)
#endif
class XmpErrorType_c {
public:
explicit XmpErrorType_c(uint8_t aData): Data(aData) {}
explicit XmpErrorType_c(uint64_t aData): Data((uint8_t)aData) {}
bool IsUncorrectable() const { return (Data & UncorrectableMask) != 0; }
bool IsCorrectable() const { return (Data & CorrectableMask) != 0; }
void SetUncorrectable(bool aValue) { Data = SET_BITS(Data, UncorrectableMask, aValue ? UncorrectableMask : 0); }
void SetCorrectable(bool aValue) { Data = SET_BITS(Data, CorrectableMask, aValue ? CorrectableMask : 0); }
operator uint8_t() { return Data; }
protected:
enum {
CorrectableMask = 1,
UncorrectableMask = 2
};
uint8_t Data;
};
inline std::ostream & operator << (std::ostream &aStream, const XmpErrorType_c &aE) {
aStream << (aE.IsCorrectable() ? ".C" : ".-");
aStream << (aE.IsUncorrectable() ? ".U." : ".-.");
return aStream;
}
class Mode_c {
public:
Mode_c() {
mWaitingForSemaphore = false;
mYmpEnableSecondVectorLogical = false;
mSv1BitMatrixLoaded = false;
mFloatingPointErrorStatus = false;
mBidirectionalMemoryMode = false;
mOperandRangeErrorMode = false;
mFloatingPointErrorMode = false;
mUncorrectableMemoryErrorMode = false;
mCorrectableMemoryErrorMode = false;
mYmpEnhancedAddressingMode = false;
mSelectedForExternalInterrupts = false;
mInterruptMonitorMode = false;
mMonitorMode = false;
}
explicit Mode_c(uint16_t aData, MachineTypes_e aMachineType): mMachineType(aMachineType) {
if (IsXmp(mMachineType)) {
mWaitingForSemaphore = (aData & uint16_t(XmpModes_e::WaitingForSemaphore)) != 0;
mYmpEnableSecondVectorLogical = false;
mSv1BitMatrixLoaded = false;
mFloatingPointErrorStatus = (aData & uint16_t(XmpModes_e::FloatingPointErrorStatus)) != 0;
mBidirectionalMemoryMode = (aData & uint16_t(XmpModes_e::BidirectionalMemoryMode)) != 0;
mOperandRangeErrorMode = (aData & uint16_t(XmpModes_e::OperandRangeErrorMode)) != 0;
mFloatingPointErrorMode = (aData & uint16_t(XmpModes_e::FloatingPointErrorMode)) != 0;
mUncorrectableMemoryErrorMode = (aData & uint16_t(XmpModes_e::UncorrectableMemoryErrorMode)) != 0;
mCorrectableMemoryErrorMode = (aData & uint16_t(XmpModes_e::CorrectableMemoryErrorMode)) != 0;
mYmpEnhancedAddressingMode = false;
mSelectedForExternalInterrupts = (aData & uint16_t(XmpModes_e::SelectedForExternalInterrupts)) != 0;
mInterruptMonitorMode = (aData & uint16_t(XmpModes_e::InterruptMonitorMode)) != 0;
mMonitorMode = (aData & uint16_t(XmpModes_e::MonitorMode)) != 0;
} else {
mWaitingForSemaphore = (aData & uint16_t(YmpModes_e::WaitingForSemaphore)) != 0;
mYmpEnableSecondVectorLogical = (aData & uint16_t(YmpModes_e::YmpEnableSecondVectorLogical)) != 0;
mSv1BitMatrixLoaded = mMachineType == MachineTypes_e::SV1 ? (aData & uint16_t(YmpModes_e::Sv1BitMatrixLoaded)) != 0 : false;
mFloatingPointErrorStatus = (aData & uint16_t(YmpModes_e::FloatingPointErrorStatus)) != 0;
mBidirectionalMemoryMode = (aData & uint16_t(YmpModes_e::BidirectionalMemoryMode)) != 0;
mOperandRangeErrorMode = (aData & uint16_t(YmpModes_e::OperandRangeErrorMode)) != 0;
mFloatingPointErrorMode = (aData & uint16_t(YmpModes_e::FloatingPointErrorMode)) != 0;
mUncorrectableMemoryErrorMode = (aData & uint16_t(YmpModes_e::UncorrectableMemoryErrorMode)) != 0;
mCorrectableMemoryErrorMode = (aData & uint16_t(YmpModes_e::CorrectableMemoryErrorMode)) != 0;
mYmpEnhancedAddressingMode = (aData & uint16_t(YmpModes_e::YmpEnhancedAddressingMode)) != 0;
mSelectedForExternalInterrupts = (aData & uint16_t(YmpModes_e::SelectedForExternalInterrupts)) != 0;
mInterruptMonitorMode = (aData & uint16_t(YmpModes_e::InterruptMonitorMode)) != 0;
mMonitorMode = (aData & uint16_t(YmpModes_e::MonitorMode)) != 0;
}
}
uint16_t GetRawValue() const {
uint16_t RetVal = 0;
if (IsXmp(mMachineType)) {
RetVal |= mWaitingForSemaphore ? uint16_t(XmpModes_e::WaitingForSemaphore) : 0;
RetVal |= mFloatingPointErrorStatus ? uint16_t(XmpModes_e::FloatingPointErrorStatus) : 0;
RetVal |= mBidirectionalMemoryMode ? uint16_t(XmpModes_e::BidirectionalMemoryMode) : 0;
RetVal |= mOperandRangeErrorMode ? uint16_t(XmpModes_e::OperandRangeErrorMode) : 0;
RetVal |= mFloatingPointErrorMode ? uint16_t(XmpModes_e::FloatingPointErrorMode) : 0;
RetVal |= mUncorrectableMemoryErrorMode ? uint16_t(XmpModes_e::UncorrectableMemoryErrorMode) : 0;
RetVal |= mCorrectableMemoryErrorMode ? uint16_t(XmpModes_e::CorrectableMemoryErrorMode) : 0;
RetVal |= mSelectedForExternalInterrupts ? uint16_t(XmpModes_e::SelectedForExternalInterrupts) : 0;
RetVal |= mInterruptMonitorMode ? uint16_t(XmpModes_e::InterruptMonitorMode) : 0;
RetVal |= mMonitorMode ? uint16_t(XmpModes_e::MonitorMode) : 0;
}
else {
RetVal |= mWaitingForSemaphore ? uint16_t(YmpModes_e::WaitingForSemaphore) : 0;
RetVal |= mYmpEnableSecondVectorLogical ? uint16_t(YmpModes_e::YmpEnableSecondVectorLogical) : 0;
if (mMachineType == MachineTypes_e::SV1) {
RetVal |= mSv1BitMatrixLoaded ? uint16_t(YmpModes_e::Sv1BitMatrixLoaded) : 0;
}
RetVal |= mFloatingPointErrorStatus ? uint16_t(YmpModes_e::FloatingPointErrorStatus) : 0;
RetVal |= mBidirectionalMemoryMode ? uint16_t(YmpModes_e::BidirectionalMemoryMode) : 0;
RetVal |= mOperandRangeErrorMode ? uint16_t(YmpModes_e::OperandRangeErrorMode) : 0;
RetVal |= mFloatingPointErrorMode ? uint16_t(YmpModes_e::FloatingPointErrorMode) : 0;
RetVal |= mUncorrectableMemoryErrorMode ? uint16_t(YmpModes_e::UncorrectableMemoryErrorMode) : 0;
RetVal |= mCorrectableMemoryErrorMode ? uint16_t(YmpModes_e::CorrectableMemoryErrorMode) : 0;
RetVal |= mYmpEnhancedAddressingMode ? uint16_t(YmpModes_e::YmpEnhancedAddressingMode) : 0;
RetVal |= mSelectedForExternalInterrupts ? uint16_t(YmpModes_e::SelectedForExternalInterrupts) : 0;
RetVal |= mInterruptMonitorMode ? uint16_t(YmpModes_e::InterruptMonitorMode) : 0;
RetVal |= mMonitorMode ? uint16_t(YmpModes_e::MonitorMode) : 0;
}
return RetVal;
}
bool IsWaitingForSemaphore() const { return mWaitingForSemaphore; }
bool IsYmpEnableSecondVectorLogical() const { return mYmpEnableSecondVectorLogical; }
bool IsSv1BitMatrixLoaded() const { return mSv1BitMatrixLoaded; }
bool IsFloatingPointErrorStatus() const { return mFloatingPointErrorStatus; }
bool IsBidirectionalMemoryMode() const { return mBidirectionalMemoryMode; }
bool IsOperandRangeErrorMode() const { return mOperandRangeErrorMode; }
bool IsFloatingPointErrorMode() const { return mFloatingPointErrorMode; }
bool IsUncorrectableMemoryErrorMode() const { return mUncorrectableMemoryErrorMode; }
bool IsCorrectableMemoryErrorMode() const { return mCorrectableMemoryErrorMode; }
bool IsYmpEnhancedAddressingMode() const { return mYmpEnhancedAddressingMode; }
bool IsSelectedForExternalInterrupts() const { return mSelectedForExternalInterrupts; }
bool IsInterruptMonitorMode() const { return mInterruptMonitorMode; }
bool IsMonitorMode() const { return mMonitorMode; }
void SetWaitingForSemaphore(bool aValue) { mWaitingForSemaphore = aValue; }
void SetYmpEnableSecondVectorLogical(bool aValue) { CRAY_ASSERT(!IsXmp(mMachineType) || !aValue); mYmpEnableSecondVectorLogical = aValue; }
void SetSv1BitMatrixLoaded(bool aValue) { CRAY_ASSERT(mMachineType == MachineTypes_e::SV1 || !aValue); mSv1BitMatrixLoaded = aValue; }
void SetFloatingPointErrorStatus(bool aValue) { mFloatingPointErrorStatus = aValue; }
void SetBidirectionalMemoryMode(bool aValue) { mBidirectionalMemoryMode = aValue; }
void SetOperandRangeErrorMode(bool aValue) { mOperandRangeErrorMode = aValue; }
void SetFloatingPointErrorMode(bool aValue) {
mFloatingPointErrorMode = aValue;
if (aValue) {
std::cout << "mFloatingPointErrorMode is set!" << std::endl;
}
}
void SetUncorrectableMemoryErrorMode(bool aValue) { mUncorrectableMemoryErrorMode = aValue; }
void SetCorrectableMemoryErrorMode(bool aValue) { mCorrectableMemoryErrorMode = aValue; }
void SetYmpEnhancedAddressingMode(bool aValue) { CRAY_ASSERT(!IsXmp(mMachineType) || !aValue); mYmpEnhancedAddressingMode = aValue; }
void SetSelectedForExternalInterrupts(bool aValue) { mSelectedForExternalInterrupts = aValue; }
void SetInterruptMonitorMode(bool aValue) { mInterruptMonitorMode = aValue; }
void SetMonitorMode(bool aValue) { mMonitorMode = aValue; }
protected:
enum class XmpModes_e {
WaitingForSemaphore = 0x0010,
FloatingPointErrorStatus = 0x0008,
BidirectionalMemoryMode = 0x0004,
SelectedForExternalInterrupts = 0x0002,
InterruptMonitorMode = 0x0001,
OperandRangeErrorMode = 0x0200,
CorrectableMemoryErrorMode = 0x0100,
FloatingPointErrorMode = 0x0080,
UncorrectableMemoryErrorMode = 0x0040,
MonitorMode = 0x0020
};
enum class YmpModes_e {
WaitingForSemaphore = 0x1000,
YmpEnableSecondVectorLogical = 0x0800,
Sv1BitMatrixLoaded = 0x0400, // NOTE: this is the 'PS' bit in the J90.
FloatingPointErrorStatus = 0x0200,
BidirectionalMemoryMode = 0x0100,
OperandRangeErrorMode = 0x0080,
FloatingPointErrorMode = 0x0040,
UncorrectableMemoryErrorMode = 0x0020,
CorrectableMemoryErrorMode = 0x0010,
YmpEnhancedAddressingMode = 0x0008,
SelectedForExternalInterrupts = 0x0004,
InterruptMonitorMode = 0x0002,
MonitorMode = 0x0001
};
bool mWaitingForSemaphore;
bool mYmpEnableSecondVectorLogical;
bool mSv1BitMatrixLoaded;
bool mFloatingPointErrorStatus;
bool mBidirectionalMemoryMode;
bool mOperandRangeErrorMode;
bool mFloatingPointErrorMode;
bool mUncorrectableMemoryErrorMode;
bool mCorrectableMemoryErrorMode;
bool mYmpEnhancedAddressingMode;
bool mSelectedForExternalInterrupts;
bool mInterruptMonitorMode;
bool mMonitorMode;
public:
MachineTypes_e mMachineType;
};
inline std::ostream & operator << (std::ostream &aStream, const Mode_c &aMode) {
if (IsXmp(aMode.mMachineType)) {
aStream << (aMode.IsWaitingForSemaphore() ? ".WS" : ".--");
aStream << (aMode.IsFloatingPointErrorStatus() ? ".FPS" : ".---");
aStream << (aMode.IsBidirectionalMemoryMode() ? ".BDM" : ".---");
aStream << (aMode.IsSelectedForExternalInterrupts() ? ".SEI" : ".---");
aStream << (aMode.IsInterruptMonitorMode() ? ".IMM" : ".---");
aStream << (aMode.IsOperandRangeErrorMode() ? ".IOR" : ".---");
aStream << (aMode.IsCorrectableMemoryErrorMode() ? ".ICM" : ".---");
aStream << (aMode.IsFloatingPointErrorMode() ? ".IFP" : ".---");
aStream << (aMode.IsUncorrectableMemoryErrorMode() ? ".IUM" : ".---");
aStream << (aMode.IsMonitorMode() ? ".MM." : ".--.");
} else {
aStream << (aMode.IsWaitingForSemaphore() ? ".WS" : ".--");
aStream << (aMode.IsYmpEnableSecondVectorLogical() ? ".ESVL" : ".----");
aStream << (aMode.IsSv1BitMatrixLoaded() ? ".BML" : ".---");
aStream << (aMode.IsFloatingPointErrorStatus() ? ".FPS" : ".---");
aStream << (aMode.IsBidirectionalMemoryMode() ? ".BDM" : ".---");
aStream << (aMode.IsOperandRangeErrorMode() ? ".IOR" : ".---");
aStream << (aMode.IsFloatingPointErrorMode() ? ".IFP" : ".---");
aStream << (aMode.IsUncorrectableMemoryErrorMode() ? ".IUM" : ".---");
aStream << (aMode.IsCorrectableMemoryErrorMode() ? ".ICM" : ".---");
aStream << (aMode.IsYmpEnhancedAddressingMode() ? ".EAM" : ".---");
aStream << (aMode.IsSelectedForExternalInterrupts() ? ".SEI" : ".---");
aStream << (aMode.IsInterruptMonitorMode() ? ".IMM" : ".---");
aStream << (aMode.IsMonitorMode() ? ".MM." : ".--.");
}
return aStream;
}
class Flags_c {
public:
Flags_c(): Data(0) {}
Flags_c(const Flags_c &aFlags) : Data(aFlags.Data) {}
explicit Flags_c(uint16_t aData): Data(aData) {}
explicit Flags_c(uint64_t aData): Data((uint16_t)aData) {}
bool IsInterruptFromInternalCpu() const { return (Data & InterProcessorInterrupt ) != 0; } // Other CPU
bool IsDeadlock() const { return (Data & Deadlock ) != 0; } // THERE'S A BUG HERE: in a deadlock, ALL processors participating in a dead-lock are interrupted. Thus, this interrupt is 'Other CPU'
bool IsProgrammableClockInterrupt() const { return (Data & ProgrammableClockInterrupt ) != 0; } // Internal
bool IsMcuInterrupt() const { return (Data & McuInterrupt ) != 0; } // IOS
bool IsFloatingPointError() const { return (Data & FloatingPointError ) != 0; } // Internal
bool IsOperandRangeError() const { return (Data & OperandRangeError ) != 0; } // Internal
bool IsProgramRangeError() const { return (Data & ProgramRangeError ) != 0; } // Internal
bool IsMemoryError() const { return (Data & MemoryError ) != 0; } // Internal
bool IsIoInterrupt() const { return (Data & IoInterrupt ) != 0; } // IOS (routed)
bool IsErrorExit() const { return (Data & ErrorExit ) != 0; } // Internal
bool IsNormalExit() const { return (Data & NormalExit ) != 0; } // Internal
void SetInterProcessorInterrupt() { Data |= InterProcessorInterrupt ; }
void SetDeadlock() { Data |= Deadlock ; }
void SetProgrammableClockInterrupt() { Data |= ProgrammableClockInterrupt ; }
void SetMcuInterrupt() { Data |= McuInterrupt ; }
void SetFloatingPointError() { Data |= FloatingPointError ; }
void SetOperandRangeError() { Data |= OperandRangeError ; }
void SetProgramRangeError() { Data |= ProgramRangeError ; }
void SetMemoryError() { Data |= MemoryError ; }
void SetIoInterrupt() { Data |= IoInterrupt ; }
void SetErrorExit() { Data |= ErrorExit ; }
void SetNormalExit() { Data |= NormalExit ; }
void ClearInterProcessorInterrupt() { Data &= ~InterProcessorInterrupt ; }
void ClearDeadlock() { Data &= ~Deadlock ; }
void ClearProgrammableClockInterrupt() { Data &= ~ProgrammableClockInterrupt ; }
void ClearMcuInterrupt() { Data &= ~McuInterrupt ; }
void ClearFloatingPointError() { Data &= ~FloatingPointError ; }
void ClearOperandRangeError() { Data &= ~OperandRangeError ; }
void ClearProgramRangeError() { Data &= ~ProgramRangeError ; }
void ClearMemoryError() { Data &= ~MemoryError ; }
void ClearIoInterrupt() { Data &= ~IoInterrupt ; }
void ClearErrorExit() { Data &= ~ErrorExit ; }
void ClearNormalExit() { Data &= ~NormalExit ; }
void ClearBits(uint16_t aMask) { Data &= ~aMask ; }
// operator uint16_t() { return Data; }
enum: uint16_t {
InterProcessorInterrupt = 0x0400,
Deadlock = 0x0200,
ProgrammableClockInterrupt = 0x0100,
McuInterrupt = 0x0080,
FloatingPointError = 0x0040,
OperandRangeError = 0x0020,
ProgramRangeError = 0x0010,
MemoryError = 0x0008,
IoInterrupt = 0x0004,
ErrorExit = 0x0002,
NormalExit = 0x0001
};
uint16_t Get() const { return Data; }
void Set(uint16_t aValue) { Data = aValue; }
protected:
// AtomicUInt16 Data;
uint16_t Data;
friend class SoftCpu_c;
};
inline std::ostream & operator << (std::ostream &aStream, const Flags_c &aFlags) {
aStream << (aFlags.IsInterruptFromInternalCpu() ? ".ICP" : ".---");
aStream << (aFlags.IsDeadlock() ? ".DL" : ".--");
aStream << (aFlags.IsProgrammableClockInterrupt() ? ".PCI" : ".---");
aStream << (aFlags.IsMcuInterrupt() ? ".MCU" : ".---");
aStream << (aFlags.IsFloatingPointError() ? ".PFE" : ".---");
aStream << (aFlags.IsOperandRangeError() ? ".ORE" : ".---");
aStream << (aFlags.IsProgramRangeError() ? ".PRE" : ".---");
aStream << (aFlags.IsMemoryError() ? ".ME" : ".--");
aStream << (aFlags.IsIoInterrupt() ? ".IOI" : ".---");
aStream << (aFlags.IsErrorExit() ? ".EEX" : ".---");
aStream << (aFlags.IsNormalExit() ? ".NEX." : ".---.");
return aStream;
}
class ExchangePacket_c {
public:
static const size_t mDataSize = 16;
explicit ExchangePacket_c(MachineTypes_e aMachineType):
mMachineType(aMachineType)
{
memset(Data, 0, sizeof(Data));
if (aMachineType == MachineTypes_e::J90) SetYmpProcessorType(0);
if (aMachineType == MachineTypes_e::SV1) SetYmpProcessorType(2);
}
explicit ExchangePacket_c(MachineTypes_e aMachineType, void *aMem):
mMachineType(aMachineType)
{
Read(aMem);
if (aMachineType == MachineTypes_e::J90) SetYmpProcessorType(0);
if (aMachineType == MachineTypes_e::SV1) SetYmpProcessorType(2);
}
void SetData(CInt_t aData, size_t aOfs) {
CRAY_ASSERT(aOfs < mDataSize);
Data[aOfs] = SwapBytes(aData);
}
CInt_t GetData(size_t aOfs) const {
CRAY_ASSERT(aOfs < mDataSize);
return SwapBytes(Data[aOfs]);
}
void Read(void *aMem) {
memcpy(Data,aMem,sizeof(Data));
for(size_t i=0;i<sizeof(Data)/sizeof(Data[0]);++i) Data[i] = SwapBytes(Data[i]);
}
void Write(void *aMem) const {
uint64_t SwappedData[16];
for(size_t i=0;i<sizeof(Data)/sizeof(Data[0]);++i) SwappedData[i] = SwapBytes(Data[i]);
memcpy(aMem,SwappedData,sizeof(Data));
}
size_t GetProtectionBits() const {
switch (mMachineType) {
case MachineTypes_e::XMP1xx: return 19;
case MachineTypes_e::XMP2xx: return 17;
case MachineTypes_e::XMP4xx: return 18;
case MachineTypes_e::YMP: return 24;
case MachineTypes_e::YEL: return 23;
case MachineTypes_e::J90: return 22;
case MachineTypes_e::SV1: return 22;
default: {
throw Generic_x() << "Unknwon machine type: " << int(mMachineType);
}
}
}
size_t GetProtectionTop() const {
switch (mMachineType) {
case MachineTypes_e::XMP1xx: return 63-16;
case MachineTypes_e::XMP2xx: return 63-18;
case MachineTypes_e::XMP4xx: return 63-16;
case MachineTypes_e::YMP: return 55;
case MachineTypes_e::YEL: return 54;
case MachineTypes_e::J90: return 55;
case MachineTypes_e::SV1: return 55;
default: {
throw Generic_x() << "Unknwon machine type: " << int(mMachineType);
}
}
}
size_t GetProtectionShift() const {
switch (mMachineType) {
case MachineTypes_e::XMP1xx: return 5;
case MachineTypes_e::XMP2xx: return 5;
case MachineTypes_e::XMP4xx: return 6;
case MachineTypes_e::YMP: return 8; // ???
case MachineTypes_e::YEL: return 8;
case MachineTypes_e::J90: return 10;
case MachineTypes_e::SV1: return 10;
default: {
throw Generic_x() << "Unknwon machine type: " << int(mMachineType);
}
}
}
#ifdef CREATE_FIELD
#error CREATE_FIELD is already defined!
#endif
#ifdef CREATE_PROT_FIELD
#error CREATE_PROT_FIELD is already defined!
#endif
#define CREATE_FIELD(aaType, aaFieldName, aaWordIdx, aaStartBit, aaEndBit, aaShift) \
aaType Get##aaFieldName() const { return aaType(GetBits(Data[(aaWordIdx)],63-(aaStartBit),63-(aaEndBit)) << aaShift); } \
void Set##aaFieldName(aaType aValue) { Data[(aaWordIdx)] = SetBits(Data[(aaWordIdx)],63-(aaStartBit),63-(aaEndBit),uint64_t(aValue) >> aaShift); }
#define CREATE_PROT_FIELD(aaFieldName, aaWordIdx) \
CAddr_t Get##aaFieldName() const { return CAddr_t(GetBits(Data[(aaWordIdx)],GetProtectionTop(),GetProtectionTop()-GetProtectionBits()+1) << GetProtectionShift()); } \
void Set##aaFieldName(CAddr_t aValue) { Data[(aaWordIdx)] = SetBits(Data[(aaWordIdx)],GetProtectionTop(),GetProtectionTop()-GetProtectionBits()+1,uint64_t(aValue) >> GetProtectionShift()); }
// Type FieldName WordIdx StartBit EndBit Shift
//******************************************** XMP FIELDS ****************************************
CREATE_FIELD(uint8_t, XmpProcessorNumber, 0, 0, 1, 0)
CREATE_FIELD(XmpErrorType_c, XmpErrorType, 0, 2, 3, 0)
CREATE_FIELD(uint8_t, XmpSyndrome, 0, 4, 11, 0)
CREATE_FIELD(CProgramAddr_t, XmpProgramAddress, 0, 16, 39, 0)
CREATE_FIELD(uint8_t, XmpReadMode, 1, 0, 1, 0)
CREATE_FIELD(CAddr_t, XmpReadAddress, 1, 2, 11, 6)
CREATE_FIELD(uint8_t, XmpVectorNotUsed, 2, 0, 0, 0)
CREATE_FIELD(uint8_t, XmpEnableSecondVectorLogical, 3, 0, 0, 0)
CREATE_FIELD(uint8_t, XmpExchangeAddress, 3, 16, 23, 0)
CREATE_FIELD(uint8_t, XmpVectorLength, 3, 24, 30, 0)
CREATE_FIELD(uint8_t, XmpEnhancedAddressingMode, 4, 0, 0, 0)
CREATE_FIELD(uint8_t, XmpProgramState, 4, 35, 35, 0)
CREATE_FIELD(uint8_t, XmpClusterNumber, 4, 37, 39, 0)
CREATE_PROT_FIELD( XmpInstBaseAddr, 1)
CREATE_PROT_FIELD( XmpInstLimitAddr, 2)
CREATE_PROT_FIELD( XmpDataBaseAddr, 4)
CREATE_PROT_FIELD( XmpDataLimitAddr, 5)
//******************************************** YMP FIELDS ****************************************
CREATE_FIELD(uint8_t, YmpProcessorNumber, 0, 0, 7, 0)
CREATE_FIELD(CProgramAddr_t, YmpProgramAddress, 0, 8, 31, 0)
CREATE_FIELD(uint8_t, YmpSyndrome, 1, 0, 7, 0)
CREATE_FIELD(CAddr_t, YmpReadAddress, 2, 0, 7, 0)
CREATE_FIELD(uint8_t, YmpExchangeAddress, 5, 8, 15, 0)
CREATE_FIELD(uint8_t, YmpVectorLength, 5, 16, 22, 0)
// Here the number of bits is actually series dependent. YEL for example has 4 bits, J90 has 6. Leaving as 8 for now as it doesn't seem to cause trouble.
CREATE_FIELD(uint8_t, YmpClusterNumber, 5, 24, 31, 0)
CREATE_FIELD(uint8_t, YmpVectorNotUsed, 6, 0, 0, 0)
CREATE_FIELD(uint8_t, YmpProcessorType, 7, 0, 1, 0)
CREATE_PROT_FIELD( YmpInstBaseAddr, 1)
CREATE_PROT_FIELD( YmpInstLimitAddr, 2)
CREATE_PROT_FIELD( YmpDataBaseAddr, 3)
CREATE_PROT_FIELD( YmpDataLimitAddr, 4)
#undef CREATE_FIELD
#undef CREATE_PROT_FIELD
#ifdef CREATE_UNIFIED_FIELD
#error CREATE_UNIFIED_FIELD is already defined!
#endif
#define CREATE_UNIFIED_FIELD(aaType, aaFieldName) \
aaType Get##aaFieldName() const { if (IsXmp(mMachineType)) return GetXmp##aaFieldName(); else return GetYmp##aaFieldName(); } \
void Set##aaFieldName(aaType aValue) { if (IsXmp(mMachineType)) SetXmp##aaFieldName(aValue); else SetYmp##aaFieldName(aValue); }
CREATE_UNIFIED_FIELD(uint8_t, ProcessorNumber)
CREATE_UNIFIED_FIELD(uint8_t, Syndrome)
CREATE_UNIFIED_FIELD(CProgramAddr_t, ProgramAddress)
CREATE_UNIFIED_FIELD(uint8_t, ExchangeAddress)
CREATE_UNIFIED_FIELD(uint8_t, VectorLength)
CREATE_UNIFIED_FIELD(uint8_t, ClusterNumber)
CREATE_UNIFIED_FIELD(uint8_t, VectorNotUsed)
CREATE_UNIFIED_FIELD(CAddr_t, InstBaseAddr)
CREATE_UNIFIED_FIELD(CAddr_t, InstLimitAddr)
CREATE_UNIFIED_FIELD(CAddr_t, DataBaseAddr)
CREATE_UNIFIED_FIELD(CAddr_t, DataLimitAddr)
#undef CREATE_UNIFIED_FIELD
Mode_c GetMode() const {
if (IsXmp(mMachineType)) {
return Mode_c((uint16_t)(((uint16_t)GetBits(Data[2], 63 - 35, 63 - 39) << 5) | ((uint16_t)GetBits(Data[1], 63 - 35, 63 - 39))), mMachineType);
} else {
return Mode_c((uint16_t)(GetBits(Data[6], 32, 43) | (GetBits(Data[6], 62, 62) << 12)), mMachineType);
}
}
void SetMode(Mode_c aMode) {
uint16_t RawMode = aMode.GetRawValue();
if (IsXmp(mMachineType)) {
Data[2] = SetBits(Data[2], 63 - 35, 63 - 39, RawMode >> 5);
Data[1] = SetBits(Data[1], 63 - 35, 63 - 39, RawMode);
}
else {
Data[6] = SetBits(Data[6], 32, 43, RawMode & 0x0fff);
Data[6] = SetBits(Data[6], 62, 62, (RawMode & 0x1000) >> 12);
}
}
Flags_c GetFlag() const {
if (IsXmp(mMachineType)) {
return Flags_c((uint16_t)(((uint16_t)GetBits(Data[3], 63 - 14, 63 - 15) << 9) | ((uint16_t)GetBits(Data[3], 63 - 31, 63 - 39))));
} else {
return Flags_c(GetBits(Data[6], 44, 55));
}
}
void ClearFlags() { SetFlag(Flags_c()); }
void SetFlag(Flags_c aFlag) {
if (IsXmp(mMachineType)) {
uint16_t RawFlag = aFlag.Get();
Data[3] = SetBits(Data[3], 63 - 14, 63 - 15, RawFlag >> 9);
Data[3] = SetBits(Data[3], 63 - 31, 63 - 39, RawFlag);
}
else {
Data[6] = SetBits(Data[6], 44, 55, aFlag.Get());
}
}
uint8_t GetEnableSecondVectorLogical() const {
if (IsXmp(mMachineType)) {
return GetXmpEnableSecondVectorLogical();
} else {
return GetMode().IsYmpEnableSecondVectorLogical() ? 1 : 0;
}
}
void SetEnableSecondVectorLogical(uint8_t aValue) {
if (IsXmp(mMachineType)) {
SetXmpEnableSecondVectorLogical(aValue);
} else {
Mode_c Mode = GetMode();
Mode.SetYmpEnableSecondVectorLogical(aValue != 0);
SetMode(Mode);
}
}
CAddr_t GetA(size_t aIdx) const { return (CAddr_t)GetBits(Data[aIdx], std::numeric_limits<CAddr_t>::digits - 1, 0); }
CAddr_t GetA0() const { return GetA(0); }
CAddr_t GetA1() const { return GetA(1); }
CAddr_t GetA2() const { return GetA(2); }
CAddr_t GetA3() const { return GetA(3); }
CAddr_t GetA4() const { return GetA(4); }
CAddr_t GetA5() const { return GetA(5); }
CAddr_t GetA6() const { return GetA(6); }
CAddr_t GetA7() const { return GetA(7); }
void SetA(size_t aIdx, CAddr_t aAddr) {
if (IsXmp(mMachineType)) {
Data[aIdx] = SetBits(Data[aIdx], std::numeric_limits<CXmpAddr_t>::digits - 1, 0, aAddr);
} else {
Data[aIdx] = SetBits(Data[aIdx], std::numeric_limits<CAddr_t>::digits - 1, 0, aAddr);
}
}
void SetA0(CAddr_t aAddr) { SetA(0,aAddr); }
void SetA1(CAddr_t aAddr) { SetA(1,aAddr); }
void SetA2(CAddr_t aAddr) { SetA(2,aAddr); }
void SetA3(CAddr_t aAddr) { SetA(3,aAddr); }
void SetA4(CAddr_t aAddr) { SetA(4,aAddr); }
void SetA5(CAddr_t aAddr) { SetA(5,aAddr); }
void SetA6(CAddr_t aAddr) { SetA(6,aAddr); }
void SetA7(CAddr_t aAddr) { SetA(7,aAddr); }
uint64_t GetS(size_t aIdx) const { return Data[8+aIdx]; }
uint64_t GetS0() const { return GetS(0); }
uint64_t GetS1() const { return GetS(1); }
uint64_t GetS2() const { return GetS(2); }
uint64_t GetS3() const { return GetS(3); }
uint64_t GetS4() const { return GetS(4); }
uint64_t GetS5() const { return GetS(5); }
uint64_t GetS6() const { return GetS(6); }
uint64_t GetS7() const { return GetS(7); }
void SetS(size_t aIdx, uint64_t aS) { Data[8+aIdx] = aS; }
void SetS0(uint64_t aS) { SetS(0,aS); }
void SetS1(uint64_t aS) { SetS(1,aS); }
void SetS2(uint64_t aS) { SetS(2,aS); }
void SetS3(uint64_t aS) { SetS(3,aS); }
void SetS4(uint64_t aS) { SetS(4,aS); }
void SetS5(uint64_t aS) { SetS(5,aS); }
void SetS6(uint64_t aS) { SetS(6,aS); }
void SetS7(uint64_t aS) { SetS(7,aS); }
friend std::ostream & operator << (std::ostream &aStream, const ExchangePacket_c &aEP);
protected:
uint64_t Data[mDataSize];
MachineTypes_e mMachineType;
};
inline std::ostream & operator << (std::ostream &aStream, const ExchangePacket_c &aEP) {
for(size_t Idx=0;Idx<sizeof(aEP.Data)/sizeof(aEP.Data[0]);++Idx) {
aStream << "Raw packet " << Idx << ": " << HexPrinter(aEP.Data[Idx]) << std::endl;
}
aStream << "PN:" << DecPrinter(aEP.GetProcessorNumber(),0) << std::endl;
if (IsXmp(aEP.mMachineType)) {
aStream << "E:" << aEP.GetXmpErrorType() << std::endl;
}
aStream << "S:" << HexPrinter(aEP.GetSyndrome()) << std::endl;
if (IsXmp(aEP.mMachineType)) {
aStream << "R:" << DecPrinter(aEP.GetXmpReadMode(), 0) << std::endl;
}
aStream << "CSB:" << Addr(aEP.GetXmpReadAddress()) << std::endl;
aStream << "M:" << aEP.GetMode() << std::endl;
aStream << "VNU:" << DecPrinter(aEP.GetVectorNotUsed(),0) << std::endl;
if (IsXmp(aEP.mMachineType)) {
aStream << "ESVL:" << DecPrinter(aEP.GetEnableSecondVectorLogical(), 0) << std::endl;
aStream << "EAM:" << DecPrinter(aEP.GetXmpEnhancedAddressingMode(), 0) << std::endl;
}
aStream << "F:" << aEP.GetFlag() << std::endl;
aStream << "XA:" << HexPrinter(aEP.GetExchangeAddress()) << std::endl;
aStream << "VL:" << DecPrinter(aEP.GetVectorLength(),0) << std::endl;
if (IsXmp(aEP.mMachineType)) {
aStream << "PS:" << DecPrinter(aEP.GetXmpProgramState(),0) << std::endl;
}
aStream << "CLN:" << DecPrinter(aEP.GetClusterNumber(),0) << std::endl;
aStream << "P:" << InstAddr(aEP.GetProgramAddress()) << std::endl;
aStream << "IBA:" << Addr(aEP.GetInstBaseAddr()) << std::endl;
aStream << "ILA:" << Addr(aEP.GetInstLimitAddr()) << std::endl;
aStream << "DBA:" << Addr(aEP.GetDataBaseAddr()) << std::endl;
aStream << "DLA:" << Addr(aEP.GetDataLimitAddr()) << std::endl;
for(size_t i=0; i<8; ++i) aStream << "A" << i << ":" << HexPrinter(aEP.GetA(i)) << std::endl;
for(size_t i=0; i<8; ++i) aStream << "S" << i << ":" << HexPrinter(aEP.GetS(i)) << std::endl;
return aStream;
}
#if defined(PARTIAL_DEBUG) && defined(_MSC_VER)
#pragma optimize ("", on)
#endif
#endif // __EXCHANGE_PACKET_H__