added sc_comm_singleton to coordinate interaction with clients (e.g. web

browser)
This commit is contained in:
Eyck Jentzsch 2017-11-10 22:40:24 +01:00
parent 29bd95fb6d
commit eced81b5ea
35 changed files with 953 additions and 467 deletions

View File

@ -6,6 +6,7 @@ SystemCVerification/2.0.0a@minres/stable
[generators] [generators]
cmake cmake
txt
[options] [options]
Poco:shared=True Poco:shared=True

33
html/app.js Normal file
View File

@ -0,0 +1,33 @@
var ws;
$(function() {
ws = new WebSocket('ws://' + document.location.host + '/ws');
ws.onopen = function() {
console.log('onopen');
};
ws.onclose = function() {
$('#message').text('Lost connection.');
console.log('onclose');
};
ws.onmessage = function(message) {
console.log("got '" + message.data + "'");
eval(message.data);
};
ws.onerror = function(error) {
console.log('onerror ' + error);
console.log(error);
};
$('#count').click(function() {
ws.send($('#count').val());
});
$('#close').click(function() {
ws.send('close');
});
$('#die').click(function() {
ws.send('die');
});
});
set = function(value) {
$('#count').val(value)
}

14
html/index.html Normal file
View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Hello, world</title>
<script src='lib/jquery.min.js'></script>
<script src='app.js'></script>
</head>
<body>
<input id="count" type="button" value="..."></input>
<input id="close" type="button" value="Close"></input>
<input id="die" type="button" value="Die"></input>
</body>
</html>

16
html/lib/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

105
html/ws.html Normal file
View File

@ -0,0 +1,105 @@
<!doctype html>
<html lang=en>
<head>
<meta charset=utf-8>
<meta name=viewport content="width=device-width, initial-scale=1">
<title>system output</title>
<style>
h1 { font-family: helvetica, sans-serif; margin: 0; }
h1+p { margin: 0; }
li { font-family: Courier; list-style-type: '>';}
pre { margin-top:0; margin-bottom:0;}
.term { background-color:black; color:white; font-weight:bold;padding-top:10px; padding-bottom:10px; max-height:400px; overflow: scroll;}
span.timestamp { font-family: monospace; white-space: pre;width: 50px;}
span.value_1 { background-color: green;}
span.value_0 { background-color: blue;}
span.value_x { background-color: red;}
</style>
</head>
<body>
<h1>system output</h1>
<div id="top">
</div>
<script>
String.format = function() {
// The string containing the format items (e.g. "{0}")
// will and always has to be the first argument.
var theString = arguments[0];
// start with the second argument (i = 1)
for (var i = 1; i < arguments.length; i++) {
// "gm" = RegEx options for Global search (more than one instance)
// and for Multiline search
var regEx = new RegExp("\\{" + (i - 1) + "\\}", "gm");
theString = theString.replace(regEx, arguments[i]);
}
return theString;
}
String.prototype.paddingLeft = function (paddingValue) {
return String(paddingValue + this).slice(-paddingValue.length);
};
var log = function (n, m) {
console.log(m);
var data = JSON.parse(m);
if( data.hasOwnProperty("message") ) {
var ul = document.getElementById(n);
var li = document.createElement('li');
var p = document.createElement('pre');
// i.innerText = new Date().toISOString()+': '+m;
p.innerText = '['+data.time.paddingLeft(' ')+'] '+ data.message;
li.appendChild(p);
ul.appendChild(li);
var objDiv = document.getElementById(n + '_container');
objDiv.scrollTop = objDiv.scrollHeight;
} else if(data.hasOwnProperty("data")){
var ul = document.getElementById(n);
var li = document.createElement('li');
var span = document.createElement('span');
span.className="timestamp";
span.innerText='['+data.time.paddingLeft(' ')+']'
li.appendChild(span);
var s = data.data;
for ( var i = 0; i < s.length; i++ ){
var spani = document.createElement('span');
if(s.charAt(i) == 'Z')
spani.className="value_z";
else if(s.charAt(i) == '1')
spani.className="value_1";
else if(s.charAt(i) == '0')
spani.className="value_0";
else if(s.charAt(i) == 'X')
spani.className="value_x";
spani.appendChild(document.createTextNode('\u00A0'));
li.appendChild(spani);
}
ul.appendChild(li);
var objDiv = document.getElementById(n + '_container');
objDiv.scrollTop = objDiv.scrollHeight;
}
}
var open_connection = function(name){
var s = new WebSocket('ws://'+window.location.host+'/ws/i_simple_system.i_'+name);
s.addEventListener('error', function (m) { log(name, new Date().toISOString()+': ===connection error ==='); });
s.addEventListener('open', function (m) { log(name, new Date().toISOString()+': ===connection opened==='); });
s.addEventListener('message', function (m) { log(name, m.data); });
s.addEventListener('close', function (m) { log(name, new Date().toISOString()+': ===connection closed==='); });
}
var createElem = function(n){
var top = document.getElementById('top');
var p = document.createElement('p');
p.innerText="Component " + n;
var div = document.createElement('div');
div.className = "term";
div.id= n + '_container';
var ul = document.createElement('ul');
ul.id= n;
div.appendChild(ul);
top.appendChild(p);
top.appendChild(div);
open_connection(n);
}
createElem("uart0");
createElem("gpio0");
</script>
</body>
</html>

View File

@ -12,8 +12,13 @@ addrmap e300_plat_t {
plic_regs plic @0x0C000000; plic_regs plic @0x0C000000;
aon_regs aon @0x10000000; aon_regs aon @0x10000000;
prci_regs prci @0x10008000; prci_regs prci @0x10008000;
gpio_regs gpio @0x10012000; gpio_regs gpio0 @0x10012000;
uart_regs uart0 @0x10013000; uart_regs uart0 @0x10013000;
spi_regs spi @0x10014000; spi_regs qspi0 @0x10014000;
//pwm_regs pwm0 @0x10015000;
uart_regs uart1 @0x10023000; uart_regs uart1 @0x10023000;
spi_regs qspi1 @0x10024000;
//pwm_regs pwm1 @0x10025000;
spi_regs qspi2 @0x10034000;
//pwm_regs pwm2 @0x10035000;
} e300_plat; } e300_plat;

View File

