Compare commits
	
		
			2 Commits
		
	
	
		
			0996d15bd4
			...
			9de0aed84d
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 9de0aed84d | |||
| bb4e2766d1 | 
| @@ -204,7 +204,7 @@ private: | |||||||
|             }; |             }; | ||||||
|             this->builder.CreateCall(this->mod->getFunction("print_disass"), args); |             this->builder.CreateCall(this->mod->getFunction("print_disass"), args); | ||||||
|         } |         } | ||||||
| 		this->gen_sync(iss::PRE_SYNC, instr_descr.size()); |         this->gen_sync(iss::PRE_SYNC, instr_descr.size()); | ||||||
|         this->builder.CreateStore(this->builder.CreateLoad(this->get_typeptr(traits::NEXT_PC), get_reg_ptr(traits::NEXT_PC), true), |         this->builder.CreateStore(this->builder.CreateLoad(this->get_typeptr(traits::NEXT_PC), get_reg_ptr(traits::NEXT_PC), true), | ||||||
|                                    get_reg_ptr(traits::PC), true); |                                    get_reg_ptr(traits::PC), true); | ||||||
|         this->builder.CreateStore( |         this->builder.CreateStore( | ||||||
|   | |||||||
| @@ -602,7 +602,7 @@ std::pair<uint64_t, bool> riscv_hart_m_p<BASE, FEAT, LOGCAT>::load_file(std::str | |||||||
|             if(reader.get_machine() != EM_RISCV) |             if(reader.get_machine() != EM_RISCV) | ||||||
|                 throw std::runtime_error("wrong elf machine in file"); |                 throw std::runtime_error("wrong elf machine in file"); | ||||||
|             auto entry = reader.get_entry(); |             auto entry = reader.get_entry(); | ||||||
|             for(const auto pseg : reader.segments) { |             for(const auto& pseg : reader.segments) { | ||||||
|                 const auto fsize = pseg->get_file_size(); // 0x42c/0x0 |                 const auto fsize = pseg->get_file_size(); // 0x42c/0x0 | ||||||
|                 const auto seg_data = pseg->get_data(); |                 const auto seg_data = pseg->get_data(); | ||||||
|                 const auto type = pseg->get_type(); |                 const auto type = pseg->get_type(); | ||||||
| @@ -689,7 +689,7 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read(const address_type type, co | |||||||
|                 } |                 } | ||||||
|                 return res; |                 return res; | ||||||
|             } catch(trap_access& ta) { |             } catch(trap_access& ta) { | ||||||
|                 if( (access & access_type::DEBUG) == 0) { |                 if((access & access_type::DEBUG) == 0) { | ||||||
|                     this->reg.trap_state = (1UL << 31) | ta.id; |                     this->reg.trap_state = (1UL << 31) | ta.id; | ||||||
|                     fault_data = ta.addr; |                     fault_data = ta.addr; | ||||||
|                 } |                 } | ||||||
|   | |||||||
| @@ -671,8 +671,10 @@ iss::status riscv_hart_msu_vp<BASE>::read(const address_type type, const access_ | |||||||
|                 } |                 } | ||||||
|                 return res; |                 return res; | ||||||
|             } catch(trap_access& ta) { |             } catch(trap_access& ta) { | ||||||
|                 this->reg.trap_state = (1 << 31) | ta.id; |                 if((access & access_type::DEBUG) == 0) { | ||||||
|                 fault_data = ta.addr; |                     this->reg.trap_state = (1UL << 31) | ta.id; | ||||||
|  |                     fault_data = ta.addr; | ||||||
|  |                 } | ||||||
|                 return iss::Err; |                 return iss::Err; | ||||||
|             } |             } | ||||||
|         } break; |         } break; | ||||||
| @@ -710,8 +712,10 @@ iss::status riscv_hart_msu_vp<BASE>::read(const address_type type, const access_ | |||||||
|         } |         } | ||||||
|         return iss::Ok; |         return iss::Ok; | ||||||
|     } catch(trap_access& ta) { |     } catch(trap_access& ta) { | ||||||
|         this->reg.trap_state = (1UL << 31) | ta.id; |         if((access & access_type::DEBUG) == 0) { | ||||||
|         fault_data = ta.addr; |             this->reg.trap_state = (1UL << 31) | ta.id; | ||||||
|  |             fault_data = ta.addr; | ||||||
|  |         } | ||||||
|         return iss::Err; |         return iss::Err; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -841,8 +845,10 @@ iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access | |||||||
|         } |         } | ||||||
|         return iss::Ok; |         return iss::Ok; | ||||||
|     } catch(trap_access& ta) { |     } catch(trap_access& ta) { | ||||||
|         this->reg.trap_state = (1UL << 31) | ta.id; |         if((access & access_type::DEBUG) == 0) { | ||||||
|         fault_data = ta.addr; |             this->reg.trap_state = (1UL << 31) | ta.id; | ||||||
|  |             fault_data = ta.addr; | ||||||
|  |         } | ||||||
|         return iss::Err; |         return iss::Err; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -674,7 +674,7 @@ std::pair<uint64_t, bool> riscv_hart_mu_p<BASE, FEAT, LOGCAT>::load_file(std::st | |||||||
|             if(reader.get_machine() != EM_RISCV) |             if(reader.get_machine() != EM_RISCV) | ||||||
|                 throw std::runtime_error("wrong elf machine in file"); |                 throw std::runtime_error("wrong elf machine in file"); | ||||||
|             auto entry = reader.get_entry(); |             auto entry = reader.get_entry(); | ||||||
|             for(const auto pseg : reader.segments) { |             for(const auto& pseg : reader.segments) { | ||||||
|                 const auto fsize = pseg->get_file_size(); // 0x42c/0x0 |                 const auto fsize = pseg->get_file_size(); // 0x42c/0x0 | ||||||
|                 const auto seg_data = pseg->get_data(); |                 const auto seg_data = pseg->get_data(); | ||||||
|                 const auto type = pseg->get_type(); |                 const auto type = pseg->get_type(); | ||||||
| @@ -685,7 +685,7 @@ std::pair<uint64_t, bool> riscv_hart_mu_p<BASE, FEAT, LOGCAT>::load_file(std::st | |||||||
|                         CPPLOG(ERR) << "problem writing " << fsize << "bytes to 0x" << std::hex << pseg->get_physical_address(); |                         CPPLOG(ERR) << "problem writing " << fsize << "bytes to 0x" << std::hex << pseg->get_physical_address(); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             for(const auto sec : reader.sections) { |             for(const auto& sec : reader.sections) { | ||||||
|                 if(sec->get_name() == ".symtab") { |                 if(sec->get_name() == ".symtab") { | ||||||
|                     if(SHT_SYMTAB == sec->get_type() || SHT_DYNSYM == sec->get_type()) { |                     if(SHT_SYMTAB == sec->get_type() || SHT_DYNSYM == sec->get_type()) { | ||||||
|                         ELFIO::symbol_section_accessor symbols(reader, sec); |                         ELFIO::symbol_section_accessor symbols(reader, sec); | ||||||
| @@ -877,8 +877,10 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read(const address_type type, c | |||||||
|                 } |                 } | ||||||
|                 return res; |                 return res; | ||||||
|             } catch(trap_access& ta) { |             } catch(trap_access& ta) { | ||||||
|                 this->reg.trap_state = (1UL << 31) | ta.id; |                 if((access & access_type::DEBUG) == 0) { | ||||||
|                 fault_data = ta.addr; |                     this->reg.trap_state = (1UL << 31) | ta.id; | ||||||
|  |                     fault_data = ta.addr; | ||||||
|  |                 } | ||||||
|                 return iss::Err; |                 return iss::Err; | ||||||
|             } |             } | ||||||
|         } break; |         } break; | ||||||
| @@ -905,8 +907,10 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read(const address_type type, c | |||||||
|         } |         } | ||||||
|         return iss::Ok; |         return iss::Ok; | ||||||
|     } catch(trap_access& ta) { |     } catch(trap_access& ta) { | ||||||
|         this->reg.trap_state = (1UL << 31) | ta.id; |         if((access & access_type::DEBUG) == 0) { | ||||||
|         fault_data = ta.addr; |             this->reg.trap_state = (1UL << 31) | ta.id; | ||||||
|  |             fault_data = ta.addr; | ||||||
|  |         } | ||||||
|         return iss::Err; |         return iss::Err; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -1045,8 +1049,10 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write(const address_type type, | |||||||
|         } |         } | ||||||
|         return iss::Ok; |         return iss::Ok; | ||||||
|     } catch(trap_access& ta) { |     } catch(trap_access& ta) { | ||||||
|         this->reg.trap_state = (1UL << 31) | ta.id; |         if((access & access_type::DEBUG) == 0) { | ||||||
|         fault_data = ta.addr; |             this->reg.trap_state = (1UL << 31) | ta.id; | ||||||
|  |             fault_data = ta.addr; | ||||||
|  |         } | ||||||
|         return iss::Err; |         return iss::Err; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -39,8 +39,6 @@ | |||||||
| #include <iss/iss.h> | #include <iss/iss.h> | ||||||
|  |  | ||||||
| #include <array> | #include <array> | ||||||
| #include <iostream> |  | ||||||
| #include <fstream> |  | ||||||
| #include <memory> | #include <memory> | ||||||
| #ifndef FMT_HEADER_ONLY | #ifndef FMT_HEADER_ONLY | ||||||
| #define FMT_HEADER_ONLY | #define FMT_HEADER_ONLY | ||||||
| @@ -109,7 +107,7 @@ public: | |||||||
|     status process_query(unsigned int& mask, const rp_thread_ref& arg, rp_thread_info& info) override; |     status process_query(unsigned int& mask, const rp_thread_ref& arg, rp_thread_info& info) override; | ||||||
|  |  | ||||||
|     status thread_list_query(int first, const rp_thread_ref& arg, std::vector<rp_thread_ref>& result, size_t max_num, size_t& num, |     status thread_list_query(int first, const rp_thread_ref& arg, std::vector<rp_thread_ref>& result, size_t max_num, size_t& num, | ||||||
|             bool& done) override; |                              bool& done) override; | ||||||
|  |  | ||||||
|     status current_thread_query(rp_thread_ref& thread) override; |     status current_thread_query(rp_thread_ref& thread) override; | ||||||
|  |  | ||||||
| @@ -140,15 +138,11 @@ protected: | |||||||
|     rp_thread_ref thread_idx; |     rp_thread_ref thread_idx; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| template <typename ARCH> | template <typename ARCH> typename std::enable_if<iss::arch::traits<ARCH>::FLEN != 0, unsigned>::type get_f0_offset() { | ||||||
| typename std::enable_if<iss::arch::traits<ARCH>::FLEN!=0, unsigned>::type get_f0_offset() { |  | ||||||
|     return iss::arch::traits<ARCH>::F0; |     return iss::arch::traits<ARCH>::F0; | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename ARCH> | template <typename ARCH> typename std::enable_if<iss::arch::traits<ARCH>::FLEN == 0, unsigned>::type get_f0_offset() { return 0; } | ||||||
| typename std::enable_if<iss::arch::traits<ARCH>::FLEN==0, unsigned>::type get_f0_offset() { |  | ||||||
|     return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| template <typename ARCH> status riscv_target_adapter<ARCH>::set_gen_thread(rp_thread_ref& thread) { | template <typename ARCH> status riscv_target_adapter<ARCH>::set_gen_thread(rp_thread_ref& thread) { | ||||||
|     thread_idx = thread; |     thread_idx = thread; | ||||||
| @@ -197,14 +191,14 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::read_registers(std:: | |||||||
|     auto start_reg = arch::traits<ARCH>::X0; |     auto start_reg = arch::traits<ARCH>::X0; | ||||||
|     for(size_t i = 0; i < 33; ++i) { |     for(size_t i = 0; i < 33; ++i) { | ||||||
|         if(i < arch::traits<ARCH>::RFS || i == arch::traits<ARCH>::PC) { |         if(i < arch::traits<ARCH>::RFS || i == arch::traits<ARCH>::PC) { | ||||||
|             auto reg_no = i<32? start_reg + i: arch::traits<ARCH>::PC; |             auto reg_no = i < 32 ? start_reg + i : arch::traits<ARCH>::PC; | ||||||
|             unsigned offset = traits<ARCH>::reg_byte_offsets[reg_no]; |             unsigned offset = traits<ARCH>::reg_byte_offsets[reg_no]; | ||||||
|             for(size_t j = 0; j < arch::traits<ARCH>::XLEN/8; ++j) { |             for(size_t j = 0; j < arch::traits<ARCH>::XLEN / 8; ++j) { | ||||||
|                 data.push_back(*(reg_base + offset + j)); |                 data.push_back(*(reg_base + offset + j)); | ||||||
|                 avail.push_back(0xff); |                 avail.push_back(0xff); | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             for(size_t j = 0; j < arch::traits<ARCH>::XLEN/8; ++j) { |             for(size_t j = 0; j < arch::traits<ARCH>::XLEN / 8; ++j) { | ||||||
|                 data.push_back(0); |                 data.push_back(0); | ||||||
|                 avail.push_back(0); |                 avail.push_back(0); | ||||||
|             } |             } | ||||||
| @@ -229,15 +223,15 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::write_registers(cons | |||||||
|     auto start_reg = arch::traits<ARCH>::X0; |     auto start_reg = arch::traits<ARCH>::X0; | ||||||
|     auto* reg_base = core->get_regs_base_ptr(); |     auto* reg_base = core->get_regs_base_ptr(); | ||||||
|     auto iter = data.data(); |     auto iter = data.data(); | ||||||
|     auto iter_end = data.data()+data.size(); |     auto iter_end = data.data() + data.size(); | ||||||
|     for(size_t i = 0; i < 33 && iter < iter_end; ++i) { |     for(size_t i = 0; i < 33 && iter < iter_end; ++i) { | ||||||
|         auto reg_width = arch::traits<ARCH>::XLEN / 8; |         auto reg_width = arch::traits<ARCH>::XLEN / 8; | ||||||
|         if(i < arch::traits<ARCH>::RFS) { |         if(i < arch::traits<ARCH>::RFS) { | ||||||
|             auto offset = traits<ARCH>::reg_byte_offsets[start_reg + i]; |             auto offset = traits<ARCH>::reg_byte_offsets[start_reg + i]; | ||||||
|             std::copy(iter, iter + reg_width, reg_base+offset); |             std::copy(iter, iter + reg_width, reg_base + offset); | ||||||
|         } else if(i == 32) { |         } else if(i == 32) { | ||||||
|             auto offset = traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC]; |             auto offset = traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC]; | ||||||
|             std::copy(iter, iter + reg_width, reg_base+offset); |             std::copy(iter, iter + reg_width, reg_base + offset); | ||||||
|         } |         } | ||||||
|         iter += reg_width; |         iter += reg_width; | ||||||
|     } |     } | ||||||
| @@ -246,7 +240,7 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::write_registers(cons | |||||||
|         auto reg_width = arch::traits<ARCH>::FLEN / 8; |         auto reg_width = arch::traits<ARCH>::FLEN / 8; | ||||||
|         for(size_t i = 0; i < 32 && iter < iter_end; ++i) { |         for(size_t i = 0; i < 32 && iter < iter_end; ++i) { | ||||||
|             unsigned offset = traits<ARCH>::reg_byte_offsets[fstart_reg + i]; |             unsigned offset = traits<ARCH>::reg_byte_offsets[fstart_reg + i]; | ||||||
|             std::copy(iter, iter + reg_width, reg_base+offset); |             std::copy(iter, iter + reg_width, reg_base + offset); | ||||||
|             iter += reg_width; |             iter += reg_width; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -255,7 +249,7 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::write_registers(cons | |||||||
|  |  | ||||||
| template <typename ARCH> | template <typename ARCH> | ||||||
| status riscv_target_adapter<ARCH>::read_single_register(unsigned int reg_no, std::vector<uint8_t>& data, std::vector<uint8_t>& avail) { | status riscv_target_adapter<ARCH>::read_single_register(unsigned int reg_no, std::vector<uint8_t>& data, std::vector<uint8_t>& avail) { | ||||||
|     if(reg_no <csr_offset) { |     if(reg_no < csr_offset) { | ||||||
|         // auto reg_size = arch::traits<ARCH>::reg_bit_width(static_cast<typename |         // auto reg_size = arch::traits<ARCH>::reg_bit_width(static_cast<typename | ||||||
|         // arch::traits<ARCH>::reg_e>(reg_no))/8; |         // arch::traits<ARCH>::reg_e>(reg_no))/8; | ||||||
|         auto* reg_base = core->get_regs_base_ptr(); |         auto* reg_base = core->get_regs_base_ptr(); | ||||||
| @@ -349,7 +343,7 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::add_break(break_type | |||||||
|         auto eaddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr + length}); |         auto eaddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr + length}); | ||||||
|         target_adapter_base::bp_lut.addEntry(++target_adapter_base::bp_count, saddr.val, eaddr.val - saddr.val); |         target_adapter_base::bp_lut.addEntry(++target_adapter_base::bp_count, saddr.val, eaddr.val - saddr.val); | ||||||
|         CPPLOG(TRACE) << "Adding breakpoint with handle " << target_adapter_base::bp_count << " for addr 0x" << std::hex << saddr.val |         CPPLOG(TRACE) << "Adding breakpoint with handle " << target_adapter_base::bp_count << " for addr 0x" << std::hex << saddr.val | ||||||
|                 << std::dec; |                       << std::dec; | ||||||
|         CPPLOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints"; |         CPPLOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints"; | ||||||
|         return Ok; |         return Ok; | ||||||
|     } |     } | ||||||
| @@ -379,7 +373,7 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::remove_break(break_t | |||||||
|  |  | ||||||
| template <typename ARCH> | template <typename ARCH> | ||||||
| status riscv_target_adapter<ARCH>::resume_from_addr(bool step, int sig, uint64_t addr, rp_thread_ref thread, | status riscv_target_adapter<ARCH>::resume_from_addr(bool step, int sig, uint64_t addr, rp_thread_ref thread, | ||||||
|         std::function<void(unsigned)> stop_callback) { |                                                     std::function<void(unsigned)> stop_callback) { | ||||||
|     auto* reg_base = core->get_regs_base_ptr(); |     auto* reg_base = core->get_regs_base_ptr(); | ||||||
|     auto reg_width = arch::traits<ARCH>::reg_bit_widths[arch::traits<ARCH>::PC] / 8; |     auto reg_width = arch::traits<ARCH>::reg_bit_widths[arch::traits<ARCH>::PC] / 8; | ||||||
|     auto offset = traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC]; |     auto offset = traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC]; | ||||||
| @@ -398,17 +392,20 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::target_xml_query(std | |||||||
|             oss << "  <architectureriscv:rv64</architecture>\n"; |             oss << "  <architectureriscv:rv64</architecture>\n"; | ||||||
|         oss << "  <feature name=\"org.gnu.gdb.riscv.cpu\">\n"; |         oss << "  <feature name=\"org.gnu.gdb.riscv.cpu\">\n"; | ||||||
|         auto reg_base_num = iss::arch::traits<ARCH>::X0; |         auto reg_base_num = iss::arch::traits<ARCH>::X0; | ||||||
|         for(auto i = 0U; i<iss::arch::traits<ARCH>::RFS; ++i) { |         for(auto i = 0U; i < iss::arch::traits<ARCH>::RFS; ++i) { | ||||||
|             oss << "    <reg name=\"x" << i << "\" bitsize=\"" << iss::arch::traits<ARCH>::reg_bit_widths[reg_base_num + i] << "\" type=\"int\" regnum=\"" << i << "\"/>\n"; |             oss << "    <reg name=\"x" << i << "\" bitsize=\"" << iss::arch::traits<ARCH>::reg_bit_widths[reg_base_num + i] | ||||||
|  |                 << "\" type=\"int\" regnum=\"" << i << "\"/>\n"; | ||||||
|         } |         } | ||||||
|         oss << "    <reg name=\"pc\" bitsize=\"" << iss::arch::traits<ARCH>::reg_bit_widths[iss::arch::traits<ARCH>::PC] << "\" type=\"code_ptr\" regnum=\"" << 32U << "\"/>\n"; |         oss << "    <reg name=\"pc\" bitsize=\"" << iss::arch::traits<ARCH>::reg_bit_widths[iss::arch::traits<ARCH>::PC] | ||||||
|  |             << "\" type=\"code_ptr\" regnum=\"" << 32U << "\"/>\n"; | ||||||
|         oss << "  </feature>\n"; |         oss << "  </feature>\n"; | ||||||
|         if(iss::arch::traits<ARCH>::FLEN > 0) { |         if(iss::arch::traits<ARCH>::FLEN > 0) { | ||||||
|             oss << "  <feature name=\"org.gnu.gdb.riscv.fpu\">\n"; |             oss << "  <feature name=\"org.gnu.gdb.riscv.fpu\">\n"; | ||||||
|             auto reg_base_num =  get_f0_offset<ARCH>(); |             auto reg_base_num = get_f0_offset<ARCH>(); | ||||||
|             auto type = iss::arch::traits<ARCH>::FLEN==32?"ieee_single":"riscv_double"; |             auto type = iss::arch::traits<ARCH>::FLEN == 32 ? "ieee_single" : "riscv_double"; | ||||||
|             for(auto i = 0U; i<32; ++i) { |             for(auto i = 0U; i < 32; ++i) { | ||||||
|                 oss << "    <reg name=\"f" << i << "\" bitsize=\"" << iss::arch::traits<ARCH>::reg_bit_widths[reg_base_num + i] << "\" type=\""<<type<<"\" regnum=\"" << i+33 << "\"/>\n"; |                 oss << "    <reg name=\"f" << i << "\" bitsize=\"" << iss::arch::traits<ARCH>::reg_bit_widths[reg_base_num + i] | ||||||
|  |                     << "\" type=\"" << type << "\" regnum=\"" << i + 33 << "\"/>\n"; | ||||||
|             } |             } | ||||||
|             oss << "    <reg name=\"fcsr\" bitsize=\"" << iss::arch::traits<ARCH>::XLEN << "\" regnum=\"103\" type int/>\n"; |             oss << "    <reg name=\"fcsr\" bitsize=\"" << iss::arch::traits<ARCH>::XLEN << "\" regnum=\"103\" type int/>\n"; | ||||||
|             oss << "    <reg name=\"fflags\" bitsize=\"" << iss::arch::traits<ARCH>::XLEN << "\" regnum=\"101\" type int/>\n"; |             oss << "    <reg name=\"fflags\" bitsize=\"" << iss::arch::traits<ARCH>::XLEN << "\" regnum=\"101\" type int/>\n"; | ||||||
| @@ -420,12 +417,13 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::target_xml_query(std | |||||||
|         std::vector<uint8_t> avail; |         std::vector<uint8_t> avail; | ||||||
|         data.resize(sizeof(typename traits<ARCH>::reg_t)); |         data.resize(sizeof(typename traits<ARCH>::reg_t)); | ||||||
|         avail.resize(sizeof(typename traits<ARCH>::reg_t)); |         avail.resize(sizeof(typename traits<ARCH>::reg_t)); | ||||||
|         for(auto i = 0U; i<4096; ++i) { |         for(auto i = 0U; i < 4096; ++i) { | ||||||
|             typed_addr_t<iss::address_type::PHYSICAL> a(iss::access_type::DEBUG_READ, traits<ARCH>::CSR, i); |             typed_addr_t<iss::address_type::PHYSICAL> a(iss::access_type::DEBUG_READ, traits<ARCH>::CSR, i); | ||||||
|             std::fill(avail.begin(), avail.end(), 0xff); |             std::fill(avail.begin(), avail.end(), 0xff); | ||||||
|             auto res = core->read(a, data.size(), data.data()); |             auto res = core->read(a, data.size(), data.data()); | ||||||
|             if(res == iss::Ok) { |             if(res == iss::Ok) { | ||||||
|                 oss << "    <reg name=\"" << get_csr_name(i) << "\" bitsize=\"" << iss::arch::traits<ARCH>::XLEN << "\"  type=\"int\" regnum=\"" << (i + csr_offset) << "\"/>\n"; |                 oss << "    <reg name=\"" << get_csr_name(i) << "\" bitsize=\"" << iss::arch::traits<ARCH>::XLEN | ||||||
|  |                     << "\"  type=\"int\" regnum=\"" << (i + csr_offset) << "\"/>\n"; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         oss << "  </feature>\n"; |         oss << "  </feature>\n"; | ||||||
|   | |||||||
| @@ -141,7 +141,10 @@ int main(int argc, char* argv[]) { | |||||||
|             std::tie(cpu, vm) = f.create(isa_opt, clim["gdb-port"].as<unsigned>(), &semihosting_cb); |             std::tie(cpu, vm) = f.create(isa_opt, clim["gdb-port"].as<unsigned>(), &semihosting_cb); | ||||||
|         } |         } | ||||||
|         if(!cpu) { |         if(!cpu) { | ||||||
|             CPPLOG(ERR) << "Could not create cpu for isa " << isa_opt << " and backend " << clim["backend"].as<std::string>() << std::endl; |             auto list = f.get_names(); | ||||||
|  |             std::sort(std::begin(list), std::end(list)); | ||||||
|  |             CPPLOG(ERR) << "Could not create cpu for isa " << isa_opt << " and backend " << clim["backend"].as<std::string>() << "\n" | ||||||
|  |                         << "Available implementations (core|platform|backend):\n  - " << util::join(list, "\n  - ") << std::endl; | ||||||
|             return 127; |             return 127; | ||||||
|         } |         } | ||||||
|         if(!vm) { |         if(!vm) { | ||||||
|   | |||||||
| @@ -42,7 +42,6 @@ | |||||||
| #include <iss/plugin/loader.h> | #include <iss/plugin/loader.h> | ||||||
| #endif | #endif | ||||||
| #include "sc_core_adapter_if.h" | #include "sc_core_adapter_if.h" | ||||||
| #include <iss/arch/tgc_mapper.h> |  | ||||||
| #include <scc/report.h> | #include <scc/report.h> | ||||||
| #include <util/ities.h> | #include <util/ities.h> | ||||||
| #include <iostream> | #include <iostream> | ||||||
| @@ -208,8 +207,7 @@ core_complex<BUSWIDTH>::core_complex(sc_module_name const& name) | |||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| template <unsigned int BUSWIDTH> | template <unsigned int BUSWIDTH> void core_complex<BUSWIDTH>::init() { | ||||||
| void core_complex<BUSWIDTH>::init() { |  | ||||||
|     trc = new core_trace(); |     trc = new core_trace(); | ||||||
|     ibus.register_invalidate_direct_mem_ptr([=](uint64_t start, uint64_t end) -> void { |     ibus.register_invalidate_direct_mem_ptr([=](uint64_t start, uint64_t end) -> void { | ||||||
|         auto lut_entry = fetch_lut.getEntry(start); |         auto lut_entry = fetch_lut.getEntry(start); | ||||||
| @@ -254,19 +252,16 @@ void core_complex<BUSWIDTH>::init() { | |||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| template <unsigned int BUSWIDTH> | template <unsigned int BUSWIDTH> core_complex<BUSWIDTH>::~core_complex() { | ||||||
| core_complex<BUSWIDTH>::~core_complex() { |  | ||||||
|     delete cpu; |     delete cpu; | ||||||
|     delete trc; |     delete trc; | ||||||
|     for(auto* p : plugin_list) |     for(auto* p : plugin_list) | ||||||
|         delete p; |         delete p; | ||||||
| } | } | ||||||
|  |  | ||||||
| template <unsigned int BUSWIDTH> | template <unsigned int BUSWIDTH> void core_complex<BUSWIDTH>::trace(sc_trace_file* trf) const {} | ||||||
| void core_complex<BUSWIDTH>::trace(sc_trace_file* trf) const {} |  | ||||||
|  |  | ||||||
| template <unsigned int BUSWIDTH> | template <unsigned int BUSWIDTH> void core_complex<BUSWIDTH>::before_end_of_elaboration() { | ||||||
| void core_complex<BUSWIDTH>::before_end_of_elaboration() { |  | ||||||
|     SCCDEBUG(SCMOD) << "instantiating iss::arch::tgf with " << GET_PROP_VALUE(backend) << " backend"; |     SCCDEBUG(SCMOD) << "instantiating iss::arch::tgf with " << GET_PROP_VALUE(backend) << " backend"; | ||||||
|     // cpu = scc::make_unique<core_wrapper>(this); |     // cpu = scc::make_unique<core_wrapper>(this); | ||||||
|     cpu = new core_wrapper(this); |     cpu = new core_wrapper(this); | ||||||
| @@ -307,8 +302,7 @@ void core_complex<BUSWIDTH>::before_end_of_elaboration() { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| template <unsigned int BUSWIDTH> | template <unsigned int BUSWIDTH> void core_complex<BUSWIDTH>::start_of_simulation() { | ||||||
| void core_complex<BUSWIDTH>::start_of_simulation() { |  | ||||||
|     // quantum_keeper.reset(); |     // quantum_keeper.reset(); | ||||||
|     if(GET_PROP_VALUE(elf_file).size() > 0) { |     if(GET_PROP_VALUE(elf_file).size() > 0) { | ||||||
|         istringstream is(GET_PROP_VALUE(elf_file)); |         istringstream is(GET_PROP_VALUE(elf_file)); | ||||||
| @@ -331,8 +325,7 @@ void core_complex<BUSWIDTH>::start_of_simulation() { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| template <unsigned int BUSWIDTH> | template <unsigned int BUSWIDTH> bool core_complex<BUSWIDTH>::disass_output(uint64_t pc, const std::string instr_str) { | ||||||
| bool core_complex<BUSWIDTH>::disass_output(uint64_t pc, const std::string instr_str) { |  | ||||||
|     if(trc->m_db == nullptr) |     if(trc->m_db == nullptr) | ||||||
|         return false; |         return false; | ||||||
|     if(trc->tr_handle.is_active()) |     if(trc->tr_handle.is_active()) | ||||||
| @@ -346,8 +339,7 @@ bool core_complex<BUSWIDTH>::disass_output(uint64_t pc, const std::string instr_ | |||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| template <unsigned int BUSWIDTH> | template <unsigned int BUSWIDTH> void core_complex<BUSWIDTH>::forward() { | ||||||
| void core_complex<BUSWIDTH>::forward() { |  | ||||||
| #ifndef CWR_SYSTEMC | #ifndef CWR_SYSTEMC | ||||||
|     set_clock_period(clk_i.read()); |     set_clock_period(clk_i.read()); | ||||||
| #else | #else | ||||||
| @@ -356,30 +348,24 @@ void core_complex<BUSWIDTH>::forward() { | |||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| template <unsigned int BUSWIDTH> | template <unsigned int BUSWIDTH> void core_complex<BUSWIDTH>::set_clock_period(sc_core::sc_time period) { | ||||||
| void core_complex<BUSWIDTH>::set_clock_period(sc_core::sc_time period) { |  | ||||||
|     curr_clk = period; |     curr_clk = period; | ||||||
|     if(period == SC_ZERO_TIME) |     if(period == SC_ZERO_TIME) | ||||||
|         cpu->set_interrupt_execution(true); |         cpu->set_interrupt_execution(true); | ||||||
| } | } | ||||||
|  |  | ||||||
| template <unsigned int BUSWIDTH> | template <unsigned int BUSWIDTH> void core_complex<BUSWIDTH>::rst_cb() { | ||||||
| void core_complex<BUSWIDTH>::rst_cb() { |  | ||||||
|     if(rst_i.read()) |     if(rst_i.read()) | ||||||
|         cpu->set_interrupt_execution(true); |         cpu->set_interrupt_execution(true); | ||||||
| } | } | ||||||
|  |  | ||||||
| template <unsigned int BUSWIDTH> | template <unsigned int BUSWIDTH> void core_complex<BUSWIDTH>::sw_irq_cb() { cpu->local_irq(3, sw_irq_i.read()); } | ||||||
| void core_complex<BUSWIDTH>::sw_irq_cb() { cpu->local_irq(3, sw_irq_i.read()); } |  | ||||||
|  |  | ||||||
| template <unsigned int BUSWIDTH> | template <unsigned int BUSWIDTH> void core_complex<BUSWIDTH>::timer_irq_cb() { cpu->local_irq(7, timer_irq_i.read()); } | ||||||
| void core_complex<BUSWIDTH>::timer_irq_cb() { cpu->local_irq(7, timer_irq_i.read()); } |  | ||||||
|  |  | ||||||
| template <unsigned int BUSWIDTH> | template <unsigned int BUSWIDTH> void core_complex<BUSWIDTH>::ext_irq_cb() { cpu->local_irq(11, ext_irq_i.read()); } | ||||||
| void core_complex<BUSWIDTH>::ext_irq_cb() { cpu->local_irq(11, ext_irq_i.read()); } |  | ||||||
|  |  | ||||||
| template <unsigned int BUSWIDTH> | template <unsigned int BUSWIDTH> void core_complex<BUSWIDTH>::local_irq_cb() { | ||||||
| void core_complex<BUSWIDTH>::local_irq_cb() { |  | ||||||
|     for(auto i = 0U; i < local_irq_i.size(); ++i) { |     for(auto i = 0U; i < local_irq_i.size(); ++i) { | ||||||
|         if(local_irq_i[i].event()) { |         if(local_irq_i[i].event()) { | ||||||
|             cpu->local_irq(16 + i, local_irq_i[i].read()); |             cpu->local_irq(16 + i, local_irq_i[i].read()); | ||||||
| @@ -387,8 +373,7 @@ void core_complex<BUSWIDTH>::local_irq_cb() { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| template <unsigned int BUSWIDTH> | template <unsigned int BUSWIDTH> void core_complex<BUSWIDTH>::run() { | ||||||
| void core_complex<BUSWIDTH>::run() { |  | ||||||
|     wait(SC_ZERO_TIME); // separate from elaboration phase |     wait(SC_ZERO_TIME); // separate from elaboration phase | ||||||
|     do { |     do { | ||||||
|         wait(SC_ZERO_TIME); |         wait(SC_ZERO_TIME); | ||||||
| @@ -406,8 +391,7 @@ void core_complex<BUSWIDTH>::run() { | |||||||
|     sc_stop(); |     sc_stop(); | ||||||
| } | } | ||||||
|  |  | ||||||
| template <unsigned int BUSWIDTH> | template <unsigned int BUSWIDTH> bool core_complex<BUSWIDTH>::read_mem(uint64_t addr, unsigned length, uint8_t* const data, bool is_fetch) { | ||||||
| bool core_complex<BUSWIDTH>::read_mem(uint64_t addr, unsigned length, uint8_t* const data, bool is_fetch) { |  | ||||||
|     auto& dmi_lut = is_fetch ? fetch_lut : read_lut; |     auto& dmi_lut = is_fetch ? fetch_lut : read_lut; | ||||||
|     auto lut_entry = dmi_lut.getEntry(addr); |     auto lut_entry = dmi_lut.getEntry(addr); | ||||||
|     if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && addr + length <= lut_entry.get_end_address() + 1) { |     if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && addr + length <= lut_entry.get_end_address() + 1) { | ||||||
| @@ -465,8 +449,7 @@ bool core_complex<BUSWIDTH>::read_mem(uint64_t addr, unsigned length, uint8_t* c | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| template <unsigned int BUSWIDTH> | template <unsigned int BUSWIDTH> bool core_complex<BUSWIDTH>::write_mem(uint64_t addr, unsigned length, const uint8_t* const data) { | ||||||
| bool core_complex<BUSWIDTH>::write_mem(uint64_t addr, unsigned length, const uint8_t* const data) { |  | ||||||
|     auto lut_entry = write_lut.getEntry(addr); |     auto lut_entry = write_lut.getEntry(addr); | ||||||
|     if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && addr + length <= lut_entry.get_end_address() + 1) { |     if(lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && addr + length <= lut_entry.get_end_address() + 1) { | ||||||
|         auto offset = addr - lut_entry.get_start_address(); |         auto offset = addr - lut_entry.get_start_address(); | ||||||
| @@ -514,8 +497,7 @@ bool core_complex<BUSWIDTH>::write_mem(uint64_t addr, unsigned length, const uin | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| template <unsigned int BUSWIDTH> | template <unsigned int BUSWIDTH> bool core_complex<BUSWIDTH>::read_mem_dbg(uint64_t addr, unsigned length, uint8_t* const data) { | ||||||
| bool core_complex<BUSWIDTH>::read_mem_dbg(uint64_t addr, unsigned length, uint8_t* const data) { |  | ||||||
|     tlm::tlm_generic_payload gp; |     tlm::tlm_generic_payload gp; | ||||||
|     gp.set_command(tlm::TLM_READ_COMMAND); |     gp.set_command(tlm::TLM_READ_COMMAND); | ||||||
|     gp.set_address(addr); |     gp.set_address(addr); | ||||||
| @@ -525,8 +507,7 @@ bool core_complex<BUSWIDTH>::read_mem_dbg(uint64_t addr, unsigned length, uint8_ | |||||||
|     return dbus->transport_dbg(gp) == length; |     return dbus->transport_dbg(gp) == length; | ||||||
| } | } | ||||||
|  |  | ||||||
| template <unsigned int BUSWIDTH> | template <unsigned int BUSWIDTH> bool core_complex<BUSWIDTH>::write_mem_dbg(uint64_t addr, unsigned length, const uint8_t* const data) { | ||||||
| bool core_complex<BUSWIDTH>::write_mem_dbg(uint64_t addr, unsigned length, const uint8_t* const data) { |  | ||||||
|     write_buf.resize(length); |     write_buf.resize(length); | ||||||
|     std::copy(data, data + length, write_buf.begin()); // need to copy as TLM does not guarantee data integrity |     std::copy(data, data + length, write_buf.begin()); // need to copy as TLM does not guarantee data integrity | ||||||
|     tlm::tlm_generic_payload gp; |     tlm::tlm_generic_payload gp; | ||||||
|   | |||||||
| @@ -33,10 +33,10 @@ | |||||||
| #ifndef _SYSC_CORE_COMPLEX_H_ | #ifndef _SYSC_CORE_COMPLEX_H_ | ||||||
| #define _SYSC_CORE_COMPLEX_H_ | #define _SYSC_CORE_COMPLEX_H_ | ||||||
|  |  | ||||||
|  | #include <scc/signal_opt_ports.h> | ||||||
| #include <scc/tick2time.h> | #include <scc/tick2time.h> | ||||||
| #include <scc/traceable.h> | #include <scc/traceable.h> | ||||||
| #include <scc/utilities.h> | #include <scc/utilities.h> | ||||||
| #include <scc/signal_opt_ports.h> |  | ||||||
| #include <tlm/scc/initiator_mixin.h> | #include <tlm/scc/initiator_mixin.h> | ||||||
| #include <tlm/scc/scv/tlm_rec_initiator_socket.h> | #include <tlm/scc/scv/tlm_rec_initiator_socket.h> | ||||||
| #ifdef CWR_SYSTEMC | #ifdef CWR_SYSTEMC | ||||||
| @@ -71,28 +71,27 @@ struct core_complex_if { | |||||||
|  |  | ||||||
|     virtual ~core_complex_if() = default; |     virtual ~core_complex_if() = default; | ||||||
|  |  | ||||||
|     virtual bool read_mem(uint64_t addr, unsigned length, uint8_t* const data, bool is_fetch) =0; |     virtual bool read_mem(uint64_t addr, unsigned length, uint8_t* const data, bool is_fetch) = 0; | ||||||
|  |  | ||||||
|     virtual bool write_mem(uint64_t addr, unsigned length, const uint8_t* const data)  =0; |     virtual bool write_mem(uint64_t addr, unsigned length, const uint8_t* const data) = 0; | ||||||
|  |  | ||||||
|     virtual bool read_mem_dbg(uint64_t addr, unsigned length, uint8_t* const data)  =0; |     virtual bool read_mem_dbg(uint64_t addr, unsigned length, uint8_t* const data) = 0; | ||||||
|  |  | ||||||
|     virtual bool write_mem_dbg(uint64_t addr, unsigned length, const uint8_t* const data)  =0; |     virtual bool write_mem_dbg(uint64_t addr, unsigned length, const uint8_t* const data) = 0; | ||||||
|  |  | ||||||
|     virtual bool disass_output(uint64_t pc, const std::string instr)  =0; |     virtual bool disass_output(uint64_t pc, const std::string instr) = 0; | ||||||
|  |  | ||||||
|     virtual unsigned get_last_bus_cycles() =0; |     virtual unsigned get_last_bus_cycles() = 0; | ||||||
|  |  | ||||||
|     //! Allow quantum keeper handling |     //! Allow quantum keeper handling | ||||||
|     virtual void sync(uint64_t) =0; |     virtual void sync(uint64_t) = 0; | ||||||
|  |  | ||||||
|     virtual char const* hier_name() = 0; |     virtual char const* hier_name() = 0; | ||||||
|  |  | ||||||
|     scc::sc_in_opt<uint64_t> mtime_i{"mtime_i"}; |     scc::sc_in_opt<uint64_t> mtime_i{"mtime_i"}; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| template <unsigned int BUSWIDTH = scc::LT> | template <unsigned int BUSWIDTH = scc::LT> class core_complex : public sc_core::sc_module, public scc::traceable, public core_complex_if { | ||||||
| class core_complex : public sc_core::sc_module, public scc::traceable, public core_complex_if { |  | ||||||
| public: | public: | ||||||
|     tlm::scc::initiator_mixin<tlm::tlm_initiator_socket<BUSWIDTH>> ibus{"ibus"}; |     tlm::scc::initiator_mixin<tlm::tlm_initiator_socket<BUSWIDTH>> ibus{"ibus"}; | ||||||
|  |  | ||||||
| @@ -208,9 +207,7 @@ public: | |||||||
|  |  | ||||||
|     void set_clock_period(sc_core::sc_time period); |     void set_clock_period(sc_core::sc_time period); | ||||||
|  |  | ||||||
|     char const* hier_name() override { |     char const* hier_name() override { return name(); } | ||||||
|         return name(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| protected: | protected: | ||||||
|     void before_end_of_elaboration() override; |     void before_end_of_elaboration() override; | ||||||
|   | |||||||
| @@ -55,8 +55,8 @@ public: | |||||||
|             s << "[p:" << lvl[this->reg.PRIV] << ";s:0x" << std::hex << std::setfill('0') << std::setw(sizeof(reg_t) * 2) |             s << "[p:" << lvl[this->reg.PRIV] << ";s:0x" << std::hex << std::setfill('0') << std::setw(sizeof(reg_t) * 2) | ||||||
|               << (reg_t)this->state.mstatus << std::dec << ";c:" << this->reg.icount + this->cycle_offset << "]"; |               << (reg_t)this->state.mstatus << std::dec << ";c:" << this->reg.icount + this->cycle_offset << "]"; | ||||||
|             SCCDEBUG(owner->hier_name()) << "disass: " |             SCCDEBUG(owner->hier_name()) << "disass: " | ||||||
|                                     << "0x" << std::setw(16) << std::right << std::setfill('0') << std::hex << pc << "\t\t" << std::setw(40) |                                          << "0x" << std::setw(16) << std::right << std::setfill('0') << std::hex << pc << "\t\t" | ||||||
|                                     << std::setfill(' ') << std::left << instr << s.str(); |                                          << std::setw(40) << std::setfill(' ') << std::left << instr << s.str(); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
| @@ -113,7 +113,7 @@ public: | |||||||
|  |  | ||||||
|     iss::status read_csr(unsigned addr, reg_t& val) override { |     iss::status read_csr(unsigned addr, reg_t& val) override { | ||||||
|         if((addr == iss::arch::time || addr == iss::arch::timeh)) { |         if((addr == iss::arch::time || addr == iss::arch::timeh)) { | ||||||
|             uint64_t time_val = owner->mtime_i.get_interface()? owner->mtime_i.read():0; |             uint64_t time_val = owner->mtime_i.get_interface() ? owner->mtime_i.read() : 0; | ||||||
|             if(addr == iss::arch::time) { |             if(addr == iss::arch::time) { | ||||||
|                 val = static_cast<reg_t>(time_val); |                 val = static_cast<reg_t>(time_val); | ||||||
|             } else if(addr == iss::arch::timeh) { |             } else if(addr == iss::arch::timeh) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user