Commit 9ef6c528 authored by Leon Hiemstra's avatar Leon Hiemstra

CCFG to MMAP, implemented FIFOs

parent 0d81340a
......@@ -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};
......
......@@ -48,12 +48,12 @@ class CMD {
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 RELOAD="reload";
const std::string HELP = "help";
const std::string QUIT = "quit";
const std::string INFO = "list";
const std::string MMREAD = "read";
const std::string MMWRITE = "write";
const std::string RELOAD = "reload";
std::vector<std::string> supported_cmds;
......@@ -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)
......
This diff is collapsed.
/*
* 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()) {