@ -3,17 +3,17 @@ regfile plic_regs {
name="priority"; name="priority";
desc="interrupt source priority"; desc="interrupt source priority";
field {} priority[2:0]; field {} priority[2:0];
} priority[255] @0x004; } priority[256] @0x000;
reg { reg {
name="pending"; name="pending";
desc="pending irq"; desc="pending irq";
field {} pending[31:0]; field {} pending[31:0];
} pending @0x1000; } pending[8] @0x1000;
reg { reg {
name="enabled"; name="enabled";
desc="enabled interrupts"; desc="enabled interrupts";
field {} enabled[31:0]; field {} enabled[31:0];
} enabled @0x2000; } enabled[8] @0x2000;
reg { reg {
name="threshold"; name="threshold";
desc="interrupt priority threshold"; desc="interrupt priority threshold";

View File

@ -86,6 +86,14 @@ public:
sc_core::sc_in<bool> rst_i; sc_core::sc_in<bool> rst_i;
sc_core::sc_in<bool> global_irq_i;
sc_core::sc_in<bool> timer_irq_i;
sc_core::sc_in<bool> sw_irq_i;
sc_core::sc_vector<sc_core::sc_in<bool>> local_irq_i;
scc::ext_attribute<std::string> elf_file; scc::ext_attribute<std::string> elf_file;
scc::ext_attribute<bool> enable_disass; scc::ext_attribute<bool> enable_disass;
@ -124,6 +132,9 @@ protected:
void start_of_simulation(); void start_of_simulation();
void run(); void run();
void clk_cb(); void clk_cb();
void sw_irq_cb();
void timer_irq_cb();
void global_irq_cb();
util::range_lut<tlm_dmi_ext> read_lut, write_lut; util::range_lut<tlm_dmi_ext> read_lut, write_lut;
tlm_utils::tlm_quantumkeeper quantum_keeper; tlm_utils::tlm_quantumkeeper quantum_keeper;
std::vector<uint8_t> write_buf; std::vector<uint8_t> write_buf;

View File

@ -28,7 +28,7 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. // POSSIBILITY OF SUCH DAMAGE.
// //
// Created on: Wed Oct 04 10:06:35 CEST 2017 // Created on: Fri Nov 10 18:01:53 CET 2017
// * aon_regs.h Author: <RDL Generator> // * aon_regs.h Author: <RDL Generator>
// //
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -36,14 +36,17 @@
#ifndef _AON_REGS_H_ #ifndef _AON_REGS_H_
#define _AON_REGS_H_ #define _AON_REGS_H_
#include <scc/utilities.h>
#include <util/bit_field.h> #include <util/bit_field.h>
#include "scc/register.h" #include <scc/register.h>
#include "scc/tlm_target.h" #include <scc/tlm_target.h>
#include "scc/utilities.h"
namespace sysc { namespace sysc {
class aon_regs : public sc_core::sc_module, public scc::resetable { class aon_regs :
public sc_core::sc_module,
public scc::resetable
{
public: public:
// storage declarations // storage declarations
uint32_t r_wdogcfg; uint32_t r_wdogcfg;
@ -77,7 +80,7 @@ public:
BF_FIELD(vddpaden, 5, 1); BF_FIELD(vddpaden, 5, 1);
BF_FIELD(corerst, 7, 1); BF_FIELD(corerst, 7, 1);
BF_FIELD(hfclkrst, 8, 1); BF_FIELD(hfclkrst, 8, 1);
END_BF_DECL(); END_BF_DECL() ;
std::array<pmuwakeupi_t, 8> r_pmuwakeupi; std::array<pmuwakeupi_t, 8> r_pmuwakeupi;
BEGIN_BF_DECL(pmusleepi_t, uint32_t); BEGIN_BF_DECL(pmusleepi_t, uint32_t);
@ -85,7 +88,7 @@ public:
BF_FIELD(vddpaden, 5, 1); BF_FIELD(vddpaden, 5, 1);
BF_FIELD(corerst, 7, 1); BF_FIELD(corerst, 7, 1);
BF_FIELD(hfclkrst, 8, 1); BF_FIELD(hfclkrst, 8, 1);
END_BF_DECL(); END_BF_DECL() ;
std::array<pmusleepi_t, 8> r_pmusleepi; std::array<pmusleepi_t, 8> r_pmusleepi;
uint32_t r_pmuie; uint32_t r_pmuie;
@ -119,7 +122,8 @@ public:
aon_regs(sc_core::sc_module_name nm); aon_regs(sc_core::sc_module_name nm);
template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target); template<unsigned BUSWIDTH=32>
void registerResources(scc::tlm_target<BUSWIDTH>& target);
}; };
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -146,9 +150,12 @@ inline sysc::aon_regs::aon_regs(sc_core::sc_module_name nm)
, NAMED(pmuie, r_pmuie, 0, *this) , NAMED(pmuie, r_pmuie, 0, *this)
, NAMED(pmucause, r_pmucause, 0, *this) , NAMED(pmucause, r_pmucause, 0, *this)
, NAMED(pmusleep, r_pmusleep, 0, *this) , NAMED(pmusleep, r_pmusleep, 0, *this)
, NAMED(pmukey, r_pmukey, 0, *this) {} , NAMED(pmukey, r_pmukey, 0, *this)
{
}
template <unsigned BUSWIDTH> inline void sysc::aon_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) { template<unsigned BUSWIDTH>
inline void sysc::aon_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) {
target.addResource(wdogcfg, 0x0UL); target.addResource(wdogcfg, 0x0UL);
target.addResource(wdogcount, 0x8UL); target.addResource(wdogcount, 0x8UL);
target.addResource(wdogs, 0x10UL); target.addResource(wdogs, 0x10UL);

View File

@ -28,7 +28,7 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. // POSSIBILITY OF SUCH DAMAGE.
// //
// Created on: Wed Oct 04 10:06:35 CEST 2017 // Created on: Fri Nov 10 18:01:53 CET 2017
// * clint_regs.h Author: <RDL Generator> // * clint_regs.h Author: <RDL Generator>
// //
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -36,14 +36,17 @@
#ifndef _CLINT_REGS_H_ #ifndef _CLINT_REGS_H_
#define _CLINT_REGS_H_ #define _CLINT_REGS_H_
#include <scc/utilities.h>
#include <util/bit_field.h> #include <util/bit_field.h>
#include "scc/register.h" #include <scc/register.h>
#include "scc/tlm_target.h" #include <scc/tlm_target.h>
#include "scc/utilities.h"
namespace sysc { namespace sysc {
class clint_regs : public sc_core::sc_module, public scc::resetable { class clint_regs :
public sc_core::sc_module,
public scc::resetable
{
public: public:
// storage declarations // storage declarations
BEGIN_BF_DECL(msip_t, uint32_t); BEGIN_BF_DECL(msip_t, uint32_t);
@ -61,7 +64,8 @@ public:
clint_regs(sc_core::sc_module_name nm); clint_regs(sc_core::sc_module_name nm);
template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target); template<unsigned BUSWIDTH=32>
void registerResources(scc::tlm_target<BUSWIDTH>& target);
}; };
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -72,9 +76,12 @@ inline sysc::clint_regs::clint_regs(sc_core::sc_module_name nm)
: sc_core::sc_module(nm) : sc_core::sc_module(nm)
, NAMED(msip, r_msip, 0, *this) , NAMED(msip, r_msip, 0, *this)
, NAMED(mtimecmp, r_mtimecmp, 0, *this) , NAMED(mtimecmp, r_mtimecmp, 0, *this)
, NAMED(mtime, r_mtime, 0, *this) {} , NAMED(mtime, r_mtime, 0, *this)
{
}
template <unsigned BUSWIDTH> inline void sysc::clint_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) { template<unsigned BUSWIDTH>
inline void sysc::clint_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) {
target.addResource(msip, 0x0UL); target.addResource(msip, 0x0UL);
target.addResource(mtimecmp, 0x4000UL); target.addResource(mtimecmp, 0x4000UL);
target.addResource(mtime, 0xbff8UL); target.addResource(mtime, 0xbff8UL);

View File

@ -1,16 +1,17 @@
#ifndef _E300_PLAT_MAP_H_ #ifndef _E300_PLAT_MAP_H_
#define _E300_PLAT_MAP_H_ #define _E300_PLAT_MAP_H_
// need double braces, see // need double braces, see https://stackoverflow.com/questions/6893700/how-to-construct-stdarray-object-with-initializer-list#6894191
// https://stackoverflow.com/questions/6893700/how-to-construct-stdarray-object-with-initializer-list#6894191 const std::array<scc::target_memory_map_entry<32>, 10> e300_plat_map = {{
const std::array<scc::target_memory_map_entry<32>, 8> e300_plat_map = {{
{&i_clint, 0x2000000, 0xc000}, {&i_clint, 0x2000000, 0xc000},
{&i_plic, 0xc000000, 0x200008}, {&i_plic, 0xc000000, 0x200008},
{&i_aon, 0x10000000, 0x150}, {&i_aon, 0x10000000, 0x150},
{&i_prci, 0x10008000, 0x14}, {&i_prci, 0x10008000, 0x14},
{&i_gpio, 0x10012000, 0x44}, {&i_gpio0, 0x10012000, 0x44},
{&i_uart0, 0x10013000, 0x1c}, {&i_uart0, 0x10013000, 0x1c},
{&i_qspi0, 0x10014000, 0x78},
{&i_uart1, 0x10023000, 0x1c}, {&i_uart1, 0x10023000, 0x1c},
{&i_spi, 0x10014000, 0x78}, {&i_qspi1, 0x10024000, 0x78},
{&i_qspi2, 0x10034000, 0x78},
}}; }};
#endif /* _E300_PLAT_MAP_H_ */ #endif /* _E300_PLAT_MAP_H_ */

View File

@ -28,7 +28,7 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. // POSSIBILITY OF SUCH DAMAGE.
// //
// Created on: Wed Oct 04 10:06:35 CEST 2017 // Created on: Fri Nov 10 18:01:53 CET 2017
// * gpio_regs.h Author: <RDL Generator> // * gpio_regs.h Author: <RDL Generator>
// //
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -36,14 +36,17 @@
#ifndef _GPIO_REGS_H_ #ifndef _GPIO_REGS_H_
#define _GPIO_REGS_H_ #define _GPIO_REGS_H_
#include <scc/utilities.h>
#include <util/bit_field.h> #include <util/bit_field.h>
#include "scc/register.h" #include <scc/register.h>
#include "scc/tlm_target.h" #include <scc/tlm_target.h>
#include "scc/utilities.h"
namespace sysc { namespace sysc {
class gpio_regs : public sc_core::sc_module, public scc::resetable { class gpio_regs :
public sc_core::sc_module,
public scc::resetable
{
public: public:
// storage declarations // storage declarations
uint32_t r_value; uint32_t r_value;
@ -101,7 +104,8 @@ public:
gpio_regs(sc_core::sc_module_name nm); gpio_regs(sc_core::sc_module_name nm);
template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target); template<unsigned BUSWIDTH=32>
void registerResources(scc::tlm_target<BUSWIDTH>& target);
}; };
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -126,9 +130,12 @@ inline sysc::gpio_regs::gpio_regs(sc_core::sc_module_name nm)
, NAMED(low_ip, r_low_ip, 0, *this) , NAMED(low_ip, r_low_ip, 0, *this)
, NAMED(iof_en, r_iof_en, 0, *this) , NAMED(iof_en, r_iof_en, 0, *this)
, NAMED(iof_sel, r_iof_sel, 0, *this) , NAMED(iof_sel, r_iof_sel, 0, *this)
, NAMED(out_xor, r_out_xor, 0, *this) {} , NAMED(out_xor, r_out_xor, 0, *this)
{
}
template <unsigned BUSWIDTH> inline void sysc::gpio_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) { template<unsigned BUSWIDTH>
inline void sysc::gpio_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) {
target.addResource(value, 0x0UL); target.addResource(value, 0x0UL);
target.addResource(input_en, 0x4UL); target.addResource(input_en, 0x4UL);
target.addResource(output_en, 0x8UL); target.addResource(output_en, 0x8UL);

View File

@ -28,7 +28,7 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. // POSSIBILITY OF SUCH DAMAGE.
// //
// Created on: Wed Oct 04 10:06:35 CEST 2017 // Created on: Fri Nov 10 18:01:53 CET 2017
// * plic_regs.h Author: <RDL Generator> // * plic_regs.h Author: <RDL Generator>
// //
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -36,24 +36,27 @@
#ifndef _PLIC_REGS_H_ #ifndef _PLIC_REGS_H_
#define _PLIC_REGS_H_ #define _PLIC_REGS_H_
#include <scc/utilities.h>
#include <util/bit_field.h> #include <util/bit_field.h>
#include "scc/register.h" #include <scc/register.h>
#include "scc/tlm_target.h" #include <scc/tlm_target.h>
#include "scc/utilities.h"
namespace sysc { namespace sysc {
class plic_regs : public sc_core::sc_module, public scc::resetable { class plic_regs :
public sc_core::sc_module,
public scc::resetable
{
public: public:
// storage declarations // storage declarations
BEGIN_BF_DECL(priority_t, uint32_t); BEGIN_BF_DECL(priority_t, uint32_t);
BF_FIELD(priority, 0, 3); BF_FIELD(priority, 0, 3);
END_BF_DECL(); END_BF_DECL() ;
std::array<priority_t, 255> r_priority; std::array<priority_t, 256> r_priority;
uint32_t r_pending; std::array<uint32_t, 8> r_pending;
uint32_t r_enabled; std::array<uint32_t, 8> r_enabled;
BEGIN_BF_DECL(threshold_t, uint32_t); BEGIN_BF_DECL(threshold_t, uint32_t);
BF_FIELD(threshold, 0, 3); BF_FIELD(threshold, 0, 3);
@ -62,15 +65,16 @@ public:
uint32_t r_claim_complete; uint32_t r_claim_complete;
// register declarations // register declarations
scc::sc_register_indexed<priority_t, 255> priority; scc::sc_register_indexed<priority_t, 256> priority;
scc::sc_register<uint32_t> pending; scc::sc_register_indexed<uint32_t, 8> pending;
scc::sc_register<uint32_t> enabled; scc::sc_register_indexed<uint32_t, 8> enabled;
scc::sc_register<threshold_t> threshold; scc::sc_register<threshold_t> threshold;
scc::sc_register<uint32_t> claim_complete; scc::sc_register<uint32_t> claim_complete;
plic_regs(sc_core::sc_module_name nm); plic_regs(sc_core::sc_module_name nm);
template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target); template<unsigned BUSWIDTH=32>
void registerResources(scc::tlm_target<BUSWIDTH>& target);
}; };
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -83,10 +87,13 @@ inline sysc::plic_regs::plic_regs(sc_core::sc_module_name nm)
, NAMED(pending, r_pending, 0, *this) , NAMED(pending, r_pending, 0, *this)
, NAMED(enabled, r_enabled, 0, *this) , NAMED(enabled, r_enabled, 0, *this)
, NAMED(threshold, r_threshold, 0, *this) , NAMED(threshold, r_threshold, 0, *this)
, NAMED(claim_complete, r_claim_complete, 0, *this) {} , NAMED(claim_complete, r_claim_complete, 0, *this)
{
}
template <unsigned BUSWIDTH> inline void sysc::plic_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) { template<unsigned BUSWIDTH>
target.addResource(priority, 0x4UL); inline void sysc::plic_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) {
target.addResource(priority, 0x0UL);
target.addResource(pending, 0x1000UL); target.addResource(pending, 0x1000UL);
target.addResource(enabled, 0x2000UL); target.addResource(enabled, 0x2000UL);
target.addResource(threshold, 0x200000UL); target.addResource(threshold, 0x200000UL);

View File

@ -28,7 +28,7 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. // POSSIBILITY OF SUCH DAMAGE.
// //
// Created on: Wed Oct 04 10:06:35 CEST 2017 // Created on: Fri Nov 10 18:01:53 CET 2017
// * prci_regs.h Author: <RDL Generator> // * prci_regs.h Author: <RDL Generator>
// //
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -36,14 +36,17 @@
#ifndef _PRCI_REGS_H_ #ifndef _PRCI_REGS_H_
#define _PRCI_REGS_H_ #define _PRCI_REGS_H_
#include <scc/utilities.h>
#include <util/bit_field.h> #include <util/bit_field.h>
#include "scc/register.h" #include <scc/register.h>
#include "scc/tlm_target.h" #include <scc/tlm_target.h>
#include "scc/utilities.h"
namespace sysc { namespace sysc {
class prci_regs : public sc_core::sc_module, public scc::resetable { class prci_regs :
public sc_core::sc_module,
public scc::resetable
{
public: public:
// storage declarations // storage declarations
BEGIN_BF_DECL(hfrosccfg_t, uint32_t); BEGIN_BF_DECL(hfrosccfg_t, uint32_t);
@ -81,7 +84,8 @@ public:
prci_regs(sc_core::sc_module_name nm); prci_regs(sc_core::sc_module_name nm);
template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target); template<unsigned BUSWIDTH=32>
void registerResources(scc::tlm_target<BUSWIDTH>& target);
}; };
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -94,9 +98,12 @@ inline sysc::prci_regs::prci_regs(sc_core::sc_module_name nm)
, NAMED(hfxosccfg, r_hfxosccfg, 0, *this) , NAMED(hfxosccfg, r_hfxosccfg, 0, *this)
, NAMED(pllcfg, r_pllcfg, 0, *this) , NAMED(pllcfg, r_pllcfg, 0, *this)
, NAMED(plloutdiv, r_plloutdiv, 0, *this) , NAMED(plloutdiv, r_plloutdiv, 0, *this)
, NAMED(coreclkcfg, r_coreclkcfg, 0, *this) {} , NAMED(coreclkcfg, r_coreclkcfg, 0, *this)
{
}
template <unsigned BUSWIDTH> inline void sysc::prci_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) { template<unsigned BUSWIDTH>
inline void sysc::prci_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) {
target.addResource(hfrosccfg, 0x0UL); target.addResource(hfrosccfg, 0x0UL);
target.addResource(hfxosccfg, 0x4UL); target.addResource(hfxosccfg, 0x4UL);
target.addResource(pllcfg, 0x8UL); target.addResource(pllcfg, 0x8UL);

View File

@ -28,7 +28,7 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. // POSSIBILITY OF SUCH DAMAGE.
// //
// Created on: Wed Oct 04 10:06:35 CEST 2017 // Created on: Fri Nov 10 18:01:53 CET 2017
// * spi_regs.h Author: <RDL Generator> // * spi_regs.h Author: <RDL Generator>
// //
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -36,14 +36,17 @@
#ifndef _SPI_REGS_H_ #ifndef _SPI_REGS_H_
#define _SPI_REGS_H_ #define _SPI_REGS_H_
#include <scc/utilities.h>
#include <util/bit_field.h> #include <util/bit_field.h>
#include "scc/register.h" #include <scc/register.h>
#include "scc/tlm_target.h" #include <scc/tlm_target.h>
#include "scc/utilities.h"
namespace sysc { namespace sysc {
class spi_regs : public sc_core::sc_module, public scc::resetable { class spi_regs :
public sc_core::sc_module,
public scc::resetable
{
public: public:
// storage declarations // storage declarations
BEGIN_BF_DECL(sckdiv_t, uint32_t); BEGIN_BF_DECL(sckdiv_t, uint32_t);
@ -143,7 +146,8 @@ public:
spi_regs(sc_core::sc_module_name nm); spi_regs(sc_core::sc_module_name nm);
template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target); template<unsigned BUSWIDTH=32>
void registerResources(scc::tlm_target<BUSWIDTH>& target);
}; };
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -167,9 +171,12 @@ inline sysc::spi_regs::spi_regs(sc_core::sc_module_name nm)
, NAMED(fctrl, r_fctrl, 0, *this) , NAMED(fctrl, r_fctrl, 0, *this)
, NAMED(ffmt, r_ffmt, 0, *this) , NAMED(ffmt, r_ffmt, 0, *this)
, NAMED(ie, r_ie, 0, *this) , NAMED(ie, r_ie, 0, *this)
, NAMED(ip, r_ip, 0, *this) {} , NAMED(ip, r_ip, 0, *this)
{
}
template <unsigned BUSWIDTH> inline void sysc::spi_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) { template<unsigned BUSWIDTH>
inline void sysc::spi_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) {
target.addResource(sckdiv, 0x0UL); target.addResource(sckdiv, 0x0UL);
target.addResource(sckmode, 0x4UL); target.addResource(sckmode, 0x4UL);
target.addResource(csid, 0x10UL); target.addResource(csid, 0x10UL);

View File

@ -28,7 +28,7 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. // POSSIBILITY OF SUCH DAMAGE.
// //
// Created on: Wed Oct 04 10:06:35 CEST 2017 // Created on: Fri Nov 10 18:01:53 CET 2017
// * uart_regs.h Author: <RDL Generator> // * uart_regs.h Author: <RDL Generator>
// //
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -36,14 +36,17 @@
#ifndef _UART_REGS_H_ #ifndef _UART_REGS_H_
#define _UART_REGS_H_ #define _UART_REGS_H_
#include <scc/utilities.h>
#include <util/bit_field.h> #include <util/bit_field.h>
#include "scc/register.h" #include <scc/register.h>
#include "scc/tlm_target.h" #include <scc/tlm_target.h>
#include "scc/utilities.h"
namespace sysc { namespace sysc {
class uart_regs : public sc_core::sc_module, public scc::resetable { class uart_regs :
public sc_core::sc_module,
public scc::resetable
{
public: public:
// storage declarations // storage declarations
BEGIN_BF_DECL(txdata_t, uint32_t); BEGIN_BF_DECL(txdata_t, uint32_t);
@ -92,7 +95,8 @@ public:
uart_regs(sc_core::sc_module_name nm); uart_regs(sc_core::sc_module_name nm);
template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target); template<unsigned BUSWIDTH=32>
void registerResources(scc::tlm_target<BUSWIDTH>& target);
}; };
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -107,9 +111,12 @@ inline sysc::uart_regs::uart_regs(sc_core::sc_module_name nm)
, NAMED(rxctrl, r_rxctrl, 0, *this) , NAMED(rxctrl, r_rxctrl, 0, *this)
, NAMED(ie, r_ie, 0, *this) , NAMED(ie, r_ie, 0, *this)
, NAMED(ip, r_ip, 0, *this) , NAMED(ip, r_ip, 0, *this)
, NAMED(div, r_div, 0, *this) {} , NAMED(div, r_div, 0, *this)
{
}
template <unsigned BUSWIDTH> inline void sysc::uart_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) { template<unsigned BUSWIDTH>
inline void sysc::uart_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) {
target.addResource(txdata, 0x0UL); target.addResource(txdata, 0x0UL);
target.addResource(rxdata, 0x4UL); target.addResource(rxdata, 0x4UL);
target.addResource(txctrl, 0x8UL); target.addResource(txctrl, 0x8UL);

View File

@ -18,24 +18,34 @@
#define _GPIO_H_ #define _GPIO_H_
#include "scc/tlm_target.h" #include "scc/tlm_target.h"
#include <sysc/communication/sc_signal_rv_ports.h>
namespace sysc { namespace sysc {
class gpio_regs; class gpio_regs;
class WsHandler;
class gpio : public sc_core::sc_module, public scc::tlm_target<> { class gpio : public sc_core::sc_module, public scc::tlm_target<> {
public: public:
SC_HAS_PROCESS(gpio); SC_HAS_PROCESS(gpio);
sc_core::sc_in<sc_core::sc_time> clk_i; sc_core::sc_in<sc_core::sc_time> clk_i;
sc_core::sc_in<bool> rst_i; sc_core::sc_in<bool> rst_i;
sc_core::sc_inout_rv<32> pins_io;
gpio(sc_core::sc_module_name nm); gpio(sc_core::sc_module_name nm);
virtual ~gpio() override; // need to keep it in source file because of fwd declaration of gpio_regs virtual ~gpio() override; // need to keep it in source file because of fwd declaration of gpio_regs
protected: protected:
void clock_cb(); void clock_cb();
void reset_cb(); void reset_cb();
void update_pins();
void pins_cb();
sc_core::sc_time clk; sc_core::sc_time clk;
std::unique_ptr<gpio_regs> regs; std::unique_ptr<gpio_regs> regs;
std::shared_ptr<sysc::WsHandler> handler;
private:
void update_value_reg();
}; };
} /* namespace sysc */ } /* namespace sysc */

View File

@ -48,8 +48,8 @@ public:
SiFive::core_complex i_core_complex; SiFive::core_complex i_core_complex;
scc::router<> i_router; scc::router<> i_router;
uart i_uart0, i_uart1; uart i_uart0, i_uart1;
spi i_spi; spi i_qspi0, i_qspi1, i_qspi2;
gpio i_gpio; gpio i_gpio0;
plic i_plic; plic i_plic;
aon i_aon; aon i_aon;
prci i_prci; prci i_prci;
@ -59,8 +59,9 @@ public:
scc::memory<128_kB, 32> i_mem_ram; scc::memory<128_kB, 32> i_mem_ram;
sc_core::sc_signal<sc_core::sc_time> s_clk; sc_core::sc_signal<sc_core::sc_time> s_clk;
sc_core::sc_signal<bool> s_rst, s_mtime_int, s_msie_int; sc_core::sc_signal<bool> s_rst, s_mtime_int, s_msie_int;
sc_core::sc_vector<sc_core::sc_signal<bool>> s_global_int; sc_core::sc_vector<sc_core::sc_signal<bool>> s_global_int, s_local_int;
sc_core::sc_signal<bool> s_core_int; sc_core::sc_signal<bool> s_core_int;
sc_core::sc_signal_rv<32> s_gpio_pins;
platform(sc_core::sc_module_name nm); platform(sc_core::sc_module_name nm);

View File

@ -22,6 +22,7 @@
namespace sysc { namespace sysc {
class uart_regs; class uart_regs;
class WsHandler;
class uart : public sc_core::sc_module, public scc::tlm_target<> { class uart : public sc_core::sc_module, public scc::tlm_target<> {
public: public:
@ -38,6 +39,7 @@ protected:
sc_core::sc_time clk; sc_core::sc_time clk;
std::unique_ptr<uart_regs> regs; std::unique_ptr<uart_regs> regs;
std::vector<uint8_t> queue; std::vector<uint8_t> queue;
std::shared_ptr<sysc::WsHandler> handler;
}; };
} /* namespace sysc */ } /* namespace sysc */

View File

@ -0,0 +1,82 @@
/*
* sc_singleton.h
*
* Created on: 09.10.2017
* Author: eyck
*/
#ifndef RISCV_SC_INCL_SYSC_SC_COMM_SINGLETON_H_
#define RISCV_SC_INCL_SYSC_SC_COMM_SINGLETON_H_
#include <sysc/kernel/sc_module.h>
#include <seasocks/PageHandler.h>
#include "seasocks/WebSocket.h"
#include <memory>
#include <thread>
#include <cstring>
namespace sysc {
class WsHandler: public seasocks::WebSocket::Handler {
public:
explicit WsHandler() { }
void onConnect(seasocks::WebSocket* connection) override;
void onData(seasocks::WebSocket* connection, const char* data) override;
void onDisconnect(seasocks::WebSocket* connection) override;
void send(std::string msg) { for (auto *con : _connections) con->send(msg); }
void set_receive_callback(std::function<void(const char* data)> cb){callback=cb;}
private:
std::set<seasocks::WebSocket*> _connections;
std::function<void(const char* data)> callback;
};
class sc_comm_singleton: public sc_core::sc_module {
struct DefaultPageHandler: public seasocks::PageHandler {
DefaultPageHandler(sc_comm_singleton& o):owner(o){}
virtual std::shared_ptr<seasocks::Response> handle(const seasocks::Request& request);
sc_comm_singleton& owner;
};
public:
sc_comm_singleton() = delete;
sc_comm_singleton(const sc_comm_singleton&) = delete;
sc_comm_singleton& operator=(sc_comm_singleton& o) = delete;
virtual ~sc_comm_singleton();
static sc_comm_singleton& inst(){
static sc_comm_singleton i("__sc_singleton");
return i;
}
seasocks::Server& get_server();
void registerWebSocketHandler(const char* endpoint, std::shared_ptr<seasocks::WebSocket::Handler> handler, bool allowCrossOriginRequests = false);
void execute(std::function<void()> f);
void start_client();
protected:
void start_of_simulation() override;
void end_of_simulation() override;
private:
sc_comm_singleton(sc_core::sc_module_name nm);
std::unique_ptr<seasocks::Server> m_serv;
std::thread t;
void thread_func();
bool client_started;
};
} /* namespace sysc */
#endif /* RISCV_SC_INCL_SYSC_SC_COMM_SINGLETON_H_ */

View File

@ -1,49 +0,0 @@
/*
* sc_singleton.h
*
* Created on: 09.10.2017
* Author: eyck
*/
#ifndef RISCV_SC_INCL_SYSC_SC_SINGLETON_H_
#define RISCV_SC_INCL_SYSC_SC_SINGLETON_H_
#include <sysc/kernel/sc_module.h>
#include <memory>
#include <thread>
namespace seasocks {
class Server;
}
namespace sysc {
class sc_singleton: public sc_core::sc_module {
public:
sc_singleton() = delete;
sc_singleton(const sc_singleton&) = delete;
sc_singleton& operator=(sc_singleton& o) = delete;
virtual ~sc_singleton();
static sc_singleton& inst(){
static sc_singleton i("__sc_singleton");
return i;
}
seasocks::Server& get_server();
protected:
void start_of_simulation();
private:
sc_singleton(sc_core::sc_module_name nm);
std::unique_ptr<seasocks::Server> m_serv;
std::thread t;
void thread_func();
};
} /* namespace sysc */
#endif /* RISCV_SC_INCL_SYSC_SC_SINGLETON_H_ */

View File

@ -56,11 +56,11 @@ int sc_main(int argc, char *argv[]) {
("elf,l", po::value<std::string>(), "ELF file to load") ("elf,l", po::value<std::string>(), "ELF file to load")
("gdb-port,g", po::value<unsigned short>()->default_value(0), "enable gdb server and specify port to use") ("gdb-port,g", po::value<unsigned short>()->default_value(0), "enable gdb server and specify port to use")
("dump-ir", "dump the intermediate representation") ("dump-ir", "dump the intermediate representation")
("cycles,c", po::value<int64_t>()->default_value(-1), "number of cycles to run") ("cycles", po::value<int64_t>()->default_value(-1), "number of cycles to run")
("quantum", po::value<unsigned>(), "SystemC quantum time in ns") ("quantum", po::value<unsigned>(), "SystemC quantum time in ns")
("reset,r", po::value<std::string>(), "reset address") ("reset,r", po::value<std::string>(), "reset address")
("trace,t", po::value<unsigned>()->default_value(0), "enable tracing, or combintation of 1=signals and 2=TX text, 4=TX compressed text, 6=TX in SQLite") ("trace,t", po::value<unsigned>()->default_value(0), "enable tracing, or combintation of 1=signals and 2=TX text, 4=TX compressed text, 6=TX in SQLite")
("rv64", "run RV64") ("max_time,m", po::value<std::string>(), "maximum time to run")
("config-file,c", po::value<std::string>()->default_value(""), "configuration file"); ("config-file,c", po::value<std::string>()->default_value(""), "configuration file");
// clang-format on // clang-format on
po::variables_map vm; po::variables_map vm;
@ -136,6 +136,10 @@ int sc_main(int argc, char *argv[]) {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// run simulation // run simulation
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
if(vm.count("max_time")){
sc_core::sc_time max_time = scc::parse_from_string(vm["max_time"].as<std::string>());
sc_core::sc_start(max_time);
} else
sc_core::sc_start(); sc_core::sc_start();
if (!sc_core::sc_end_of_simulation_invoked()) sc_core::sc_stop(); if (!sc_core::sc_end_of_simulation_invoked()) sc_core::sc_stop();
return 0; return 0;

View File

@ -35,7 +35,9 @@ aon::aon(sc_core::sc_module_name nm)
dont_initialize(); dont_initialize();
} }
void aon::clock_cb() {} void aon::clock_cb() {
this->clk = clk_i.read();
}
aon::~aon() {} aon::~aon() {}

View File

@ -17,6 +17,7 @@
#include "sysc/SiFive/clint.h" #include "sysc/SiFive/clint.h"
#include "scc/utilities.h" #include "scc/utilities.h"
#include "scc/report.h"
#include "sysc/SiFive/gen/clint_regs.h" #include "sysc/SiFive/gen/clint_regs.h"
namespace sysc { namespace sysc {
@ -63,7 +64,7 @@ clint::clint(sc_core::sc_module_name nm)
void clint::clock_cb() { void clint::clock_cb() {
update_mtime(); update_mtime();
clk = clk_i.read(); this->clk = clk_i.read();
update_mtime(); update_mtime();
} }
@ -85,9 +86,12 @@ void clint::update_mtime() {
regs->r_mtime += (diffi + cnt_fraction) / lfclk_mutiplier; regs->r_mtime += (diffi + cnt_fraction) / lfclk_mutiplier;
cnt_fraction = (cnt_fraction + diffi) % lfclk_mutiplier; cnt_fraction = (cnt_fraction + diffi) % lfclk_mutiplier;
mtime_evt.cancel(); mtime_evt.cancel();
if (regs->r_mtimecmp > regs->r_mtime && clk > sc_core::SC_ZERO_TIME) { if (regs->r_mtimecmp > 0)
if(regs->r_mtimecmp > regs->r_mtime && clk > sc_core::SC_ZERO_TIME) {
sc_core::sc_time next_trigger = (clk * lfclk_mutiplier) * (regs->r_mtimecmp - regs->mtime) - cnt_fraction * clk; sc_core::sc_time next_trigger = (clk * lfclk_mutiplier) * (regs->r_mtimecmp - regs->mtime) - cnt_fraction * clk;
LOG(DEBUG)<<"Timer fires at "<< sc_time_stamp()+next_trigger;
mtime_evt.notify(next_trigger); mtime_evt.notify(next_trigger);
mtime_int_o.write(false);
} else } else
mtime_int_o.write(true); mtime_int_o.write(true);
last_updt = sc_core::sc_time_stamp(); last_updt = sc_core::sc_time_stamp();

View File

@ -118,12 +118,43 @@ public:
iss::status write_mem(phys_addr_t addr, unsigned length, const uint8_t *const data) { iss::status write_mem(phys_addr_t addr, unsigned length, const uint8_t *const data) {
if (addr.type & iss::DEBUG) if (addr.type & iss::DEBUG)
return owner->write_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err; return owner->write_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err;
else else{
return owner->write_mem(addr.val, length, data) ? iss::Ok : iss::Err; auto res = owner->write_mem(addr.val, length, data) ? iss::Ok : iss::Err;
// TODO: this is an ugly hack (clear MTIP on mtimecmp write), needs to be fixed
if(addr.val==0x2004000)
this->csr[iss::arch::mip] &= ~(1ULL<<7);
return res;
}
} }
void wait_until(uint64_t flags) {
do{
wait(wfi_evt);
this->check_interrupt();
} while(this->reg.pending_trap==0);
base_type::wait_until(flags);
}
void local_irq(short id){
switch(id){
case 16: // SW
this->csr[iss::arch::mip] |= 1<<3;
break;
case 17: // timer
this->csr[iss::arch::mip] |= 1<<7;
break;
case 18: //external
this->csr[iss::arch::mip] |= 1<<11;
break;
default:
/* do nothing*/
break;
}
wfi_evt.notify();
}
private: private:
core_complex *const owner; core_complex *const owner;
sc_event wfi_evt;
}; };
int cmd_sysc(int argc, char* argv[], iss::debugger::out_func of, iss::debugger::data_func df, iss::debugger::target_adapter_if* tgt_adapter){ int cmd_sysc(int argc, char* argv[], iss::debugger::out_func of, iss::debugger::data_func df, iss::debugger::target_adapter_if* tgt_adapter){
@ -166,6 +197,9 @@ core_complex::core_complex(sc_core::sc_module_name name)
, NAMED(initiator) , NAMED(initiator)
, NAMED(clk_i) , NAMED(clk_i)
, NAMED(rst_i) , NAMED(rst_i)
, NAMED(global_irq_i)
, NAMED(timer_irq_i)
, NAMED(local_irq_i, 16)
, NAMED(elf_file, this) , NAMED(elf_file, this)
, NAMED(enable_disass, true, this) , NAMED(enable_disass, true, this)
, NAMED(reset_address, 0ULL, this) , NAMED(reset_address, 0ULL, this)
@ -196,6 +230,12 @@ core_complex::core_complex(sc_core::sc_module_name name)
SC_THREAD(run); SC_THREAD(run);
SC_METHOD(clk_cb); SC_METHOD(clk_cb);
sensitive << clk_i; sensitive << clk_i;
SC_METHOD(sw_irq_cb);
sensitive<<sw_irq_i;
SC_METHOD(timer_irq_cb);
sensitive<<timer_irq_i;
SC_METHOD(global_irq_cb);
sensitive<<global_irq_i;
} }
core_complex::~core_complex() = default; core_complex::~core_complex() = default;
@ -242,7 +282,21 @@ void core_complex::disass_output(uint64_t pc, const std::string instr_str) {
#endif #endif
} }
void core_complex::clk_cb() { curr_clk = clk_i.read(); } void core_complex::clk_cb() {
curr_clk = clk_i.read();
}
void core_complex::sw_irq_cb(){
if(sw_irq_i.read()) cpu->local_irq(16);
}
void core_complex::timer_irq_cb(){
if(timer_irq_i.read()) cpu->local_irq(17);
}
void core_complex::global_irq_cb(){
if(timer_irq_i.read()) cpu->local_irq(18);
}
void core_complex::run() { void core_complex::run() {
wait(sc_core::SC_ZERO_TIME); wait(sc_core::SC_ZERO_TIME);
@ -268,7 +322,7 @@ bool core_complex::read_mem(uint64_t addr, unsigned length, uint8_t *const data,
gp.set_address(addr); gp.set_address(addr);
gp.set_data_ptr(data); gp.set_data_ptr(data);
gp.set_data_length(length); gp.set_data_length(length);
gp.set_streaming_width(4); gp.set_streaming_width(length);
auto delay{quantum_keeper.get_local_time()}; auto delay{quantum_keeper.get_local_time()};
#ifdef WITH_SCV #ifdef WITH_SCV
if(m_db!=nullptr && tr_handle.is_valid()){ if(m_db!=nullptr && tr_handle.is_valid()){
@ -315,7 +369,7 @@ bool core_complex::write_mem(uint64_t addr, unsigned length, const uint8_t *cons
gp.set_address(addr); gp.set_address(addr);
gp.set_data_ptr(write_buf.data()); gp.set_data_ptr(write_buf.data());
gp.set_data_length(length); gp.set_data_length(length);
gp.set_streaming_width(4); gp.set_streaming_width(length);
auto delay{quantum_keeper.get_local_time()}; auto delay{quantum_keeper.get_local_time()};
initiator->b_transport(gp, delay); initiator->b_transport(gp, delay);
quantum_keeper.set(delay); quantum_keeper.set(delay);

View File

@ -16,6 +16,8 @@
#include "sysc/SiFive/gpio.h" #include "sysc/SiFive/gpio.h"
#include "sysc/sc_comm_singleton.h"
#include "scc/report.h"
#include "scc/utilities.h" #include "scc/utilities.h"
#include "sysc/SiFive/gen/gpio_regs.h" #include "sysc/SiFive/gen/gpio_regs.h"
@ -26,6 +28,7 @@ gpio::gpio(sc_core::sc_module_name nm)
, tlm_target<>(clk) , tlm_target<>(clk)
, NAMED(clk_i) , NAMED(clk_i)
, NAMED(rst_i) , NAMED(rst_i)
, NAMED(pins_io)
, NAMEDD(gpio_regs, regs) { , NAMEDD(gpio_regs, regs) {
regs->registerResources(*this); regs->registerResources(*this);
SC_METHOD(clock_cb); SC_METHOD(clock_cb);
@ -33,9 +36,31 @@ gpio::gpio(sc_core::sc_module_name nm)
SC_METHOD(reset_cb); SC_METHOD(reset_cb);
sensitive << rst_i; sensitive << rst_i;
dont_initialize(); dont_initialize();
} SC_METHOD(pins_cb);
sensitive << pins_io;
void gpio::clock_cb() {} regs->port.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool {
if (!this->regs->in_reset()) {
reg.put(data);
// read r_ports and update pins_io
update_pins();
}
return true;
});
regs->value.set_read_cb([this](const scc::sc_register<uint32_t> &reg, uint32_t& data) -> bool {
if (!this->regs->in_reset()) {
// read pins_io and update r_value
update_value_reg();
data=reg.get();
}
return true;
});
LOG(TRACE)<<"Adding WS handler for "<<(std::string{"/ws/"}+name());
handler=std::make_shared<WsHandler>();
sc_comm_singleton::inst().registerWebSocketHandler((std::string{"/ws/"}+name()).c_str(), handler);
}
gpio::~gpio() {} gpio::~gpio() {}
@ -46,4 +71,46 @@ void gpio::reset_cb() {
regs->reset_stop(); regs->reset_stop();
} }
void gpio::clock_cb() {
this->clk = clk_i.read();
}
void gpio::pins_cb(){
auto inval=pins_io.read();
std::string msg(inval.to_string());
sc_core::sc_time now = sc_core::sc_time_stamp();
sc_comm_singleton::inst().execute([this, msg, now](){
std::stringstream os;
//os << "[" << std::setw(20) << now << "] "<<msg;
os << "{\"time\":\"" << now << "\",\"data\":\""<<msg<<"\"}";
this->handler->send(os.str());
});
}
void gpio::update_value_reg() {
// read pins_io and update r_value reg
auto inval = pins_io.read();
uint32_t res = 0;
for (size_t i = 0, msk = 1; i < 32; ++i, msk = msk << 1) {
bool bit_set = false;
if ((regs->r_input_en & msk) != 0) {
if (inval.get_bit(1) == sc_dt::Log_1)
bit_set = true;
else if (inval.get_bit(1) == sc_dt::Log_Z
&& (regs->r_pue & msk) != 0)
bit_set = true;
}
if (bit_set) res |= msk;
}
regs->r_value = res;
}
void gpio::update_pins() {
sc_core::sc_inout_rv<32>::data_type out_val;
for(size_t i=0, msk = 1; i<32; ++i, msk=msk<<1)
out_val.set_bit(i, regs->r_output_en&msk?regs->r_port&msk?sc_dt::Log_1:sc_dt::Log_0:sc_dt::Log_Z);
pins_io.write(out_val);
}
} /* namespace sysc */ } /* namespace sysc */

View File

@ -27,11 +27,13 @@ namespace sysc {
platform::platform(sc_core::sc_module_name nm) platform::platform(sc_core::sc_module_name nm)
: sc_core::sc_module(nm) : sc_core::sc_module(nm)
, NAMED(i_core_complex) , NAMED(i_core_complex)
, NAMED(i_router, 10, 1) , NAMED(i_router, 12, 1)
, NAMED(i_uart0) , NAMED(i_uart0)
, NAMED(i_uart1) , NAMED(i_uart1)
, NAMED(i_spi) , NAMED(i_qspi0)
, NAMED(i_gpio) , NAMED(i_qspi1)
, NAMED(i_qspi2)
, NAMED(i_gpio0)
, NAMED(i_plic) , NAMED(i_plic)
, NAMED(i_aon) , NAMED(i_aon)
, NAMED(i_prci) , NAMED(i_prci)
@ -41,7 +43,9 @@ platform::platform(sc_core::sc_module_name nm)
, NAMED(s_clk) , NAMED(s_clk)
, NAMED(s_rst) , NAMED(s_rst)
, NAMED(s_global_int, 256) , NAMED(s_global_int, 256)
, NAMED(s_core_int) { , NAMED(s_local_int, 16)
, NAMED(s_core_int)
, NAMED(s_gpio_pins) {
i_core_complex.initiator(i_router.target[0]); i_core_complex.initiator(i_router.target[0]);
size_t i = 0; size_t i = 0;
for (const auto &e : e300_plat_map) { for (const auto &e : e300_plat_map) {
@ -56,8 +60,10 @@ platform::platform(sc_core::sc_module_name nm)
i_uart0.clk_i(s_clk); i_uart0.clk_i(s_clk);
i_uart1.clk_i(s_clk); i_uart1.clk_i(s_clk);
i_spi.clk_i(s_clk); i_qspi0.clk_i(s_clk);
i_gpio.clk_i(s_clk); i_qspi1.clk_i(s_clk);
i_qspi2.clk_i(s_clk);
i_gpio0.clk_i(s_clk);
i_plic.clk_i(s_clk); i_plic.clk_i(s_clk);
i_aon.clk_i(s_clk); i_aon.clk_i(s_clk);
i_prci.clk_i(s_clk); i_prci.clk_i(s_clk);
@ -66,8 +72,10 @@ platform::platform(sc_core::sc_module_name nm)
i_uart0.rst_i(s_rst); i_uart0.rst_i(s_rst);
i_uart1.rst_i(s_rst); i_uart1.rst_i(s_rst);
i_spi.rst_i(s_rst); i_qspi0.rst_i(s_rst);
i_gpio.rst_i(s_rst); i_qspi1.rst_i(s_rst);
i_qspi2.rst_i(s_rst);
i_gpio0.rst_i(s_rst);
i_plic.rst_i(s_rst); i_plic.rst_i(s_rst);
i_aon.rst_i(s_rst); i_aon.rst_i(s_rst);
i_prci.rst_i(s_rst); i_prci.rst_i(s_rst);
@ -79,6 +87,14 @@ platform::platform(sc_core::sc_module_name nm)
i_plic.global_interrupts_i(s_global_int); i_plic.global_interrupts_i(s_global_int);
i_plic.core_interrupt_o(s_core_int); i_plic.core_interrupt_o(s_core_int);
i_core_complex.sw_irq_i(s_msie_int);
i_core_complex.timer_irq_i(s_mtime_int);
i_core_complex.global_irq_i(s_core_int);
i_core_complex.local_irq_i(s_local_int);
i_gpio0.pins_io(s_gpio_pins);
SC_THREAD(gen_reset); SC_THREAD(gen_reset);
} }

View File

@ -64,7 +64,9 @@ void plic::init_callbacks() {
}; };
} }
void plic::clock_cb() { this->clk = clk_i.read(); } void plic::clock_cb() {
this->clk = clk_i.read();
}
void plic::reset_cb() { void plic::reset_cb() {
if (rst_i.read()) if (rst_i.read())
@ -92,14 +94,13 @@ void plic::reset_cb() {
void plic::global_int_port_cb() { void plic::global_int_port_cb() {
// set related pending bit if enable is set for incoming global_interrupt // set related pending bit if enable is set for incoming global_interrupt
for (uint32_t i = 1; i < 256; i++) {
// todo: extend up to 255 bits (limited to 32 right now) auto reg_idx = i>>5;
for (uint32_t i = 1; i < 32; i++) { auto bit_ofs = i & 0x1F;
uint32_t enable_bits = regs->r_enabled; bool enable = regs->r_enabled[reg_idx] & (0x1 << bit_ofs); // read enable bit
bool enable = enable_bits & (0x1 << i); // read enable bit
if (enable && global_interrupts_i[i].read() == 1) { if (enable && global_interrupts_i[i].read() == 1) {
regs->r_pending = regs->r_pending | (0x1 << i); regs->r_pending[reg_idx] = regs->r_pending[reg_idx] | (0x1 << bit_ofs);
LOG(DEBUG) << "pending interrupt identified: " << i; LOG(DEBUG) << "pending interrupt identified: " << i;
} }
} }
@ -114,14 +115,14 @@ void plic::handle_pending_int() {
bool raise_int = 0; bool raise_int = 0;
uint32_t thold = regs->r_threshold.threshold; // threshold value uint32_t thold = regs->r_threshold.threshold; // threshold value
// todo: extend up to 255 bits (limited to 32 right now) for (uint32_t i = 1; i < 255; i++) {
for (uint32_t i = 1; i < 32; i++) { auto reg_idx = i>>5;
uint32_t pending_bits = regs->r_pending; auto bit_ofs = i & 0x1F;
bool pending = (pending_bits & (0x1 << i)) ? true : false; bool pending = (regs->r_pending[reg_idx] & (0x1 << bit_ofs)) ? true : false;
uint32_t prio = regs->r_priority[i - 1].priority; // read priority value uint32_t prio = regs->r_priority[i - 1].priority; // read priority value
if (pending && thold < prio) { if (pending && thold < prio) {
regs->r_pending = regs->r_pending | (0x1 << i); regs->r_pending[reg_idx] = regs->r_pending[reg_idx] | (0x1 << bit_ofs);
// below condition ensures implicitly that lowest id is selected in case of multiple identical // below condition ensures implicitly that lowest id is selected in case of multiple identical
// priority-interrupts // priority-interrupts
if (prio > claim_prio) { if (prio > claim_prio) {
@ -148,7 +149,9 @@ void plic::reset_pending_int(uint32_t irq) {
// todo: make sure that pending is set, otherwise don't reset irq ... read spec. // todo: make sure that pending is set, otherwise don't reset irq ... read spec.
LOG(INFO) << "reset pending interrupt: " << irq; LOG(INFO) << "reset pending interrupt: " << irq;
// reset related pending bit // reset related pending bit
regs->r_pending &= ~(0x1 << irq); auto reg_idx = irq>>5;
auto bit_ofs = irq & 0x1F;
regs->r_pending[reg_idx] &= ~(0x1 << bit_ofs);
core_interrupt_o.write(0); core_interrupt_o.write(0);
// evaluate next pending interrupt // evaluate next pending interrupt

View File

@ -54,7 +54,10 @@ prci::prci(sc_core::sc_module_name nm)
}); });
} }
void prci::clock_cb() {} void prci::clock_cb() {
this->clk = clk_i.read();
}
prci::~prci() {} prci::~prci() {}

View File

@ -0,0 +1,153 @@
/*
* sc_singleton.cpp
*
* Created on: 09.10.2017
* Author: eyck
*/
#include "sysc/sc_comm_singleton.h"
#include "seasocks/PrintfLogger.h"
#include "seasocks/Server.h"
#include "seasocks/StringUtil.h"
#include "seasocks/util/Json.h"
#include "seasocks/ResponseWriter.h"
#include "seasocks/util/RootPageHandler.h"
#include "seasocks/util/CrackedUriPageHandler.h"
#include "seasocks/util/StaticResponseHandler.h"
#include <cstdio>
#include <csignal>
#include <sys/stat.h>
#include <cerrno>
#include <fcntl.h>
#include <unistd.h>
namespace sysc {
using namespace seasocks;
using namespace std;
namespace {
inline void die(){perror(nullptr);exit(errno);}
}
sc_comm_singleton::sc_comm_singleton(sc_core::sc_module_name nm)
: sc_core::sc_module(nm)
, m_serv(new Server(std::make_shared<PrintfLogger>(Logger::Level::WARNING)))
, client_started(false){
m_serv->addPageHandler(std::make_shared<DefaultPageHandler>(*this));
}
sc_comm_singleton::~sc_comm_singleton() {
//Join the thread with the main thread
t.join();
}
void sc_comm_singleton::start_of_simulation() {
//Launch a thread
t=std::thread(&sc_comm_singleton::thread_func, this);
start_client();
}
void sc_comm_singleton::end_of_simulation() {
get_server().terminate();
}
void sc_comm_singleton::start_client() {
if(client_started) return;
std::stringstream ss;
#ifndef WIN32
if(fork()==0){
// daemonizing, see http://www.microhowto.info/howto/cause_a_process_to_become_a_daemon_in_c.html#id2407077
// Fork, allowing the parent process to terminate.
pid_t pid = fork();
if (pid == -1) {
die();
} else if (pid != 0) {
_exit(0);
}
// Start a new session for the daemon.
if (setsid()==-1) die();
// Fork again, allowing the parent process to terminate.
signal(SIGHUP,SIG_IGN);
pid=fork();
if (pid == -1) {
die();
} else if (pid != 0) {
_exit(0);
}
// Set the current working directory to the root directory.
if (chdir("/") == -1) die();
// Set the user file creation mask to zero.
umask(0);
// Close then reopen standard file descriptors.
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
if (open("/dev/null",O_RDONLY) == -1) die();
if (open("/dev/null",O_WRONLY) == -1) die();
if (open("/dev/null",O_RDWR) == -1) die();
// now do what is needed
ss<<"x-www-browser http://localhost:9090/ws.html"; //Linux
auto res = system (ss.str().c_str());
if(res==0) exit(0);
ss.str("");
ss<<"xdg-open http://localhost:9090/ws.html"; // Linux
res=system (ss.str().c_str());
if(res==0) exit(0);
ss.str("");
ss<<"open http://localhost:9090/ws.html"; // MacOS
res=system (ss.str().c_str());
exit(0);
}
// #else
// on windows should be open, see https://www.experts-exchange.com/articles/1595/Execute-a-Program-with-C.html
#endif
client_started=true;
}
void sc_comm_singleton::registerWebSocketHandler(const char* endpoint,
std::shared_ptr<WebSocket::Handler> handler,
bool allowCrossOriginRequests) {
get_server().addWebSocketHandler(endpoint, handler, allowCrossOriginRequests);
}
void sc_comm_singleton::execute(std::function<void()> f) {
get_server().execute(f);
}
void sc_comm_singleton::thread_func() {
get_server().serve("./html", 9090);
}
Server& sc_comm_singleton::get_server() {
return *m_serv.get();
}
std::shared_ptr<Response> sc_comm_singleton::DefaultPageHandler::handle(const Request& request) {
if(request.verb() == Request::Verb::Get && request.getRequestUri()=="conf.json"){
return Response::htmlResponse("{}");
}
return Response::unhandled();
}
void WsHandler::onConnect(WebSocket* connection) {
_connections.insert(connection);
//connection->send("Connection established");;
}
void WsHandler::onData(WebSocket* connection, const char* data) {
if (0 == strcmp("close", data)) {
connection->close();
} else if(callback)
callback(data);
}
void WsHandler::onDisconnect(WebSocket* connection) {
_connections.erase(connection);
}
} /* namespace sysc */

View File

@ -1,57 +0,0 @@
/*
* sc_singleton.cpp
*
* Created on: 09.10.2017
* Author: eyck
*/
#include "sysc/sc_singleton.h"
#include "seasocks/PrintfLogger.h"
#include "seasocks/Server.h"
#include "seasocks/StringUtil.h"
#include "seasocks/util/Json.h"
#include "seasocks/ResponseWriter.h"
#include "seasocks/util/RootPageHandler.h"
#include "seasocks/util/CrackedUriPageHandler.h"
#include "seasocks/util/StaticResponseHandler.h"
namespace sysc {
using namespace seasocks;
using namespace std;
namespace {
const std::string MSG_TXT { "Hello World"};
}
void sc_singleton::start_of_simulation() {
//Launch a thread
t=std::thread(&sc_singleton::thread_func, this);
}
sc_singleton::sc_singleton(sc_core::sc_module_name nm)
: sc_core::sc_module(nm)
, m_serv(new seasocks::Server(std::make_shared<PrintfLogger>(Logger::Level::DEBUG))){
auto rootHandler = make_shared<seasocks::RootPageHandler>();
rootHandler->add(std::shared_ptr<CrackedUriPageHandler>(new StaticResponseHandler("/", Response::textResponse(MSG_TXT))));
m_serv->addPageHandler(rootHandler);
}
sc_singleton::~sc_singleton() {
//Join the thread with the main thread
t.join();
}
void sc_singleton::thread_func() {
get_server().serve(".", 9090);
}
seasocks::Server& sc_singleton::get_server() {
return *m_serv.get();
}
} /* namespace sysc */

View File

@ -37,7 +37,9 @@ spi::spi(sc_core::sc_module_name nm)
spi::~spi() {} spi::~spi() {}
void spi::clock_cb() { this->clk = clk_i.read(); } void spi::clock_cb() {
this->clk = clk_i.read();
}
void spi::reset_cb() { void spi::reset_cb() {
if (rst_i.read()) if (rst_i.read())

View File

@ -16,76 +16,19 @@
#include "sysc/SiFive/uart.h" #include "sysc/SiFive/uart.h"
#include "sysc/sc_comm_singleton.h"
#include "scc/report.h" #include "scc/report.h"
#include "scc/utilities.h" #include "scc/utilities.h"
#include "sysc/SiFive/gen/uart_regs.h" #include "sysc/SiFive/gen/uart_regs.h"
#include "sysc/sc_singleton.h"
#include "seasocks/PrintfLogger.h" using namespace std;
#include "seasocks/Server.h"
#include "seasocks/StringUtil.h"
#include "seasocks/WebSocket.h"
#include "seasocks/util/Json.h"
namespace sysc { namespace sysc {
namespace { namespace {
using namespace seasocks; using namespace seasocks;
class MyHandler: public WebSocket::Handler {
public:
explicit MyHandler(Server* server) : _server(server), _currentValue(0) {
setValue(1);
}
virtual void onConnect(WebSocket* connection) {
_connections.insert(connection);
connection->send(_currentSetValue.c_str());
cout << "Connected: " << connection->getRequestUri()
<< " : " << formatAddress(connection->getRemoteAddress())
<< endl;
cout << "Credentials: " << *(connection->credentials()) << endl;
}
virtual void onData(WebSocket* connection, const char* data) {
if (0 == strcmp("die", data)) {
_server->terminate();
return;
}
if (0 == strcmp("close", data)) {
cout << "Closing.." << endl;
connection->close();
cout << "Closed." << endl;
return;
}
int value = atoi(data) + 1;
if (value > _currentValue) {
setValue(value);
for (auto c : _connections) {
c->send(_currentSetValue.c_str());
}
}
}
virtual void onDisconnect(WebSocket* connection) {
_connections.erase(connection);
cout << "Disconnected: " << connection->getRequestUri()
<< " : " << formatAddress(connection->getRemoteAddress())
<< endl;
}
private:
set<WebSocket*> _connections;
Server* _server;
int _currentValue;
string _currentSetValue;
void setValue(int value) {
_currentValue = value;
_currentSetValue = makeExecString("set", _currentValue);
}
};
} }
uart::uart(sc_core::sc_module_name nm) uart::uart(sc_core::sc_module_name nm)
@ -107,15 +50,16 @@ uart::uart(sc_core::sc_module_name nm)
} }
return true; return true;
}); });
auto& server = sc_singleton::inst().get_server(); LOG(TRACE)<<"Adding WS handler for "<<(std::string{"/ws/"}+name());
auto handler = std::make_shared<MyHandler>(&server); handler=std::make_shared<WsHandler>();
server.addWebSocketHandler((std::string{"/ws/"}+name()).c_str(), handler); sc_comm_singleton::inst().registerWebSocketHandler((std::string{"/ws/"}+name()).c_str(), handler);
} }
uart::~uart() {} uart::~uart() {}
void uart::clock_cb() { this->clk = clk_i.read(); } void uart::clock_cb() {
this->clk = clk_i.read();
}
void uart::reset_cb() { void uart::reset_cb() {
if (rst_i.read()) if (rst_i.read())
@ -127,7 +71,14 @@ void uart::reset_cb() {
void uart::transmit_data() { void uart::transmit_data() {
if(regs->r_txdata.data != '\r') queue.push_back(regs->r_txdata.data); if(regs->r_txdata.data != '\r') queue.push_back(regs->r_txdata.data);
if (queue.size() >> 0 && (regs->r_txdata.data == '\n' || regs->r_txdata.data == 0)) { if (queue.size() >> 0 && (regs->r_txdata.data == '\n' || regs->r_txdata.data == 0)) {
LOG(INFO) << this->name() << " transmit: '" << std::string(queue.begin(), queue.end()) << "'"; std::string msg(queue.begin(), queue.end()-1);
LOG(INFO) << this->name() << " transmit: '" << msg << "'";
sc_core::sc_time now = sc_core::sc_time_stamp();
sc_comm_singleton::inst().execute([this, msg, now](){
std::stringstream os;
os << "{\"time\":\"" << now << "\",\"message\":\""<<msg<<"\"}";
this->handler->send(os.str());
});
queue.clear(); queue.clear();
} }
} }

View File

@ -161,22 +161,22 @@ namespace {
const char lvl[] = {'U', 'S', 'H', 'M'}; const char lvl[] = {'U', 'S', 'H', 'M'};
const char *trap_str[] = {"Instruction address misaligned", const char *trap_str[] = {"Instruction address misaligned", //0
"Instruction access fault", "Instruction access fault", //1
"Illegal instruction", "Illegal instruction", //2
"Breakpoint", "Breakpoint", //3
"Load address misaligned", "Load address misaligned", //4
"Load access fault", "Load access fault", //5
"Store/AMO address misaligned", "Store/AMO address misaligned", //6
"Store/AMO access fault", "Store/AMO access fault", //7
"Environment call from U-mode", "Environment call from U-mode", //8
"Environment call from S-mode", "Environment call from S-mode", //9
"Reserved", "Reserved", //a
"Environment call from M-mode", "Environment call from M-mode", //b
"Instruction page fault", "Instruction page fault", //c
"Load page fault", "Load page fault", //d
"Reserved", "Reserved", //e
"Store/AMO page fault"}; "Store/AMO page fault"}; //f
const char *irq_str[] = { const char *irq_str[] = {
"User software interrupt", "Supervisor software interrupt", "Reserved", "Machine software interrupt", "User software interrupt", "Supervisor software interrupt", "Reserved", "Machine software interrupt",
"User timer interrupt", "Supervisor timer interrupt", "Reserved", "Machine timer interrupt", "User timer interrupt", "Supervisor timer interrupt", "Reserved", "Machine timer interrupt",
@ -479,6 +479,7 @@ private:
iss::status write_ip(unsigned addr, reg_t val); iss::status write_ip(unsigned addr, reg_t val);
iss::status read_satp(unsigned addr, reg_t &val); iss::status read_satp(unsigned addr, reg_t &val);
iss::status write_satp(unsigned addr, reg_t val); iss::status write_satp(unsigned addr, reg_t val);
protected:
void check_interrupt(); void check_interrupt();
}; };
@ -682,7 +683,7 @@ iss::status riscv_hart_msu_vp<BASE>::write(const iss::addr_t &addr, unsigned len
} }
phys_addr_t paddr = (addr.type & iss::ADDRESS_TYPE) == iss::PHYSICAL ? addr : v2p(addr); phys_addr_t paddr = (addr.type & iss::ADDRESS_TYPE) == iss::PHYSICAL ? addr : v2p(addr);
auto res = write_mem(paddr, length, data); auto res = write_mem(paddr, length, data);
if (res != iss::Ok) this->reg.trap_state = (1 << 31) | (7 << 16); // issue trap 7 (load access fault if (res != iss::Ok) this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 7 (Store/AMO access fault)
return res; return res;
} catch (trap_access &ta) { } catch (trap_access &ta) {
this->reg.trap_state = (1 << 31) | ta.id; this->reg.trap_state = (1 << 31) | ta.id;
@ -848,6 +849,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_ip(unsigned
auto req_priv_lvl = addr >> 8; auto req_priv_lvl = addr >> 8;
if (this->reg.machine_state < req_priv_lvl) throw illegal_instruction_fault(this->fault_data); if (this->reg.machine_state < req_priv_lvl) throw illegal_instruction_fault(this->fault_data);
auto mask = get_irq_mask(req_priv_lvl); auto mask = get_irq_mask(req_priv_lvl);
mask &= ~(1<<7); // MTIP is read only
csr[mip] = (csr[mip] & ~mask) | (val & mask); csr[mip] = (csr[mip] & ~mask) | (val & mask);
check_interrupt(); check_interrupt();
return iss::Ok; return iss::Ok;
@ -1142,7 +1144,8 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::enter_trap(uint64_t f
csr[uepc | (new_priv << 8)] = this->reg.NEXT_PC; // store next address if interrupt csr[uepc | (new_priv << 8)] = this->reg.NEXT_PC; // store next address if interrupt
this->reg.pending_trap = 0; this->reg.pending_trap = 0;
} }
csr[ucause | (new_priv << 8)] = cause; size_t adr=ucause | (new_priv << 8);
csr[adr] = (trap_id<<31)+cause;
// update mstatus // update mstatus
// xPP field of mstatus is written with the active privilege mode at the time // xPP field of mstatus is written with the active privilege mode at the time
// of the trap; the x PIE field of mstatus // of the trap; the x PIE field of mstatus
@ -1177,8 +1180,8 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::enter_trap(uint64_t f
this->reg.trap_state = 0; this->reg.trap_state = 0;
char buffer[32]; char buffer[32];
sprintf(buffer, "0x%016lx", addr); sprintf(buffer, "0x%016lx", addr);
CLOG(INFO, disass) << (trap_id ? "Interrupt " : "Trap ") << " with cause '" << (trap_id ? irq_str[cause] : trap_str[cause]) CLOG(INFO, disass) << (trap_id ? "Interrupt" : "Trap") << " with cause '" << (trap_id ? irq_str[cause] : trap_str[cause])<<"' ("<<trap_id<<")"
<< "' at address " << buffer << " occurred, changing privilege level from " << lvl[cur_priv] << " at address " << buffer << " occurred, changing privilege level from " << lvl[cur_priv]
<< " to " << lvl[new_priv]; << " to " << lvl[new_priv];
return this->reg.NEXT_PC; return this->reg.NEXT_PC;
} }

@ -1 +1 @@
Subproject commit 30ebb87f7683ebd65c7545e9dd341f1ccb1d26b5 Subproject commit 174e0f55f11fa932c88b99e352e5e9b58cb9ce71