Skip to content

Commit

Permalink
Began adding Xilinx FPGA support for jtagsh. Moved some common APIs t…
Browse files Browse the repository at this point in the history
…o XilinxFPGA class from derived classes
  • Loading branch information
azonenberg committed Jul 24, 2018
1 parent aee303e commit eed3e38
Show file tree
Hide file tree
Showing 11 changed files with 89 additions and 39 deletions.
2 changes: 2 additions & 0 deletions ARMCortexA9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ void ARMCortexA9::PrintInfo()
//uint32_t pss_idcode = ReadMemory(0xF8000530);
//LogDebug("pss_idcode = %08x\n", pss_idcode);

/*
//Read MCTRL
uint32_t mctrl = ReadMemory(0xF8007080);
LogDebug("mctrl = %08x\n", mctrl);
Expand All @@ -95,6 +96,7 @@ void ARMCortexA9::PrintInfo()
m_ap->GetDebugPort()->WriteMemory(0xe000a040, 0x00000000); //gpio.XGPIOPS_DATA_OFFSET
usleep(500 * 1000);
}
*/

//MIO LED @ MIO7
//MIO inputs at MIO50, 51
Expand Down
2 changes: 1 addition & 1 deletion FreescaleIMXSmartDMA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
using namespace std;

FreescaleIMXSmartDMA::FreescaleIMXSmartDMA(
unsigned int devid, unsigned int stepping,
unsigned int /*devid*/, unsigned int /*stepping*/,
unsigned int idcode, JtagInterface* iface, size_t pos)
: FreescaleDevice(idcode, iface, pos, 4)
{
Expand Down
4 changes: 2 additions & 2 deletions JtagDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ using namespace std;
@param pos Position in the chain that this device was discovered
@param irlength Length of the JTAG instruction register
*/
JtagDevice::JtagDevice(unsigned int idcode, JtagInterface* iface, size_t pos, size_t irlength)
JtagDevice::JtagDevice(uint32_t idcode, JtagInterface* iface, size_t pos, size_t irlength)
: m_irlength(irlength)
, m_idcode(idcode)
, m_iface(iface)
Expand All @@ -80,7 +80,7 @@ JtagDevice::~JtagDevice()
@return A valid JtagDevice object, or NULL if the vendor ID was not recognized.
*/
JtagDevice* JtagDevice::CreateDevice(unsigned int idcode, JtagInterface* iface, size_t pos)
JtagDevice* JtagDevice::CreateDevice(uint32_t idcode, JtagInterface* iface, size_t pos)
{
//Rightmost bit is always a zero, ignore it
unsigned int idcode_s = (idcode >> 1) & 0x7ff;
Expand Down
28 changes: 25 additions & 3 deletions JtagDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@

class JtagInterface;

#define RegisterConstant(c) m_constantMap[(#c)] = c

/**
@brief Represents a single device in the JTAG chain
Expand All @@ -46,7 +48,7 @@ class JtagInterface;
class JtagDevice
{
public:
JtagDevice(unsigned int idcode, JtagInterface* iface, size_t pos, size_t irlength);
JtagDevice(uint32_t idcode, JtagInterface* iface, size_t pos, size_t irlength);
virtual ~JtagDevice();

/**
Expand All @@ -60,7 +62,7 @@ class JtagDevice

unsigned int GetIDCode();

static JtagDevice* CreateDevice(unsigned int idcode, JtagInterface* iface, size_t pos);
static JtagDevice* CreateDevice(uint32_t idcode, JtagInterface* iface, size_t pos);

virtual void PrintInfo();

Expand All @@ -69,6 +71,17 @@ class JtagDevice
*/
virtual void PostInitProbes() =0;

bool LookupConstant(std::string name, uint32_t& value)
{
if(m_constantMap.find(name) != m_constantMap.end())
{
value = m_constantMap[name];
return true;
}
else
return false;
}

public:
//JTAG interface helpers
void SetIR(const unsigned char* data)
Expand All @@ -93,6 +106,12 @@ class JtagDevice
size_t GetIRLength()
{ return m_irlength; }

size_t GetChainIndex()
{ return m_pos; }

uint32_t GetIdcode()
{ return m_idcode; }

void EnterShiftDR();
void ShiftData(const unsigned char* send_data, unsigned char* rcv_data, int count);

Expand All @@ -101,7 +120,7 @@ class JtagDevice
size_t m_irlength;

///32-bit JEDEC ID code of this device
unsigned int m_idcode;
uint32_t m_idcode;

///The JTAGInterface associated with this device
JtagInterface* m_iface;
Expand All @@ -111,6 +130,9 @@ class JtagDevice

///Cached IR
unsigned char m_cachedIR[4];

//Map of constant names to values, used by jtagsh and other scripting support
std::map<std::string, uint32_t> m_constantMap;
};

#endif
36 changes: 28 additions & 8 deletions Xilinx7SeriesDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,26 @@ Xilinx7SeriesDevice::Xilinx7SeriesDevice(
, m_arraysize(arraysize)
, m_rev(rev)
{
RegisterConstant(CONFIG_CRC);
RegisterConstant(CONFIG_FAR);
RegisterConstant(CONFIG_FDRI);
RegisterConstant(CONFIG_FDRO);
RegisterConstant(CONFIG_CMD);
RegisterConstant(CONFIG_CTL0);
RegisterConstant(CONFIG_MASK);
RegisterConstant(CONFIG_STAT);
RegisterConstant(CONFIG_LOUT);
RegisterConstant(CONFIG_COR0);
RegisterConstant(CONFIG_MFWR);
RegisterConstant(CONFIG_CBC);
RegisterConstant(CONFIG_IDCODE);
RegisterConstant(CONFIG_AXSS);
RegisterConstant(CONFIG_COR1);
RegisterConstant(CONFIG_WBSTAR);
RegisterConstant(CONFIG_TIMER);
RegisterConstant(CONFIG_BOOTSTS);
RegisterConstant(CONFIG_CTL1);
RegisterConstant(CONFIG_BSPI);
}
/**
@brief Empty virtual destructor
Expand Down Expand Up @@ -211,7 +231,7 @@ void Xilinx7SeriesDevice::GetSerialNumber(unsigned char* data)
bool Xilinx7SeriesDevice::IsProgrammed()
{
Xilinx7SeriesDeviceStatusRegister statreg;
statreg.word = ReadWordConfigRegister(X7_CONFIG_REG_STAT);
statreg.word = ReadWordConfigRegister(CONFIG_STAT);
return statreg.bits.done;
}

Expand All @@ -237,7 +257,7 @@ void Xilinx7SeriesDevice::InternalErase()
int i;
for(i=0; i<10; i++)
{
statreg.word = ReadWordConfigRegister(X7_CONFIG_REG_STAT);
statreg.word = ReadWordConfigRegister(CONFIG_STAT);
if(statreg.bits.init_b)
break;

Expand Down Expand Up @@ -338,7 +358,7 @@ void Xilinx7SeriesDevice::Program(FirmwareImage* image)

//Get the status register and verify that configuration was successful
Xilinx7SeriesDeviceStatusRegister statreg;
statreg.word = ReadWordConfigRegister(X7_CONFIG_REG_STAT);
statreg.word = ReadWordConfigRegister(CONFIG_STAT);
if(statreg.bits.done != 1 || statreg.bits.gwe != 1)
{
if(statreg.bits.crc_err)
Expand All @@ -362,7 +382,7 @@ void Xilinx7SeriesDevice::Program(FirmwareImage* image)
void Xilinx7SeriesDevice::PrintStatusRegister()
{
Xilinx7SeriesDeviceStatusRegister statreg;
statreg.word = ReadWordConfigRegister(X7_CONFIG_REG_STAT);
statreg.word = ReadWordConfigRegister(CONFIG_STAT);
LogIndenter li;
LogVerbose(
"Status register is 0x%04x\n"
Expand Down Expand Up @@ -548,7 +568,7 @@ void Xilinx7SeriesDevice::ParseBitstreamInternals(
fpos += sizeof(syncword);

//String names for config regs
static const char* config_register_names[X7_CONFIG_REG_MAX]=
static const char* config_register_names[CONFIG_MAX]=
{
"CRC",
"FAR",
Expand Down Expand Up @@ -635,7 +655,7 @@ void Xilinx7SeriesDevice::ParseBitstreamInternals(
}

//Validate frame
if(frame.bits.reg_addr >= X7_CONFIG_REG_MAX)
if(frame.bits.reg_addr >= CONFIG_MAX)
{
LogWarning("[Xilinx7SeriesDevice] Invalid register address 0x%x in config frame at bitstream offset %02x\n",
frame.bits.reg_addr, (int)fpos);
Expand All @@ -661,7 +681,7 @@ void Xilinx7SeriesDevice::ParseBitstreamInternals(
//Look at the frame data
switch(frame.bits.reg_addr)
{
case X7_CONFIG_REG_CMD:
case CONFIG_CMD:
{
//Expect 1 word
if(frame.bits.count != 1)
Expand All @@ -684,7 +704,7 @@ void Xilinx7SeriesDevice::ParseBitstreamInternals(
}
}
break;
case X7_CONFIG_REG_IDCODE:
case CONFIG_IDCODE:
{
//Expect 1 word
if(frame.bits.count != 1)
Expand Down
42 changes: 21 additions & 21 deletions Xilinx7SeriesDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -362,36 +362,36 @@ class Xilinx7SeriesDevice : public XilinxFPGA
*/
enum x7_config_regs
{
X7_CONFIG_REG_CRC = 0x00,
X7_CONFIG_REG_FAR = 0x01,
X7_CONFIG_REG_FDRI = 0x02,
X7_CONFIG_REG_FDRO = 0x03,
X7_CONFIG_REG_CMD = 0x04,
X7_CONFIG_REG_CTL0 = 0x05,
X7_CONFIG_REG_MASK = 0x06,
X7_CONFIG_REG_STAT = 0x07,
X7_CONFIG_REG_LOUT = 0x08,
X7_CONFIG_REG_COR0 = 0x09,
X7_CONFIG_REG_MFWR = 0x0A,
X7_CONFIG_REG_CBC = 0x0B,
X7_CONFIG_REG_IDCODE = 0x0C,
X7_CONFIG_REG_AXSS = 0x0D,
X7_CONFIG_REG_COR1 = 0x0E,
CONFIG_CRC = 0x00,
CONFIG_FAR = 0x01,
CONFIG_FDRI = 0x02,
CONFIG_FDRO = 0x03,
CONFIG_CMD = 0x04,
CONFIG_CTL0 = 0x05,
CONFIG_MASK = 0x06,
CONFIG_STAT = 0x07,
CONFIG_LOUT = 0x08,
CONFIG_COR0 = 0x09,
CONFIG_MFWR = 0x0A,
CONFIG_CBC = 0x0B,
CONFIG_IDCODE = 0x0C,
CONFIG_AXSS = 0x0D,
CONFIG_COR1 = 0x0E,
//0x0F reserved or usused
X7_CONFIG_REG_WBSTAR = 0x10,
X7_CONFIG_REG_TIMER = 0x11,
CONFIG_WBSTAR = 0x10,
CONFIG_TIMER = 0x11,
//0x12 reserved or unused
//0x13 reserved or unused
//0x14 reserved or unused
//0x15 reserved or unused
X7_CONFIG_REG_BOOTSTS = 0x16,
CONFIG_BOOTSTS = 0x16,
//0x17 reserved or unused
X7_CONFIG_REG_CTL1 = 0x18,
CONFIG_CTL1 = 0x18,
//0x19 and up reserved or unused

X7_CONFIG_REG_BSPI = 0x1F,
CONFIG_BSPI = 0x1F,

X7_CONFIG_REG_MAX //max config reg value
CONFIG_MAX //max config reg value
};

/**
Expand Down
4 changes: 4 additions & 0 deletions XilinxFPGA.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ class XilinxFPGA : public XilinxDevice

virtual void PostInitProbes();

public:
//Configuration bus access
virtual uint32_t ReadWordConfigRegister(unsigned int reg) =0;

protected:
//Static function for parsing bitstream headers (common to all Xilinx devices)
void ParseBitstreamCore(XilinxFPGABitstream* bitstream, const unsigned char* data, size_t len);\
Expand Down
2 changes: 1 addition & 1 deletion XilinxSpartan3ADevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ class XilinxSpartan3ADevice : public XilinxFPGA
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Internal configuration helpers
protected:
uint32_t ReadWordConfigRegister(unsigned int reg);
virtual uint32_t ReadWordConfigRegister(unsigned int reg);
/*
void ReadWordsConfigRegister(unsigned int reg, uint16_t* dout, unsigned int count);
void WriteWordConfigRegister(unsigned int reg, uint16_t value);
Expand Down
4 changes: 3 additions & 1 deletion XilinxSpartan6Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,10 @@ void XilinxSpartan6Device::PrintStatusRegister()
@throw JtagException if the read fails
@param reg The configuration register to read
@return The register value. Note that only the low 16 bits are valid but XilinxFPGA's API has 32 in the return type
*/
uint16_t XilinxSpartan6Device::ReadWordConfigRegister(unsigned int reg)
uint32_t XilinxSpartan6Device::ReadWordConfigRegister(unsigned int reg)
{
//Send the read request
SetIR(INST_CFG_IN);
Expand Down
2 changes: 1 addition & 1 deletion XilinxSpartan6Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ class XilinxSpartan6Device : public XilinxFPGA
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Internal configuration helpers
protected:
uint16_t ReadWordConfigRegister(unsigned int reg);
virtual uint32_t ReadWordConfigRegister(unsigned int reg);
void ReadWordsConfigRegister(unsigned int reg, uint16_t* dout, unsigned int count);
void WriteWordConfigRegister(unsigned int reg, uint16_t value);

Expand Down
2 changes: 1 addition & 1 deletion XilinxUltrascaleDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ class XilinxUltrascaleDevice : public XilinxFPGA
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Internal configuration helpers
protected:
uint32_t ReadWordConfigRegister(unsigned int reg);
virtual uint32_t ReadWordConfigRegister(unsigned int reg);

virtual void ParseBitstreamInternals(
const unsigned char* data,
Expand Down

0 comments on commit eed3e38

Please sign in to comment.