openFPGALoader/src/feaparser.cpp

226 lines
7.8 KiB
C++
Raw Normal View History

2021-11-09 09:54:09 +01:00
// SPDX-License-Identifier: Apache-2.0
/*
* Copyright (C) 2021 Martin Beynon <martin.beynon@abaco.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <strings.h>
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <utility>
#include <vector>
#include "display.hpp"
#include "feaparser.hpp"
using namespace std;
FeaParser::FeaParser(string filename, bool verbose):
ConfigBitstreamParser(filename, ConfigBitstreamParser::BIN_MODE, verbose),
_feabits(0), _has_feabits(false)
{
for (int i=0; i < 3; i++)
_featuresRow[i] = 0;
}
/* fill a vector with consecutive lines, begining with 0 or 1, until EOF
* \brief read a line with '\r''\n' or '\n' termination
* check if last char is '\r'
* \return a vector of lines without [\r]\n
*/
vector<string> FeaParser::readFeaFile()
{
vector<string> lines;
while (true) {
string buffer;
std::getline(_ss, buffer, '\n');
if (buffer.empty())
break;
/* if '\r' is present -> drop */
if (buffer.back() == '\r')
buffer.pop_back();
if (buffer.front() == '0' || buffer.front() == '1')
lines.push_back(buffer);
}
return lines;
}
void FeaParser::displayHeader()
{
if (_has_feabits) {
printf("\nFeature Row: [0x");
for(int i = 2; i >= 0; i--) {
printf("%08x", _featuresRow[i]);
}
printf("]\n");
printf("\tCore Clock Select : 0x%x\n", (_featuresRow[2] >> 30) & 0x03);
printf("\tCPU : %d\n",
((_featuresRow[2] & FEATURE_CPU)? 1 : 0));
printf("\tSSPI Auto : %s\n",
((_featuresRow[2] & FEATURE_SSPI_AUTO)?"Enabled":"Disabled"));
printf("\tReserved Zero (1) : 0x%x\n", (_featuresRow[2] >> 27) & 0x01);
printf("\tEBR Enable : %s\n",
((_featuresRow[2] & FEATURE_EBR_ENABLE)?"Yes":"No"));
printf("\tHSE Clock Select : 0x%x\n", (_featuresRow[2] >> 24) & 0x03);
printf("\tCPHA : %s\n",
((_featuresRow[2] & FEATURE_CPHA)?"Enabled":"Disabled"));
printf("\tCPOL : %s\n",
((_featuresRow[2] & FEATURE_CPOL)?"Enabled":"Disabled"));
printf("\tTx Edge : %s\n",
((_featuresRow[2] & FEATURE_TX_EDGE)?"Enabled":"Disabled"));
printf("\tRx Edge : %s\n",
((_featuresRow[2] & FEATURE_RX_EDGE)?"Enabled":"Disabled"));
printf("\tLSBF : %s\n",
((_featuresRow[2] & FEATURE_LSBF)?"Enabled":"Disabled"));
printf("\tMClock Bypass : %s\n",
((_featuresRow[2] & FEATURE_MCLK_BYPASS)?"Enabled":"Disabled"));
printf("\t32-bit SPIM : %s\n",
((_featuresRow[2] & FEATURE_32BIT_SPIM)?"Enabled":"Disabled"));
printf("\tBulk Erase Disable : %s\n",
((_featuresRow[2] & FEATURE_BULK_ERASE_DISABLE)?"Yes":"No"));
printf("\tSFDP Enable : %s\n",
((_featuresRow[2] & FEATURE_SFDP_EN)?"Yes":"No"));
printf("\tSFDP Continue on Fail : %s\n",
((_featuresRow[2] & FEATURE_SFDP_CONT_FAIL)?"Yes":"No"));
printf("\tReserved Zero (2) : 0x%x\n", (_featuresRow[2] >> 12) & 0x03);
printf("\tSlave Idle Timer Count: %d\n", (_featuresRow[2] >> 8) & 0x0f);
printf("\tMaster Timer Count : %d\n", (_featuresRow[2] >> 4) & 0x0f);
printf("\tMaster Retry Count : %d\n", (_featuresRow[2] >> 2) & 0x03);
printf("\tReserved Zero (2) : 0x%x\n", _featuresRow[2] & 0x03);
printf("\tDual Boot Address : 0x%x\n", (_featuresRow[1] >> 16) & 0xffff);
printf("\tI2C Slave Address : 0x%x\n", (_featuresRow[1] >> 8) & 0xff);
printf("\tCustom Trace ID : 0x%x\n", _featuresRow[1] & 0xff);
printf("\tCustom ID Code : 0x%x\n", _featuresRow[0]);
printf("\nFEAbits: [0x%08x]\n", _feabits);
printf("\tReserved Zero (16) : 0x%x\n", (_feabits >> 17) & 0xffff);
printf("\tRollback Protection : %s\n",
((_feabits & FEA_VERSION_RB_PROT)?"Enabled":"Disabled"));
printf("\tI2C Deglitch Range : %s\n",
((_feabits & FEA_I2C_DG_RANGE_SEL)?"(1) 16 to 50 ns":"(0) 8 to 25 ns"));
int boot_mode = (_feabits >> 12) & 0x07;
printf("\tBoot Mode : ");
if ((_feabits & FEA_MSPI_PERSIST) == 0) {
if (boot_mode == 0)
printf("Dual Boot, CFG0 - CFG1\n");
else if (boot_mode == 1)
printf("Dual Boot, CFG1 - CFG0\n");
else if (boot_mode == 3)
printf("Single Boot, CFG0\n");
else if (boot_mode == 4)
printf("Single Boot, CFG1\n");
else if (boot_mode == 5)
printf("Dual Boot, Boot from former bitstream first\n");
else if (boot_mode == 7)
printf("Dual Boot, Boot from latter bitstream first\n");
else if ((boot_mode & 0x03) == 2)
printf("Dual Boot, No Boot\n");
else
printf("Unknown boot sequence selection");
}
else {
if (boot_mode == 0)
printf("Dual Boot, CFG0 - Ext\n");
else if ((boot_mode & 0x03) == 1)
printf("Single Boot, Ext\n");
else if (boot_mode == 2)
printf("Dual Boot, Ext - CFG0\n");
else if ((boot_mode & 0x03) == 3)
printf("Dual Boot, Ext - Ext\n");
else if (boot_mode == 4)
printf("Dual Boot, CFG1 - Ext\n");
else if (boot_mode == 6)
printf("Dual Boot, Ext - CFG1\n");
else
printf("Unknown boot sequence selection");
}
printf("\tMSPI Enable : %s\n",
((_feabits & FEA_MSPI_PERSIST)?"Yes":"No"));
printf("\tI2C Disable : %s\n",
((_feabits & FEA_I2C_PERSIST)?"Yes":"No"));
printf("\tSSPI Disable : %s\n",
((_feabits & FEA_SSPI_PERSIST)?"Yes":"No"));
printf("\tJTAG Disable : %s\n",
((_feabits & FEA_JTAG_PERSIST)?"Yes":"No"));
printf("\tDONE Enable : %s\n",
((_feabits & FEA_DONE_PERSIST)?"Yes":"No"));
printf("\tINIT Enable : %s\n",
((_feabits & FEA_INITN_PERSIST)?"Yes":"No"));
printf("\tPROGRAM Disable : %s\n",
((_feabits & FEA_PROG_PERSIST)?"Yes":"No"));
printf("\tCustom ID Enable : %s\n",
((_feabits & FEA_MY_ASSP_EN)?"Yes":"No"));
int flash_prot = (_feabits >> 1) & 0x07;
printf("\tFlash Protection : ");
if (flash_prot == 0) {
printf("None\n");
}
else {
if (flash_prot & 0x04)
printf("CFG0 & CFG1 ");
if (flash_prot & 0x02)
printf("Feature, Security Keys ");
if (flash_prot & 0x01)
printf("All UFMs");
printf("\n");
}
printf("\tI2C Deglitch Filter : %s\n",
((_feabits & FEA_I2C_DG_FIL_EN)?"Enabled":"Disabled"));
}
}
/* Features Row & Feabits - this data is in a separate .fea file (MachXO3D)
* DATA:
* 1: xxxx\n : feature Row (96 bits)
* 2: yyyy*\n : feabits (32 bits)
*/
void FeaParser::parseFeatureRowAndFeabits(const vector<string> &content)
{
printf("Parsing Feature Row & FEAbits...\n");
string featuresRow = content[0];
//printf("Features: [%s]\n", featuresRow.c_str());
for (size_t i = 0; i < featuresRow.size(); i++)
_featuresRow[3 - (i/32) - 1] |= ((featuresRow[i] - '0') << (32 - (i%32) - 1));
string feabits = content[1];
//printf("Feabits: [%s]\n", feabits.c_str());
_feabits = 0;
for (size_t i = 0; i < feabits.size(); i++) {
_feabits |= ((feabits[i] - '0') << (feabits.size() - i - 1));
}
}
int FeaParser::parse()
{
_ss.str(_raw_data);
std::vector<string>lines;
int first_pos;
char instr;
lines = readFeaFile();
/* empty or end of file */
if (lines.size() > 0) {
parseFeatureRowAndFeabits(lines);
_has_feabits = true;
}
return EXIT_SUCCESS;
}