Skip to content
Snippets Groups Projects
Commit 9ef6c528 authored by Kenneth Hiemstra's avatar Kenneth Hiemstra
Browse files

CCFG to MMAP, implemented FIFOs

parent 0d81340a
Branches
Tags
No related merge requests found
......@@ -87,10 +87,10 @@ CMDstatus CMD::command(string line, TermOutput& termout, string& cmdname, Server
*/
if(cmd == INFO) {
req_ret = Info(argc,argv,termout,sd);
} else if(cmd == MREAD) {
req_ret = Mread(argc,argv,termout,sd);
} else if(cmd == MWRITE) {
req_ret = Mwrite(argc,argv,termout,sd);
} else if(cmd == MMREAD) {
req_ret = MMread(argc,argv,termout,sd);
} else if(cmd == MMWRITE) {
req_ret = MMwrite(argc,argv,termout,sd);
} else if(cmd == RELOAD) {
req_ret = Reload(argc,argv,termout,sd);
/*
......@@ -156,7 +156,7 @@ CMDstatus CMD::Info(int argc, char* argv[], TermOutput& termout, Serverdat *sd)
if (vm.count("help")) {
termout.strout << "Usage: " << INFO << " [options] /unb..." << endl
<< "Options: " << generic << endl
<< "Example: ls /unb0/pn3" << endl;
<< "Example: list /unb0/pn3" << endl;
return {CMD_STATUS_OK,0,0};
}
if (vm.count("version")) {
......@@ -188,7 +188,7 @@ CMDstatus CMD::Info(int argc, char* argv[], TermOutput& termout, Serverdat *sd)
return ret;
}
CMDstatus CMD::Mread(int argc, char* argv[], TermOutput& termout, Serverdat *sd)
CMDstatus CMD::MMread(int argc, char* argv[], TermOutput& termout, Serverdat *sd)
{
CMDstatus ret = {CMD_STATUS_ERROR,0,0};
......@@ -219,7 +219,7 @@ CMDstatus CMD::Mread(int argc, char* argv[], TermOutput& termout, Serverdat *sd)
po::notify(vm);
if (vm.count("help")) {
termout.strout << "usage: " << MREAD << " [options] file(s)" << endl
termout.strout << "usage: " << MMREAD << " [options] file(s)" << endl
<< "Options: " << generic << endl
<< "Example 1: read --nvalues=1 /unb0/pn3/mm/ppsh/ppsh/status" << endl
<< "Example 2: read /unb[0:10,15]/pn[0:3]/mm/ppsh/ppsh/status" << endl
......@@ -243,7 +243,7 @@ CMDstatus CMD::Mread(int argc, char* argv[], TermOutput& termout, Serverdat *sd)
return ret;
}
CMDstatus CMD::Mwrite(int argc, char* argv[], TermOutput& termout, Serverdat *sd)
CMDstatus CMD::MMwrite(int argc, char* argv[], TermOutput& termout, Serverdat *sd)
{
CMDstatus ret = {CMD_STATUS_ERROR,0,0};
......@@ -274,7 +274,7 @@ CMDstatus CMD::Mwrite(int argc, char* argv[], TermOutput& termout, Serverdat *sd
po::notify(vm);
if (vm.count("help")) {
termout.strout << "usage: " << MWRITE << " [options] file(s)" << endl
termout.strout << "usage: " << MMWRITE << " [options] file(s)" << endl
<< "Options: " << generic << endl
<< "Example: write --offs=1 --data=[1,2,3,4] /unb0/pn3/mm/sens/sens/temp_high" << endl;
return {CMD_STATUS_OK,0,0};
......
......@@ -50,9 +50,9 @@ private:
// (1)
const std::string HELP = "help";
const std::string QUIT = "quit";
const std::string INFO="ls";
const std::string MREAD="read";
const std::string MWRITE="write";
const std::string INFO = "list";
const std::string MMREAD = "read";
const std::string MMWRITE = "write";
const std::string RELOAD = "reload";
......@@ -61,8 +61,8 @@ private:
// (3)
CMDstatus Info(int argc, char* argv[], TermOutput& termout, Serverdat *sd);
CMDstatus Mread(int argc, char* argv[], TermOutput& termout, Serverdat *sd);
CMDstatus Mwrite(int argc, char* argv[], TermOutput& termout, Serverdat *sd);
CMDstatus MMread(int argc, char* argv[], TermOutput& termout, Serverdat *sd);
CMDstatus MMwrite(int argc, char* argv[], TermOutput& termout, Serverdat *sd);
CMDstatus Reload(int argc, char* argv[], TermOutput& termout, Serverdat *sd);
public:
......@@ -71,8 +71,8 @@ private:
supported_cmds.push_back(HELP);
supported_cmds.push_back(QUIT);
supported_cmds.push_back(INFO);
supported_cmds.push_back(MREAD);
supported_cmds.push_back(MWRITE);
supported_cmds.push_back(MMREAD);
supported_cmds.push_back(MMWRITE);
supported_cmds.push_back(RELOAD);
}
......
......@@ -130,7 +130,9 @@ bool UNBos::Read(const uint32_t opcode, const uint32_t addr, const uint nvalues,
nreceived += _nvalues;
}
if(retries) cerr << "UNBos::Read() retries=" << retries << endl;
if(retries) {
cerr << "UNBos::Read() retries=" << retries << (retstat==0 ? " (recovered)" : " (failed)") << endl;
}
if(retstat==0) return true; else return false;
}
......@@ -208,7 +210,9 @@ bool UNBos::Write(const uint32_t opcode, const uint32_t addr, const uint nvalues
nsent += _nvalues;
}
if(retries) cerr << "UNBos::Write() retries=" << retries << endl;
if(retries) {
cerr << "UNBos::Write() retries=" << retries << (retstat==0 ? " (recovered)" : " (failed)") << endl;
}
if(retstat==0) return true; else return false;
}
......@@ -248,15 +252,29 @@ void UNBos::print_reply_packet(const uint8_t *pkt, const int len)
printf("\n");
}
bool UNBos::readRegister(uint32_t addr, uint32_t nvalues, uint32_t *data_ptr)
bool UNBos::readRegister(uint32_t addr, uint32_t nvalues, uint32_t *data_ptr, const bool isfifo)
{
uint32_t opcode;
if(data_ptr==NULL) throw runtime_error("UNBos::readRegister data_ptr=NULL");
return Read(UNBOS_OPCODE_MEMORY_READ, addr, nvalues, data_ptr);
if(isfifo) {
opcode = UNBOS_OPCODE_FIFO_READ;
} else {
opcode = UNBOS_OPCODE_MEMORY_READ;
}
return Read(opcode, addr, nvalues, data_ptr);
}
bool UNBos::writeRegister(uint32_t addr, uint32_t nvalues, const uint32_t *data_ptr)
bool UNBos::writeRegister(uint32_t addr, uint32_t nvalues, const uint32_t *data_ptr, const bool isfifo)
{
uint32_t opcode;
if(data_ptr==NULL) throw runtime_error("UNBos::writeRegister data_ptr=NULL");
return Write(UNBOS_OPCODE_MEMORY_WRITE, addr, nvalues, data_ptr);
if(isfifo) {
opcode = UNBOS_OPCODE_FIFO_WRITE;
cout << "UNBOS fifo write" << endl;
} else {
opcode = UNBOS_OPCODE_MEMORY_WRITE;
}
return Write(opcode, addr, nvalues, data_ptr);
}
......@@ -109,7 +109,7 @@ class UNBos
protected:
uint32_t seq_nr;
udpsocket *commdev;
int leon;
public:
int count;
......@@ -133,8 +133,8 @@ protected:
public:
bool Write(const uint32_t opcode, const uint32_t addr, const uint nvalues, const uint32_t *buf);
bool Read(const uint32_t opcode, const uint32_t addr, const uint nvalues, uint32_t *buf);
bool writeRegister(uint32_t addr, uint32_t nvalues, const uint32_t *data_ptr);
bool readRegister(uint32_t addr, uint32_t nvalues, uint32_t *data_ptr);
bool writeRegister(uint32_t addr, uint32_t nvalues, const uint32_t *data_ptr, const bool isfifo=false);
bool readRegister(uint32_t addr, uint32_t nvalues, uint32_t *data_ptr, const bool isfifo=false);
};
#endif
......@@ -32,7 +32,7 @@
#include <arpa/inet.h>
#include "system.h"
#include "../tools/ccfg.h"
#include "../tools/mmap.h"
using namespace std;
......@@ -49,12 +49,12 @@ Periph_system::Periph_system(UNBos &commdev,
registerMap = new RegisterMap(read_reg_map());
// Add composite registers:
registerMap->add_register("dev/system", 0, 0, 0xffffffff, 0, "RO");
registerMap->add_register("dev/name", 0, 0, 0xffffffff, 0, "RO");
registerMap->add_register("dev/stamps", 0, 0, 0xffffffff, 0, "RO");
registerMap->add_register("dev/note", 0, 0, 0xffffffff, 0, "RO");
registerMap->add_register("dev/sensors", 0, 0, 0xffffffff, 0, "RO");
registerMap->add_register("dev/status", 0, 0, 0xffffffff, 0, "RO");
registerMap->add_register("dev/system", 0, 0, 0xffffffff, 0, "RO", "COMP");
registerMap->add_register("dev/name", 0, 0, 0xffffffff, 0, "RO", "COMP");
registerMap->add_register("dev/stamps", 0, 0, 0xffffffff, 0, "RO", "COMP");
registerMap->add_register("dev/note", 0, 0, 0xffffffff, 0, "RO", "COMP");
registerMap->add_register("dev/sensors", 0, 0, 0xffffffff, 0, "RO", "COMP");
registerMap->add_register("dev/status", 0, 0, 0xffffffff, 0, "RO", "COMP");
try {
std::string design_name = read_design_name();
......@@ -63,7 +63,8 @@ Periph_system::Periph_system(UNBos &commdev,
}
}
bool Periph_system::Read(const string addr_str, const uint32_t offset, const uint32_t nvalues, uint32_t *data_ptr)
bool Periph_system::Read(const string addr_str, const uint32_t offset, const uint32_t nvalues,
uint32_t *data_ptr)
{
bool ret;
uint32_t addr = registerMap->getValidAddr(addr_str,offset,nvalues);
......@@ -71,8 +72,9 @@ bool Periph_system::Read(const string addr_str, const uint32_t offset, const uin
uint32_t mask = registerMap->getMask(addr_str);
uint32_t shift = registerMap->getShift(addr_str);
bool isfifo = registerMap->type_isfifo(addr_str);
ret = unbos.readRegister(addr,nvalues,data_ptr);
ret = unbos.readRegister(addr,nvalues,data_ptr,isfifo);
if(ret && (shift != 0 || mask != 0xffffffff)) {
for(uint32_t i=0; i < nvalues; i++) {
data_ptr[i] &= mask;
......@@ -82,13 +84,15 @@ bool Periph_system::Read(const string addr_str, const uint32_t offset, const uin
return ret;
}
bool Periph_system::Write(const string addr_str, const uint32_t offset, const uint32_t nvalues, uint32_t *data_ptr)
bool Periph_system::Write(const string addr_str, const uint32_t offset, const uint32_t nvalues,
uint32_t *data_ptr)
{
uint32_t addr = registerMap->getValidAddr(addr_str,offset,nvalues);
registerMap->getWritePermission(addr_str);
uint32_t shift = registerMap->getShift(addr_str);
uint32_t mask = registerMap->getMask(addr_str);
bool isfifo = registerMap->type_isfifo(addr_str);
if(shift != 0 || mask != 0xffffffff) {
for(uint32_t i=0; i<nvalues; i++) {
......@@ -96,7 +100,7 @@ bool Periph_system::Write(const string addr_str, const uint32_t offset, const ui
data_ptr[i] &= mask;
}
}
return unbos.writeRegister(addr,nvalues,data_ptr);
return unbos.writeRegister(addr,nvalues,data_ptr,isfifo);
}
bool Periph_system::read_unb_status(ostringstream& strs)
......@@ -124,7 +128,7 @@ bool Periph_system::read_unb_status(ostringstream& strs)
bool Periph_system::read_system_info(ostringstream& strs)
{
uint32_t data;
bool retval = Read("mm/system/info/info",0,1,&data);
bool retval = Read("mm/unb2b/system/info",0,1,&data);
std::string design_name = read_design_name();
strs << "design_name=" << design_name << ", ";
......@@ -148,8 +152,8 @@ bool Periph_system::read_system_info(ostringstream& strs)
design_name.c_str(), firmware_version,
my_expected_design_name.c_str(), my_expected_firmware_version);
my_current_status = "offline";
registerMap->setAllPermission_NA();
//my_current_status = "offline";
//registerMap->setAllPermission_NA();
}
return retval;
}
......@@ -188,7 +192,7 @@ string Periph_system::read_design_name(void)
uint32_t nof_design_name_regs = 4;
uint32_t nvalues = nof_design_name_regs;
uint32_t *data = new uint32_t[nvalues * sizeof(uint32_t)+1];
bool retval = Read("mm/system/info/info", 2, nvalues, data);
bool retval = Read("mm/unb2b/system/info", 2, nvalues, data);
char *str_ptr = (char *)data;
string name = string(str_ptr);
delete[] data;
......@@ -200,7 +204,7 @@ string Periph_system::read_design_note(void)
uint32_t nof_design_name_regs = 4;
uint32_t nvalues = nof_design_name_regs;
uint32_t *data = new uint32_t[nvalues * sizeof(uint32_t)+1];
bool retval = Read("mm/system/info/info", 20, nvalues,data);
bool retval = Read("mm/unb2b/system/info", 20, nvalues,data);
data[nvalues] = 0; // add end of string char
char *str_ptr = (char *)data;
string note = string(str_ptr);
......@@ -213,7 +217,7 @@ bool Periph_system::read_stamps(ostringstream& strs)
uint32_t nof_regs = 3;
uint32_t nvalues = nof_regs;
uint32_t *data = new uint32_t[nvalues * sizeof(uint32_t)+1];
bool retval = Read("mm/system/info/info", 15, nvalues, data);
bool retval = Read("mm/unb2b/system/info", 15, nvalues, data);
strs << " Stamp: date=" << data[0] << endl;
strs << " Stamp: time=" << data[1] << endl;
......@@ -228,7 +232,7 @@ bool Periph_system::read_unb_sensors(ostringstream& strs, const uint nodeNr)
uint32_t nvalues = 1;
uint32_t *data = new uint32_t[nvalues * sizeof(uint32_t)];
retval = Read("mm/sens/sens/sens_data0", 0, nvalues, data);
retval = Read("mm/unb2b/fpga/temp", 0, nvalues, data);
char str[1000];
sprintf(str," FPGA temperature = %d [degC]\n", data[0]); strs << str;
......@@ -242,29 +246,13 @@ bool Periph_system::read_unb_sensor(uint32_t *sensor, const uint nodeNr)
uint32_t nvalues = 1;
uint32_t *data = new uint32_t[nvalues * sizeof(uint32_t)];
retval = Read("mm/sens/sens/sens_data0", 0, nvalues, data);
retval = Read("mm/unb2b/fpga/temp", 0, nvalues, data);
*sensor = data[0];
delete[] data;
return retval;
}
bool Periph_system::read_temp_high(ostringstream& strs)
{
bool retval = false;
uint32_t data;
retval = Read("mm/sens/sens/temp_high", 5, 1, &data);
strs << " High temp limit = " << data << " [degC]" << endl;
return retval;
}
bool Periph_system::write_temp_high(ostringstream& strs, const int val)
{
if(val < 10) throw runtime_error("bad high temp value");
uint32_t data = val;
return Write("mm/sens/sens/temp_high", 5, 1, &data);
}
bool Periph_system::write_wdi_override(ostringstream& strs)
{
uint32_t data = 0xB007FAC7;
......@@ -301,9 +289,7 @@ RegisterMap Periph_system::read_reg_map(void)
cout << "Periph_system::read_reg_map:\n" << reg_map_str << endl;
delete[] data;
istringstream iss_regmap_step1(reg_map_str);
istringstream iss_regmap_step2(reg_map_str);
reg = ccfg_to_regmap(iss_regmap_step1);
return ccfg_upe_to_regmap_add(iss_regmap_step2, reg);
istringstream iss_regmap(reg_map_str);
return mmap_to_regmap(iss_regmap);
}
......@@ -34,8 +34,10 @@ private:
uint my_expected_firmware_version;
std::string my_current_status;
bool Read(const string addr_str, const uint32_t offset, const uint32_t nvalues, uint32_t *data_ptr);
bool Write(const string addr_str, const uint32_t offset, const uint32_t nvalues, uint32_t *data_ptr);
bool Read(const string addr_str, const uint32_t offset, const uint32_t nvalues,
uint32_t *data_ptr);
bool Write(const string addr_str, const uint32_t offset, const uint32_t nvalues,
uint32_t *data_ptr);
public:
Periph_system(UNBos &unbos, const string expected_design_name, const uint expected_firmware_version);
......@@ -52,8 +54,6 @@ public:
bool read_stamps(ostringstream& strs);
bool read_unb_sensor(uint32_t *sensor, const uint nodeNr);
bool read_unb_sensors(ostringstream& strs, const uint nodeId);
bool read_temp_high(ostringstream& strs);
bool write_temp_high(ostringstream& strs, const int val);
bool write_wdi_override(ostringstream& strs);
RegisterMap read_reg_map(void);
RegisterMap * getRegisterMap(void) { return registerMap; };
......
......@@ -24,13 +24,48 @@
using namespace std;
void RegisterMap::add_register(const std::string name, const uint32_t base,
bool RegisterMap::add_register(const std::string name, const uint32_t base,
const uint32_t span, const uint32_t mask,
const uint32_t shift, const std::string access)
const uint32_t shift, const std::string access,
const std::string type)
{
cout << "RegisterMap::add_register: " << name << endl;
register_info r={base, span, mask, shift, access};
if(find_register(name)) {
cerr << "RegisterMap::add_register: " << name << " already exist!" << endl;
return false;
}
register_info r={base, span, mask, shift, access, type};
reg.insert(reg.end(), std::pair<std::string, register_info>(name, r));
return true;
}
bool RegisterMap::update_register(const std::string name, const uint32_t base,
const uint32_t span, const uint32_t mask,
const uint32_t shift, const std::string access,
const std::string type)
{
cout << "RegisterMap::update_register: " << name << endl;
if(!find_register(name)) {
cerr << "RegisterMap::update_register: " << name << " not exist!" << endl;
return false;
}
reg[name].type = type;
reg[name].access = access;
reg[name].shift = shift;
reg[name].mask = mask;
reg[name].span = span;
reg[name].base = base;
return true;
}
bool RegisterMap::find_register(std::string name)
{
bool ret=false;
auto i = reg.find(name);
if (i != reg.end()) {
ret = true;
}
return ret;
}
void RegisterMap::print(ostringstream& strs, std::string prefix)
......@@ -41,7 +76,8 @@ void RegisterMap::print(ostringstream& strs, std::string prefix)
<< dec << m.second.span << " mask=0x"
<< hex << m.second.mask << " shift="
<< dec << m.second.shift << " access="
<< m.second.access << endl;
<< m.second.access << " type="
<< m.second.type << endl;
}
}
......@@ -53,10 +89,12 @@ void RegisterMap::print_screen(void)
<< dec << m.second.span << " mask=0x"
<< hex << m.second.mask << " shift="
<< dec << m.second.shift << " access="
<< m.second.access << endl;
<< m.second.access << " type="
<< m.second.type << endl;
}
}
std::vector<std::string> RegisterMap::getRegnames(std::string prefix)
{
std::vector<std::string> regnames;
......@@ -75,6 +113,7 @@ std::vector<std::string> RegisterMap::getRegnames_full(std::string prefix)
ss.str("");
ss.clear();
ss << m.second.access << " "
<< std::setw(4) << m.second.type << " "
<< "0x" << std::setfill('0') << std::hex << std::setw(8) << m.second.base << " "
<< std::setfill(' ') << std::dec << std::setw(4) << m.second.span << " "
<< prefix << m.first;
......@@ -85,14 +124,19 @@ std::vector<std::string> RegisterMap::getRegnames_full(std::string prefix)
}
uint32_t RegisterMap::getValidAddr(const std::string name, const uint32_t offset, const uint32_t size)
uint32_t RegisterMap::getValidAddr(const std::string name, const uint32_t offset,
const uint32_t size)
{
if(!find_register(name)) {
throw runtime_error("Register["+name+"] not existing!");
}
uint32_t _offset = offset * sizeof(uint32_t);
uint32_t end = (size + offset);// * sizeof(uint32_t);
uint32_t base = getBaseAddr(name);
uint32_t span = getSpan(name);
if(end > span) {
if(end > span && !type_isfifo(name)) {
throw runtime_error("Register["+name+"] getValidAddr() out of range!");
}
uint32_t addr = base + _offset;
......
......@@ -36,6 +36,7 @@ class RegisterMap {
uint32_t mask;
uint32_t shift;
std::string access;
std::string type;
} register_info;
std::map <std::string, register_info> reg;
......@@ -45,8 +46,13 @@ class RegisterMap {
};
~RegisterMap() {};
void add_register(const std::string name, const uint32_t base, const uint32_t span,
const uint32_t mask, const uint32_t shift, const std::string access);
bool add_register(const std::string name, const uint32_t base, const uint32_t span,
const uint32_t mask, const uint32_t shift, const std::string access,
const std::string type);
bool update_register(const std::string name, const uint32_t base, const uint32_t span,
const uint32_t mask, const uint32_t shift, const std::string access,
const std::string type);
bool find_register(std::string name);
void print(std::ostringstream& strs, std::string prefix);
void print_screen(void);
uint32_t getBaseAddr(const std::string name) { return reg[name].base; }
......@@ -54,7 +60,10 @@ class RegisterMap {
std::string getPerm(const std::string name) { return reg[name].access; }
uint32_t getMask(const std::string name) { return reg[name].mask; }
uint32_t getShift(const std::string name) { return reg[name].shift; }
uint32_t getValidAddr(const std::string name, const uint32_t offset, const uint32_t size);
std::string getType(const std::string name) { return reg[name].type; }
bool type_isfifo(const std::string name) { return (reg[name].type == "FIFO"); }
uint32_t getValidAddr(const std::string name, const uint32_t offset,
const uint32_t size);
bool getReadPermission(const std::string name);
bool getWritePermission(const std::string name);
void setPermission_NA(const std::string name) { reg[name].access = "NA"; }
......
......@@ -73,32 +73,25 @@ void monitor(void)
CMDstatus cmdstatus = {CMD_STATUS_OK, 0,0};
CMDstatus cmdstatusnew = cmdstatus;
TermOutput termout;
#define c_NOF_RETRIES_MONITOR 3
int retries = c_NOF_RETRIES_MONITOR;
// while(ServerRunning) {
// usleep(1000000);
// }
while(ServerRunning) {
usleep(1000000);
}
while(ServerRunning) {
usleep(1000000);
while(!SD.monitor_mutex.try_lock()) { cerr << "mutex not ready\n"; usleep(100000); }
if(!SD.unb->monitor(termout)) {
retries--;
cerr << "Retrying " << retries << endl;
} else {
retries = c_NOF_RETRIES_MONITOR;
}
SD.unb->monitor(termout);
SD.monitor_mutex.unlock();
if(cmdstatusnew.status != CMD_EMPTY) cmdstatus = cmdstatusnew;
cout << "Monitor thread: " << print_termout(termout) << endl;
termout.clear();
if(retries <= 0) {
//if(retries <= 0) {
//cerr << "Re-initializing, Read register maps again!" << endl;
//raise(SIGHUP)
}
//}
}
}
......
......@@ -11,7 +11,7 @@ AM_CXXFLAGS = -std=c++11 -pedantic -Wall -Woverloaded-virtual -Wwrite-strings -D
#
############################################################################
tools_SOURCES = parse.cpp parse.h util.cpp util.h ccfg.cpp ccfg.h
tools_SOURCES = parse.cpp parse.h util.cpp util.h mmap.cpp mmap.h
# the sources to add to the library and to add to the source distribution
libtools_a_SOURCES = $(tools_SOURCES)
......
/*
* Copyright 2020 Stichting Nederlandse Wetenschappelijk Onderzoek Instituten,
* ASTRON Netherlands Institute for Radio Astronomy
* Licensed under the Apache License, Version 2.0 (the "License");
*
* you may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* See ../../LICENSE.txt for more info.
*/
#include <iostream>
#include <sstream>
#include <iomanip>
#include <istream>
#include <fstream>
#include <string>
#include <strings.h>
#include <boost/numeric/ublas/io.hpp>
#include <boost/array.hpp>
#include <boost/regex.hpp>
#include "ccfg.h"
using namespace std;
using namespace boost::numeric::ublas;
RegisterMap ccfg_to_regmap(std::istringstream& iss)
{
RegisterMap regmap;
ostringstream err_str;
// DistrRAM 0x00000000 len=32 RO system info info
#define RE_CCFG_LINE_DistrRAM "^\\s*DistrRAM\\s+0x\\S+\\s+len=\\d+\\s+[R,W][O,W]\\s+\\S+\\s+\\S+\\s+.*$"
//#define RE_CCFG_LINE_DistrRAM "^\\s*DistrRAM\\s+.*$"
// BitField 0x000000E0 b[31:0] WO ctrl pio_wdi nios_reset
#define RE_CCFG_LINE_BitField "^\\s*BitField\\s+0x\\S+\\s+b\\[\\d+:\\d+\\]\\s+[R,W][O,W]\\s+\\S+\\s+\\S+\\s+.*$"
//#define RE_CCFG_LINE_BitField "^\\s*BitField\\s+.*$"
// BlockRAM 0x00001000 len=1024 RW eth1g eth data
#define RE_CCFG_LINE_BlockRAM "^\\s*BlockRAM\\s+0x\\S+\\s+len=\\d+\\s+[R,W][O,W]\\s+\\S+\\s+\\S+\\s+.*$"
//#define RE_CCFG_LINE_BlockRAM "^\\s*BlockRAM\\s+.*$"
boost::regex comment_re, spaces_re, DistrRAM_re, BitField_re, BlockRAM_re;
boost::cmatch matches;
comment_re = string("^\\s*#+.*$");
spaces_re = string("^\\s*$");
DistrRAM_re = string(RE_CCFG_LINE_DistrRAM);
BitField_re = string(RE_CCFG_LINE_BitField);
BlockRAM_re = string(RE_CCFG_LINE_BlockRAM);
char line[250];
while(iss.getline(line, sizeof(line))) {
if (regex_match(line, comment_re)) {
//cout << "import_ccfg_file match: comment ok" << endl;
} else if (regex_match(line, spaces_re)) {
//cout << "import_ccfg_file match: spaces ok" << endl;
} else if (regex_match(line, DistrRAM_re)) {
//cout << "import_ccfg_file match: DistrRAM ok" << endl;
stringstream ss(line);
string prefx, perm, peripheral, regname, regfield;
uint base, span;
char c;
// DistrRAM 0x00000000 len=32 RO system info info
ss >> prefx;
ss >> hex >> base; // in dword addresses
//base *= 4; // to byte addresses
ss >> c; // 'l'
ss >> c; // 'e'
ss >> c; // 'n'
ss >> c; // '='
ss >> dec >> span; // in dwords
//span *= 4; // to bytes
ss >> perm;
ss >> peripheral;
ss >> regname;
ss >> regfield;
if (ss.fail() || ss.bad()) {
cerr << "import_ccfg_file: invalid DistrRAM" << endl;
} else {
regmap.add_register("mm/"+peripheral+"/"+regname+"/"+regfield,base,span,0xffffffff,0,perm);
}
} else if (regex_match(line, BitField_re)) {
//cout << "import_ccfg_file match: BitField ok" << endl;
stringstream ss(line);
string prefx, perm, peripheral, regname, regfield;
uint base, span;
uint32_t mask,shift;
char c;
uint mask_to, mask_from;
// BitField 0x000000E0 b[31:0] WO ctrl pio_wdi nios_reset
ss >> prefx;
ss >> hex >> base; // in dword addresses
//base *= 4; // to byte addresses
ss >> c; // 'b'
ss >> c; // '['
ss >> dec >> mask_to;
ss >> c; // ':'
ss >> dec >> mask_from;
ss >> c; // ']'
mask = 0;
for(uint i=mask_from;i<=mask_to;i++) {
mask |= (1<<i);
}
shift = mask_from;
//cout << "mask_to=" << dec << mask_to << " mask_from=" << mask_from << endl;
//cout << " mask=0x" << hex << mask << endl;
span = 1; // in dwords
//span *= 4; // to bytes
ss >> perm;
ss >> peripheral;
ss >> regname;
ss >> regfield;
if (ss.fail() || ss.bad()) {
cerr << "import_ccfg_file: invalid BitField" << endl;
} else {
regmap.add_register("mm/"+peripheral+"/"+regname+"/"+regfield,base,span,mask,shift,perm);
}
} else if (regex_match(line, BlockRAM_re)) {
//cout << "import_ccfg_file match: BlockRAM ok" << endl;
stringstream ss(line);
string prefx, perm, peripheral, regname, regfield;
uint base, span;
char c;
// BlockRAM 0x00001000 len=1024 RW eth1g eth data
ss >> prefx;
ss >> hex >> base; // in dword addresses
//base *= 4; // to byte addresses
ss >> c; // 'l'
ss >> c; // 'e'
ss >> c; // 'n'
ss >> c; // '='
ss >> dec >> span; // in dwords
//span *= 4; // to bytes
ss >> perm;
ss >> peripheral;
ss >> regname;
ss >> regfield;
if (ss.fail() || ss.bad()) {
cerr << "import_ccfg_file: invalid BlockRAM" << endl;
} else {
regmap.add_register("mm/"+peripheral+"/"+regname+"/"+regfield,base,span,0xffffffff,0,perm);
}
} else {
cerr << "import_ccfg_file: error! illegal line: [" << line << "]" << endl;
}
}
cout << "regmap:" << endl;
regmap.print_screen();
return regmap;
}
RegisterMap ccfg_upe_to_regmap_add(std::istringstream& iss, RegisterMap &regmap)
{
ostringstream err_str;
// # peripheral=system start=0x0000 span=0x0080 count=01 idx=0 stop=0x0080
#define RE_CCFG_UPE_LINE_peripheral "^#\\s*peripheral=\\w+\\s+start=0x\\S+\\s+span=0x\\S+\\s+\\S+\\s+\\S+\\s+\\S+$"
// # REG-SLAVE=pio_system_info no.slaves=1 len=1 (base=0x80)
#define RE_CCFG_UPE_LINE_REG_SLAVE "^#\\s*REG-SLAVE=\\w+\\s+no.slaves=\\S+\\s+len=\\S+\\s+\\S+$"
// # RAM-SLAVE=avs_eth_0_ram
#define RE_CCFG_UPE_LINE_RAM_SLAVE "^#\\s*RAM-SLAVE=\\w+\\s+$"
// # FIFO-SLAVE=not_seen_any_yet
#define RE_CCFG_UPE_LINE_FIFO_SLAVE "^#\\s*FIFO-SLAVE=\\w+\\s+$"
boost::regex spaces_re, peripheral_re, REG_SLAVE_re, RAM_SLAVE_re, FIFO_SLAVE_re;
boost::cmatch matches;
spaces_re = string("^\\s*$");
peripheral_re = string(RE_CCFG_UPE_LINE_peripheral);
REG_SLAVE_re = string(RE_CCFG_UPE_LINE_REG_SLAVE);
RAM_SLAVE_re = string(RE_CCFG_UPE_LINE_RAM_SLAVE);
FIFO_SLAVE_re = string(RE_CCFG_UPE_LINE_FIFO_SLAVE);
uint peripheral_addr, peripheral_span, stage = 0;
char line[250];
while(iss.getline(line, sizeof(line))) {
if (regex_match(line, spaces_re)) {
cout << "ccfg_upe_to_regmap_add match: spaces ok" << endl;
} else if (regex_match(line, peripheral_re)) {
cout << "ccfg_upe_to_regmap_add match: RE_CCFG_UPE_LINE_peripheral ok" << endl;
stringstream ss(line);
string prefx;
char c;
// # peripheral=system start=0x0000 span=0x0080 count=01 idx=0 stop=0x0080
ss >> c; // #
ss >> prefx;
ss >> c; // s
ss >> c; // t
ss >> c; // a
ss >> c; // r
ss >> c; // t
ss >> c; // =
ss >> hex >> peripheral_addr; // in dword addresses
ss >> c; // 's'
ss >> c; // 'p'
ss >> c; // 'a'
ss >> c; // 'n'
ss >> c; // '='
ss >> hex >> peripheral_span;
peripheral_span /= 4; // byte to dwords addressing
stage = 1;
if (ss.fail() || ss.bad()) {
cerr << "ccfg_upe_to_regmap_add: invalid peripheral base/span" << endl;
} else {
//regmap.add_register("mm/"+peripheral+"/"+regname+"/"+regfield,base,span,0xffffffff,0,perm);
cout << "ccfg_upe_to_regmap_add: base=0x"
<< hex << peripheral_addr << " span=0x" << hex << peripheral_span << endl;
}
} else if (regex_match(line, REG_SLAVE_re)) {
cout << "ccfg_upe_to_regmap_add match: RE_CCFG_UPE_LINE_REG_SLAVE ok" << endl;
stringstream ss(line);
string peripheral;
char c;
// # REG-SLAVE=pio_system_info no.slaves=1 len=1 (base=0x80)
ss >> c; // #
ss >> c; // R
ss >> c; // E
ss >> c; // G
ss >> c; // -
ss >> c; // S
ss >> c; // L
ss >> c; // A
ss >> c; // V
ss >> c; // E
ss >> c; // =
ss >> peripheral;
if (ss.fail() || ss.bad()) {
cerr << "ccfg_upe_to_regmap_add: invalid peripheral name" << endl;
} else {
transform(peripheral.begin(), peripheral.end(), peripheral.begin(), ::toupper);
cout << "ccfg_upe_to_regmap_add: peripheral=" << peripheral << endl;
if(stage == 1) {
regmap.add_register("mm/"+peripheral,peripheral_addr,peripheral_span,
0xffffffff,0,"RW");
}
}
stage = 0;
} else if (regex_match(line, RAM_SLAVE_re)) {
cout << "ccfg_upe_to_regmap_add match: RE_CCFG_UPE_LINE_RAM_SLAVE ok" << endl;
stringstream ss(line);
string peripheral;
char c;
// # RAM-SLAVE=avs_eth_0_ram
ss >> c; // #
ss >> c; // R
ss >> c; // A
ss >> c; // M
ss >> c; // -
ss >> c; // S
ss >> c; // L
ss >> c; // A
ss >> c; // V
ss >> c; // E
ss >> c; // =
ss >> peripheral;
if (ss.fail() || ss.bad()) {
cerr << "ccfg_upe_to_regmap_add: invalid peripheral name" << endl;
} else {
transform(peripheral.begin(), peripheral.end(), peripheral.begin(), ::toupper);
cout << "ccfg_upe_to_regmap_add: peripheral=" << peripheral << endl;
if(stage == 1) {
regmap.add_register("mm/"+peripheral,peripheral_addr,peripheral_span,
0xffffffff,0,"RW");
}
}
stage = 0;
} else if (regex_match(line, FIFO_SLAVE_re)) {
cout << "ccfg_upe_to_regmap_add match: RE_CCFG_UPE_LINE_FIFO_SLAVE ok" << endl;
stringstream ss(line);
string peripheral;
char c;
// # FIFO-SLAVE=not_seen_any_yet
ss >> c; // #
ss >> c; // F
ss >> c; // I
ss >> c; // F
ss >> c; // O
ss >> c; // -
ss >> c; // S
ss >> c; // L
ss >> c; // A
ss >> c; // V
ss >> c; // E
ss >> c; // =
ss >> peripheral;
if (ss.fail() || ss.bad()) {
cerr << "ccfg_upe_to_regmap_add: invalid peripheral name" << endl;
} else {
transform(peripheral.begin(), peripheral.end(), peripheral.begin(), ::toupper);
cout << "ccfg_upe_to_regmap_add: peripheral=" << peripheral << endl;
if(stage == 1) {
regmap.add_register("mm/"+peripheral,peripheral_addr,peripheral_span,
0xffffffff,0,"RW");
}
}
stage = 0;
} else {
cerr << "ccfg_upe_to_regmap_add: error! illegal line: [" << line << "]" << endl;
}
}
cout << "regmap:" << endl;
regmap.print_screen();
return regmap;
}
/*
* Some help on REGEX's
*
*
Symbol Meaning
c Match the literal character c once, unless it is one of the special characters.
^ Match the beginning of a line.
. Match any character that isn't a newline.
$ Match the end of a line.
| Logical OR between expressions.
() Group subexpressions.
[] Define a character class.
* Match the preceding expression zero or more times.
+ Match the preceding expression one ore more times.
? Match the preceding expression zero or one time.
{n} Match the preceding expression n times.
{n,} Match the preceding expression at least n times.
{n, m} Match the preceding expression at least n times and at most m times.
\d Match a digit.
\D Match a character that is not a digit.
\w Match an alpha character, including the underscore.
\W Match a character that is not an alpha character.
\s Match a whitespace character (any of \t, \n, \r, or \f).
\S Match a non-whitespace character.
\t Tab.
\n Newline.
\r Carriage return.
\f Form feed.
\m Escape m, where m is one of the metacharacters described above: ^, ., $, |, (), [], *, +, ?, \, or /.
*/
/*
* Copyright 2020 Stichting Nederlandse Wetenschappelijk Onderzoek Instituten,
* ASTRON Netherlands Institute for Radio Astronomy
* Licensed under the Apache License, Version 2.0 (the "License");
*
* you may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* See ../../LICENSE.txt for more info.
*/
#include <iostream>
#include <sstream>
#include <iomanip>
#include <istream>
#include <fstream>
#include <string>
#include <strings.h>
#include <boost/numeric/ublas/io.hpp>
#include <boost/array.hpp>
#include <boost/regex.hpp>
#include "mmap.h"
using namespace std;
using namespace boost::numeric::ublas;
void mmap_add_register(RegisterMap& regmap,
std::string qsysname, std::string fullname,
uint base, uint span, uint32_t mask, uint32_t shift,
std::string perm, std::string type)
{
// add full name register
regmap.add_register(fullname, base, span, mask, shift, perm, type);
// add qsys name register
if(!regmap.find_register(qsysname)) {
regmap.add_register(qsysname, base, span, mask, shift, perm, type);
} else {
uint update_base, update_span;
update_base = regmap.getBaseAddr(qsysname);
update_span = regmap.getSpan(qsysname);
update_span += span;
if(update_base < base) {
// already have a base which is lower
regmap.update_register(qsysname, update_base, update_span, 0xffffffff, 0, "RW", type);
} else {
// this will be the new base which is lower
regmap.update_register(qsysname, base, update_span, 0xffffffff, 0, "RW", type);
}
}
}
RegisterMap mmap_to_regmap(std::istringstream& iss)
{
RegisterMap regmap;
ostringstream err_str;
// unb2b rom_system info REG 0x00000000000 8192 RO b[31:0] PIO_SYSTEM_INFO
#define RE_MMAP_LINE_REG "^\\s*\\w+\\s+\\w+\\s+\\w+\\s+REG\\s+0x\\S+\\s+\\d+\\s+[R,W][O,W]\\s+b\\[\\d+:\\d+\\]\\s+\\w+\\s+.*$"
// eth1g eth data RAM 0x00000000800 1024 RW - AVS_ETH_0_RAM
#define RE_MMAP_LINE_RAM "^\\s*\\w+\\s+\\w+\\s+\\w+\\s+RAM\\s+0x\\S+\\s+\\d+\\s+[R,W][O,W]\\s+-\\s+\\w+\\s+.*$"
// epcs dpmm_data data FIFO 0x000000000e8 1 RO - REG_DPMM_DATA
#define RE_MMAP_LINE_FIFO "^\\s*\\w+\\s+\\w+\\s+\\w+\\s+FIFO\\s+0x\\S+\\s+\\d+\\s+[R,W][O,W]\\s+-\\s+\\w+\\s+.*$"
boost::regex comment_re, spaces_re, REG_re, RAM_re, FIFO_re;
boost::cmatch matches;
comment_re = string("^\\s*#+.*$");
spaces_re = string("^\\s*$");
REG_re = string(RE_MMAP_LINE_REG);
RAM_re = string(RE_MMAP_LINE_RAM);
FIFO_re = string(RE_MMAP_LINE_FIFO);
char line[250];
while(iss.getline(line, sizeof(line))) {
if (regex_match(line, comment_re)) {
//cout << "import_mmap_file match: comment ok" << endl;
} else if (regex_match(line, spaces_re)) {
//cout << "import_mmap_file match: spaces ok" << endl;
} else if (regex_match(line, REG_re)) {
cout << "import_mmap_file match: REG ok" << endl;
stringstream ss(line);
string type, perm, peripheral, regname, regfield, qsysname;
unsigned long long base44;
uint base, span;
uint32_t mask,shift;
uint mask_to, mask_from;
char c;
ss >> peripheral;
ss >> regname;
ss >> regfield;
ss >> type;
ss >> hex >> base44; // in dword addresses
base = (uint)base44;
ss >> dec >> span; // in dwords
ss >> perm;
ss >> c; // 'b'
ss >> c; // '['
ss >> dec >> mask_to;
ss >> c; // ':'
ss >> dec >> mask_from;
ss >> c; // ']'
mask = 0;
for(uint i=mask_from;i<=mask_to;i++) {
mask |= (1<<i);
}
shift = mask_from;
ss >> qsysname;
if (ss.fail() || ss.bad()) {
cerr << "import_mmap_file: invalid REG" << endl;
} else {
mmap_add_register(regmap,"mm/"+qsysname,"mm/"+peripheral+"/"+regname+"/"+regfield,
base,span,mask,shift,perm,type);
}
} else if (regex_match(line, RAM_re)) {
cout << "import_mmap_file match: RAM ok" << endl;
stringstream ss(line);
string type, perm, peripheral, regname, regfield, qsysname;
unsigned long long base44;
uint base, span;
uint32_t mask,shift;
char c;
ss >> peripheral;
ss >> regname;
ss >> regfield;
ss >> type;
ss >> hex >> base44; // in dword addresses
base = (uint)base44;
ss >> dec >> span; // in dwords
ss >> perm;
ss >> c; // '-'
mask = 0xffffffff;
shift = 0;
ss >> qsysname;
if (ss.fail() || ss.bad()) {
cerr << "import_mmap_file: invalid RAM" << endl;
} else {
mmap_add_register(regmap,"mm/"+qsysname,"mm/"+peripheral+"/"+regname+"/"+regfield,
base,span,mask,shift,perm,type);
}
} else if (regex_match(line, FIFO_re)) {
cout << "import_mmap_file match: FIFO ok" << endl;
stringstream ss(line);
string type, perm, peripheral, regname, regfield, qsysname;
unsigned long long base44;
uint base, span;
uint32_t mask,shift;
char c;
ss >> peripheral;
ss >> regname;
ss >> regfield;
ss >> type;
ss >> hex >> base44; // in dword addresses
base = (uint)base44;
ss >> dec >> span; // in dwords
ss >> perm;
ss >> c; // '-'
mask = 0xffffffff;
shift = 0;
ss >> qsysname;
if (ss.fail() || ss.bad()) {
cerr << "import_mmap_file: invalid FIFO" << endl;
} else {
mmap_add_register(regmap,"mm/"+qsysname,"mm/"+peripheral+"/"+regname+"/"+regfield,
base,span,mask,shift,perm,type);
}
} else {
cerr << "import_mmap_file: error! illegal line: [" << line << "]" << endl;
}
}
cout << "regmap:" << endl;
regmap.print_screen();
return regmap;
}
/*
* Some help on REGEX's
*
*
Symbol Meaning
c Match the literal character c once, unless it is one of the special characters.
^ Match the beginning of a line.
. Match any character that isn't a newline.
$ Match the end of a line.
| Logical OR between expressions.
() Group subexpressions.
[] Define a character class.
* Match the preceding expression zero or more times.
+ Match the preceding expression one ore more times.
? Match the preceding expression zero or one time.
{n} Match the preceding expression n times.
{n,} Match the preceding expression at least n times.
{n, m} Match the preceding expression at least n times and at most m times.
\d Match a digit.
\D Match a character that is not a digit.
\w Match an alpha character, including the underscore.
\W Match a character that is not an alpha character.
\s Match a whitespace character (any of \t, \n, \r, or \f).
\S Match a non-whitespace character.
\t Tab.
\n Newline.
\r Carriage return.
\f Form feed.
\m Escape m, where m is one of the metacharacters described above: ^, ., $, |, (), [], *, +, ?, \, or /.
*/
......@@ -14,8 +14,8 @@
* See ../../LICENSE.txt for more info.
*/
#ifndef CCFG_H
#define CCFG_H
#ifndef MMAP_H
#define MMAP_H
#include <stdlib.h>
#include <sys/time.h>
......@@ -33,7 +33,6 @@
namespace ublas = boost::numeric::ublas;
RegisterMap ccfg_to_regmap(std::istringstream& iss);
RegisterMap ccfg_upe_to_regmap_add(std::istringstream& iss, RegisterMap& reg);
RegisterMap mmap_to_regmap(std::istringstream& iss);
#endif
......@@ -3,9 +3,9 @@
# NODE config:
# gn ipaddr expected firmware expected version
node 0 10.99.1.1 unb2b_minimal 2
node 1 10.99.1.2 unb2b_minimal 2
#node 2 10.99.1.3 unb2b_minimal 2
#node 0 10.99.1.1 unb2b_minimal 2
#node 1 10.99.1.2 unb2b_minimal 2
node 2 10.99.1.3 unb2b_minimal 2
#node 3 10.99.1.4 unb2b_minimal 2
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment