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