Compare commits
5 Commits
e382217e04
...
Trace_enha
Author | SHA1 | Date | |
---|---|---|---|
1720bd4aaa | |||
df16378605 | |||
1438f0f373 | |||
766f3ba9ee | |||
5da4e6b424 |
@ -314,11 +314,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|||||||
<%}}%>// calculate next pc value
|
<%}}%>// calculate next pc value
|
||||||
*NEXT_PC = *PC + ${instr.length/8};
|
*NEXT_PC = *PC + ${instr.length/8};
|
||||||
// execute instruction
|
// execute instruction
|
||||||
try {
|
|
||||||
<%instr.behavior.eachLine{%>${it}
|
<%instr.behavior.eachLine{%>${it}
|
||||||
<%}%>} catch(...){}
|
<%}%>TRAP_${instr.name}:break;
|
||||||
}
|
}// @suppress("No break at end of case")<%}%>
|
||||||
break;<%}%>
|
|
||||||
default: {
|
default: {
|
||||||
*NEXT_PC = *PC + ((instr & 3) == 3 ? 4 : 2);
|
*NEXT_PC = *PC + ((instr & 3) == 3 ? 4 : 2);
|
||||||
raise(0, 2);
|
raise(0, 2);
|
||||||
|
@ -567,22 +567,22 @@ iss::status riscv_hart_m_p<BASE, FEAT>::read(const address_type type, const acce
|
|||||||
try {
|
try {
|
||||||
switch (space) {
|
switch (space) {
|
||||||
case traits<BASE>::MEM: {
|
case traits<BASE>::MEM: {
|
||||||
if (unlikely((access == iss::access_type::FETCH || access == iss::access_type::DEBUG_FETCH) && (addr & 0x1) == 1)) {
|
auto alignment = is_fetch(access)? (traits<BASE>::MISA_VAL&0x100? 2 : 4) : length;
|
||||||
|
if (unlikely(is_fetch(access) && (addr&(alignment-1)))) {
|
||||||
fault_data = addr;
|
fault_data = addr;
|
||||||
if (access && iss::access_type::DEBUG) throw trap_access(0, addr);
|
if (is_debug(access)) throw trap_access(0, addr);
|
||||||
this->trap_state = (1 << 31); // issue trap 0
|
this->trap_state = (1 << 31); // issue trap 0
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
auto alignment = access == iss::access_type::FETCH? (traits<BASE>::MISA_VAL&0x100? 2 : 4) : length;
|
if(!is_debug(access) && (addr&(alignment-1))){
|
||||||
if(alignment>1 && (addr&(alignment-1))){
|
|
||||||
this->trap_state = 1<<31 | 4<<16;
|
this->trap_state = 1<<31 | 4<<16;
|
||||||
fault_data=addr;
|
fault_data=addr;
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
auto phys_addr = type==iss::address_type::PHYSICAL?phys_addr_t{access, space, addr}:BASE::v2p(iss::addr_t{access, type, space, addr});
|
auto phys_addr = type==iss::address_type::PHYSICAL?phys_addr_t{access, space, addr}:BASE::v2p(iss::addr_t{access, type, space, addr});
|
||||||
auto res = iss::Err;
|
auto res = iss::Err;
|
||||||
if(access != access_type::FETCH && memfn_range.size()){
|
if(!is_fetch(access) && memfn_range.size()){
|
||||||
auto it = std::find_if(std::begin(memfn_range), std::end(memfn_range), [phys_addr](std::tuple<uint64_t, uint64_t> const& a){
|
auto it = std::find_if(std::begin(memfn_range), std::end(memfn_range), [phys_addr](std::tuple<uint64_t, uint64_t> const& a){
|
||||||
return std::get<0>(a)<=phys_addr.val && (std::get<0>(a)+std::get<1>(a))>phys_addr.val;
|
return std::get<0>(a)<=phys_addr.val && (std::get<0>(a)+std::get<1>(a))>phys_addr.val;
|
||||||
});
|
});
|
||||||
|
@ -611,13 +611,19 @@ iss::status riscv_hart_msu_vp<BASE>::read(const address_type type, const access_
|
|||||||
try {
|
try {
|
||||||
switch (space) {
|
switch (space) {
|
||||||
case traits<BASE>::MEM: {
|
case traits<BASE>::MEM: {
|
||||||
if (unlikely((access == iss::access_type::FETCH || access == iss::access_type::DEBUG_FETCH) && (addr & 0x1) == 1)) {
|
auto alignment = is_fetch(access)? (traits<BASE>::MISA_VAL&0x100? 2 : 4) : length;
|
||||||
|
if (unlikely(is_fetch(access) && (addr&(alignment-1)))) {
|
||||||
fault_data = addr;
|
fault_data = addr;
|
||||||
if (access && iss::access_type::DEBUG) throw trap_access(0, addr);
|
if (access && iss::access_type::DEBUG) throw trap_access(0, addr);
|
||||||
this->trap_state = (1 << 31); // issue trap 0
|
this->trap_state = (1 << 31); // issue trap 0
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
if(!is_debug(access) && (addr&(alignment-1))){
|
||||||
|
this->trap_state = 1<<31 | 4<<16;
|
||||||
|
fault_data=addr;
|
||||||
|
return iss::Err;
|
||||||
|
}
|
||||||
if (unlikely((addr & ~PGMASK) != ((addr + length - 1) & ~PGMASK))) { // we may cross a page boundary
|
if (unlikely((addr & ~PGMASK) != ((addr + length - 1) & ~PGMASK))) { // we may cross a page boundary
|
||||||
vm_info vm = hart_state_type::decode_vm_info(this->reg.PRIV, state.satp);
|
vm_info vm = hart_state_type::decode_vm_info(this->reg.PRIV, state.satp);
|
||||||
if (vm.levels != 0) { // VM is active
|
if (vm.levels != 0) { // VM is active
|
||||||
|
@ -705,22 +705,22 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::read(const address_type type, const acc
|
|||||||
switch (space) {
|
switch (space) {
|
||||||
case traits<BASE>::MEM: {
|
case traits<BASE>::MEM: {
|
||||||
if(FEAT & FEAT_PMP){
|
if(FEAT & FEAT_PMP){
|
||||||
if(!pmp_check(access, addr, length) && (access&access_type::DEBUG) != access_type::DEBUG) {
|
if(!pmp_check(access, addr, length) && !is_debug(access)) {
|
||||||
fault_data = addr;
|
fault_data = addr;
|
||||||
if (access && iss::access_type::DEBUG) throw trap_access(0, addr);
|
if (is_debug(access)) throw trap_access(0, addr);
|
||||||
this->trap_state = (1 << 31) | ((access==access_type::FETCH?1:5) << 16); // issue trap 1
|
this->trap_state = (1 << 31) | ((access==access_type::FETCH?1:5) << 16); // issue trap 1
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (unlikely((access == iss::access_type::FETCH || access == iss::access_type::DEBUG_FETCH) && (addr & 0x1) == 1)) {
|
auto alignment = is_fetch(access)? (traits<BASE>::MISA_VAL&0x100? 2 : 4) : length;
|
||||||
|
if (unlikely(is_fetch(access) && (addr&(alignment-1)))) {
|
||||||
fault_data = addr;
|
fault_data = addr;
|
||||||
if (access && iss::access_type::DEBUG) throw trap_access(0, addr);
|
if (is_debug(access)) throw trap_access(0, addr);
|
||||||
this->trap_state = (1 << 31); // issue trap 0
|
this->trap_state = (1 << 31); // issue trap 0
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
auto alignment = access == iss::access_type::FETCH? (traits<BASE>::MISA_VAL&0x100? 2 : 4) : length;
|
if(!is_debug(access) && (addr&(alignment-1))){
|
||||||
if(alignment>1 && (addr&(alignment-1))){
|
|
||||||
this->trap_state = 1<<31 | 4<<16;
|
this->trap_state = 1<<31 | 4<<16;
|
||||||
fault_data=addr;
|
fault_data=addr;
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
|
@ -81,7 +81,7 @@ public:
|
|||||||
void callback(instr_info_t instr_info, exec_info const&) override;
|
void callback(instr_info_t instr_info, exec_info const&) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
iss::instrumentation_if *arch_instr;
|
iss::instrumentation_if *instr_if;
|
||||||
std::vector<instr_desc> delays;
|
std::vector<instr_desc> delays;
|
||||||
struct pair_hash {
|
struct pair_hash {
|
||||||
size_t operator()(const std::pair<uint64_t, uint64_t> &p) const {
|
size_t operator()(const std::pair<uint64_t, uint64_t> &p) const {
|
||||||
|
@ -48,7 +48,7 @@ using namespace rapidjson;
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
iss::plugin::cycle_estimate::cycle_estimate(string const& config_file_name)
|
iss::plugin::cycle_estimate::cycle_estimate(string const& config_file_name)
|
||||||
: arch_instr(nullptr)
|
: instr_if(nullptr)
|
||||||
, config_file_name(config_file_name)
|
, config_file_name(config_file_name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -57,9 +57,9 @@ iss::plugin::cycle_estimate::~cycle_estimate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if& vm) {
|
bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if& vm) {
|
||||||
arch_instr = vm.get_arch()->get_instrumentation_if();
|
instr_if = vm.get_arch()->get_instrumentation_if();
|
||||||
if(!arch_instr) return false;
|
if(!instr_if) return false;
|
||||||
const string core_name = arch_instr->core_type_name();
|
const string core_name = instr_if->core_type_name();
|
||||||
if (config_file_name.length() > 0) {
|
if (config_file_name.length() > 0) {
|
||||||
ifstream is(config_file_name);
|
ifstream is(config_file_name);
|
||||||
if (is.is_open()) {
|
if (is.is_open()) {
|
||||||
@ -108,11 +108,11 @@ bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if&
|
|||||||
}
|
}
|
||||||
|
|
||||||
void iss::plugin::cycle_estimate::callback(instr_info_t instr_info, exec_info const& exc_info) {
|
void iss::plugin::cycle_estimate::callback(instr_info_t instr_info, exec_info const& exc_info) {
|
||||||
assert(arch_instr && "No instrumentation interface available but callback executed");
|
assert(instr_if && "No instrumentation interface available but callback executed");
|
||||||
auto entry = delays[instr_info.instr_id];
|
auto entry = delays[instr_info.instr_id];
|
||||||
bool taken = exc_info.branch_taken;
|
bool taken = exc_info.branch_taken;
|
||||||
if (exc_info.branch_taken && (entry.taken > 1))
|
if (exc_info.branch_taken && (entry.taken > 1))
|
||||||
arch_instr->set_curr_instr_cycles(entry.taken);
|
instr_if->set_curr_instr_cycles(entry.taken);
|
||||||
else if (entry.not_taken > 1)
|
else if (entry.not_taken > 1)
|
||||||
arch_instr->set_curr_instr_cycles(entry.not_taken);
|
instr_if->set_curr_instr_cycles(entry.not_taken);
|
||||||
}
|
}
|
||||||
|
@ -58,10 +58,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
int_type overflow(int_type ch) override {
|
int_type overflow(int_type ch) override {
|
||||||
assert(pptr() > epptr());
|
compress_and_write();
|
||||||
*pptr() = static_cast<char_type>(ch);
|
*pptr() = static_cast<char_type>(ch);
|
||||||
pbump(1);
|
pbump(1);
|
||||||
compress_and_write();
|
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,17 +157,23 @@ void cov::callback(instr_info_t iinfo, const exec_info& einfo) {
|
|||||||
size_t id = iinfo.instr_id;
|
size_t id = iinfo.instr_id;
|
||||||
auto entry = delays[id];
|
auto entry = delays[id];
|
||||||
auto instr = instr_if->get_instr_word();
|
auto instr = instr_if->get_instr_word();
|
||||||
auto call = (id==2 || id==3) && bit_sub<7,5>(instr)!=0;
|
auto call = id==65 || id ==86 || ((id==2 || id==3) && bit_sub<7,5>(instr)!=0) ;//not taking care of tail calls (jalr with loading x6)
|
||||||
bool taken = einfo.branch_taken;
|
bool taken = einfo.branch_taken;
|
||||||
if (einfo.branch_taken)
|
bool compressed = (instr&0x3)!=0x3;
|
||||||
|
if (einfo.branch_taken) {
|
||||||
delay = entry.taken;
|
delay = entry.taken;
|
||||||
else
|
if(entry.taken > 1)
|
||||||
|
instr_if->set_curr_instr_cycles(entry.taken);
|
||||||
|
} else {
|
||||||
delay = entry.not_taken;
|
delay = entry.not_taken;
|
||||||
|
if (entry.not_taken > 1)
|
||||||
|
instr_if->set_curr_instr_cycles(entry.not_taken);
|
||||||
|
}
|
||||||
#ifndef WITH_LZ4
|
#ifndef WITH_LZ4
|
||||||
output<<std::hex <<"0x" << instr_if->get_pc() <<"," << delay <<"," << call<< "\n";
|
output<<std::hex <<"0x" << instr_if->get_pc() <<"," << delay <<"," << call<<","<<(compressed?2:4) <<"\n";
|
||||||
#else
|
#else
|
||||||
auto rdbuf=ostr.rdbuf();
|
auto rdbuf=ostr.rdbuf();
|
||||||
ostr<<std::hex <<"0x" << instr_if->get_pc() <<"," << delay <<"," << call<< "\n";
|
ostr<<std::hex <<"0x" << instr_if->get_pc() <<"," << delay <<"," << call<<","<<(compressed?2:4) <<"\n";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user