Compare commits
	
		
			3 Commits
		
	
	
		
			1e6a0086e9
			...
			6c986d38d8
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 6c986d38d8 | |||
| a1ebd83d2a | |||
| 8aed551813 | 
@@ -36,7 +36,12 @@
 | 
				
			|||||||
#define _RISCV_HART_COMMON
 | 
					#define _RISCV_HART_COMMON
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "iss/arch_if.h"
 | 
					#include "iss/arch_if.h"
 | 
				
			||||||
 | 
					#include "iss/log_categories.h"
 | 
				
			||||||
#include <cstdint>
 | 
					#include <cstdint>
 | 
				
			||||||
 | 
					#include <elfio/elfio.hpp>
 | 
				
			||||||
 | 
					#include <fmt/format.h>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <unordered_map>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace iss {
 | 
					namespace iss {
 | 
				
			||||||
namespace arch {
 | 
					namespace arch {
 | 
				
			||||||
@@ -296,6 +301,61 @@ inline void write_reg_uint32(uint64_t offs, uint32_t& reg, const uint8_t* const
 | 
				
			|||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					struct riscv_hart_common {
 | 
				
			||||||
 | 
					    riscv_hart_common(){};
 | 
				
			||||||
 | 
					    ~riscv_hart_common(){};
 | 
				
			||||||
 | 
					    std::unordered_map<std::string, uint64_t> symbol_table;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::unordered_map<std::string, uint64_t> get_sym_table(std::string name) {
 | 
				
			||||||
 | 
					        if(!symbol_table.empty())
 | 
				
			||||||
 | 
					            return symbol_table;
 | 
				
			||||||
 | 
					        FILE* fp = fopen(name.c_str(), "r");
 | 
				
			||||||
 | 
					        if(fp) {
 | 
				
			||||||
 | 
					            std::array<char, 5> buf;
 | 
				
			||||||
 | 
					            auto n = fread(buf.data(), 1, 4, fp);
 | 
				
			||||||
 | 
					            fclose(fp);
 | 
				
			||||||
 | 
					            if(n != 4)
 | 
				
			||||||
 | 
					                throw std::runtime_error("input file has insufficient size");
 | 
				
			||||||
 | 
					            buf[4] = 0;
 | 
				
			||||||
 | 
					            if(strcmp(buf.data() + 1, "ELF") == 0) {
 | 
				
			||||||
 | 
					                // Create elfio reader
 | 
				
			||||||
 | 
					                ELFIO::elfio reader;
 | 
				
			||||||
 | 
					                // Load ELF data
 | 
				
			||||||
 | 
					                if(!reader.load(name))
 | 
				
			||||||
 | 
					                    throw std::runtime_error("could not process elf file");
 | 
				
			||||||
 | 
					                // check elf properties
 | 
				
			||||||
 | 
					                if(reader.get_type() != ET_EXEC)
 | 
				
			||||||
 | 
					                    throw std::runtime_error("wrong elf type in file");
 | 
				
			||||||
 | 
					                if(reader.get_machine() != EM_RISCV)
 | 
				
			||||||
 | 
					                    throw std::runtime_error("wrong elf machine in file");
 | 
				
			||||||
 | 
					                const auto sym_sec = reader.sections[".symtab"];
 | 
				
			||||||
 | 
					                if(SHT_SYMTAB == sym_sec->get_type() || SHT_DYNSYM == sym_sec->get_type()) {
 | 
				
			||||||
 | 
					                    ELFIO::symbol_section_accessor symbols(reader, sym_sec);
 | 
				
			||||||
 | 
					                    auto sym_no = symbols.get_symbols_num();
 | 
				
			||||||
 | 
					                    std::string name;
 | 
				
			||||||
 | 
					                    ELFIO::Elf64_Addr value = 0;
 | 
				
			||||||
 | 
					                    ELFIO::Elf_Xword size = 0;
 | 
				
			||||||
 | 
					                    unsigned char bind = 0;
 | 
				
			||||||
 | 
					                    unsigned char type = 0;
 | 
				
			||||||
 | 
					                    ELFIO::Elf_Half section = 0;
 | 
				
			||||||
 | 
					                    unsigned char other = 0;
 | 
				
			||||||
 | 
					                    for(auto i = 0U; i < sym_no; ++i) {
 | 
				
			||||||
 | 
					                        symbols.get_symbol(i, name, value, size, bind, type, section, other);
 | 
				
			||||||
 | 
					                        if(name != "") {
 | 
				
			||||||
 | 
					                            this->symbol_table[name] = value;
 | 
				
			||||||
 | 
					#ifndef NDEBUG
 | 
				
			||||||
 | 
					                            LOG(DEBUG) << "Found Symbol " << name;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                return symbol_table;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            throw std::runtime_error(fmt::format("memory load file {} is not a valid elf file", name));
 | 
				
			||||||
 | 
					        } else
 | 
				
			||||||
 | 
					            throw std::runtime_error(fmt::format("memory load file not found, check if {} is a valid file", name));
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace arch
 | 
					} // namespace arch
 | 
				
			||||||
} // namespace iss
 | 
					} // namespace iss
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,6 +40,7 @@
 | 
				
			|||||||
#include "iss/log_categories.h"
 | 
					#include "iss/log_categories.h"
 | 
				
			||||||
#include "iss/vm_if.h"
 | 
					#include "iss/vm_if.h"
 | 
				
			||||||
#include "riscv_hart_common.h"
 | 
					#include "riscv_hart_common.h"
 | 
				
			||||||
 | 
					#include <stdexcept>
 | 
				
			||||||
#ifndef FMT_HEADER_ONLY
 | 
					#ifndef FMT_HEADER_ONLY
 | 
				
			||||||
#define FMT_HEADER_ONLY
 | 
					#define FMT_HEADER_ONLY
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@@ -68,7 +69,7 @@
 | 
				
			|||||||
namespace iss {
 | 
					namespace iss {
 | 
				
			||||||
namespace arch {
 | 
					namespace arch {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename BASE, features_e FEAT = FEAT_NONE> class riscv_hart_m_p : public BASE {
 | 
					template <typename BASE, features_e FEAT = FEAT_NONE> class riscv_hart_m_p : public BASE, public riscv_hart_common {
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
    const std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}};
 | 
					    const std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}};
 | 
				
			||||||
    const std::array<const char*, 16> trap_str = {{""
 | 
					    const std::array<const char*, 16> trap_str = {{""
 | 
				
			||||||
@@ -326,6 +327,8 @@ protected:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        unsigned get_reg_size(unsigned num) override { return traits<BASE>::reg_bit_widths[num]; }
 | 
					        unsigned get_reg_size(unsigned num) override { return traits<BASE>::reg_bit_widths[num]; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::unordered_map<std::string, uint64_t> get_symbol_table(std::string name) override { return arch.get_sym_table(name); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        riscv_hart_m_p<BASE, FEAT>& arch;
 | 
					        riscv_hart_m_p<BASE, FEAT>& arch;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -570,6 +573,12 @@ riscv_hart_m_p<BASE, FEAT>::riscv_hart_m_p(feature_config cfg)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename BASE, features_e FEAT> std::pair<uint64_t, bool> riscv_hart_m_p<BASE, FEAT>::load_file(std::string name, int type) {
 | 
					template <typename BASE, features_e FEAT> std::pair<uint64_t, bool> riscv_hart_m_p<BASE, FEAT>::load_file(std::string name, int type) {
 | 
				
			||||||
 | 
					    get_sym_table(name);
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        tohost = symbol_table.at("tohost");
 | 
				
			||||||
 | 
					        fromhost = symbol_table.at("fromhost");
 | 
				
			||||||
 | 
					    } catch(std::out_of_range& e) {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    FILE* fp = fopen(name.c_str(), "r");
 | 
					    FILE* fp = fopen(name.c_str(), "r");
 | 
				
			||||||
    if(fp) {
 | 
					    if(fp) {
 | 
				
			||||||
        std::array<char, 5> buf;
 | 
					        std::array<char, 5> buf;
 | 
				
			||||||
@@ -600,31 +609,11 @@ template <typename BASE, features_e FEAT> std::pair<uint64_t, bool> riscv_hart_m
 | 
				
			|||||||
                    auto res = this->write(iss::address_type::PHYSICAL, iss::access_type::DEBUG_WRITE, traits<BASE>::MEM,
 | 
					                    auto res = this->write(iss::address_type::PHYSICAL, iss::access_type::DEBUG_WRITE, traits<BASE>::MEM,
 | 
				
			||||||
                                           pseg->get_physical_address(), fsize, reinterpret_cast<const uint8_t* const>(seg_data));
 | 
					                                           pseg->get_physical_address(), fsize, reinterpret_cast<const uint8_t* const>(seg_data));
 | 
				
			||||||
                    if(res != iss::Ok)
 | 
					                    if(res != iss::Ok)
 | 
				
			||||||
                        LOG(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() == ".tohost") {
 | 
				
			||||||
                    if(SHT_SYMTAB == sec->get_type() || SHT_DYNSYM == sec->get_type()) {
 | 
					 | 
				
			||||||
                        ELFIO::symbol_section_accessor symbols(reader, sec);
 | 
					 | 
				
			||||||
                        auto sym_no = symbols.get_symbols_num();
 | 
					 | 
				
			||||||
                        std::string name;
 | 
					 | 
				
			||||||
                        ELFIO::Elf64_Addr value = 0;
 | 
					 | 
				
			||||||
                        ELFIO::Elf_Xword size = 0;
 | 
					 | 
				
			||||||
                        unsigned char bind = 0;
 | 
					 | 
				
			||||||
                        unsigned char type = 0;
 | 
					 | 
				
			||||||
                        ELFIO::Elf_Half section = 0;
 | 
					 | 
				
			||||||
                        unsigned char other = 0;
 | 
					 | 
				
			||||||
                        for(auto i = 0U; i < sym_no; ++i) {
 | 
					 | 
				
			||||||
                            symbols.get_symbol(i, name, value, size, bind, type, section, other);
 | 
					 | 
				
			||||||
                            if(name == "tohost") {
 | 
					 | 
				
			||||||
                                tohost = value;
 | 
					 | 
				
			||||||
                            } else if(name == "fromhost") {
 | 
					 | 
				
			||||||
                                fromhost = value;
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                } else if(sec->get_name() == ".tohost") {
 | 
					 | 
				
			||||||
                    tohost = sec->get_address();
 | 
					                    tohost = sec->get_address();
 | 
				
			||||||
                    fromhost = tohost + 0x40;
 | 
					                    fromhost = tohost + 0x40;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -654,11 +643,11 @@ iss::status riscv_hart_m_p<BASE, FEAT>::read(const address_type type, const acce
 | 
				
			|||||||
                                             const unsigned length, uint8_t* const data) {
 | 
					                                             const unsigned length, uint8_t* const data) {
 | 
				
			||||||
#ifndef NDEBUG
 | 
					#ifndef NDEBUG
 | 
				
			||||||
    if(access && iss::access_type::DEBUG) {
 | 
					    if(access && iss::access_type::DEBUG) {
 | 
				
			||||||
        LOG(TRACEALL) << "debug read of " << length << " bytes @addr 0x" << std::hex << addr;
 | 
					        CPPLOG(TRACEALL) << "debug read of " << length << " bytes @addr 0x" << std::hex << addr;
 | 
				
			||||||
    } else if(access && iss::access_type::FETCH) {
 | 
					    } else if(access && iss::access_type::FETCH) {
 | 
				
			||||||
        LOG(TRACEALL) << "fetch of " << length << " bytes  @addr 0x" << std::hex << addr;
 | 
					        CPPLOG(TRACEALL) << "fetch of " << length << " bytes  @addr 0x" << std::hex << addr;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        LOG(TRACE) << "read of " << length << " bytes  @addr 0x" << std::hex << addr;
 | 
					        CPPLOG(TRACE) << "read of " << length << " bytes  @addr 0x" << std::hex << addr;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
@@ -740,23 +729,23 @@ iss::status riscv_hart_m_p<BASE, FEAT>::write(const address_type type, const acc
 | 
				
			|||||||
    const char* prefix = (access && iss::access_type::DEBUG) ? "debug " : "";
 | 
					    const char* prefix = (access && iss::access_type::DEBUG) ? "debug " : "";
 | 
				
			||||||
    switch(length) {
 | 
					    switch(length) {
 | 
				
			||||||
    case 8:
 | 
					    case 8:
 | 
				
			||||||
        LOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint64_t*)&data[0] << std::dec << ") @addr 0x"
 | 
					        CPPLOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint64_t*)&data[0] << std::dec << ") @addr 0x"
 | 
				
			||||||
                   << std::hex << addr;
 | 
					                   << std::hex << addr;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 4:
 | 
					    case 4:
 | 
				
			||||||
        LOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint32_t*)&data[0] << std::dec << ") @addr 0x"
 | 
					        CPPLOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint32_t*)&data[0] << std::dec << ") @addr 0x"
 | 
				
			||||||
                   << std::hex << addr;
 | 
					                   << std::hex << addr;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 2:
 | 
					    case 2:
 | 
				
			||||||
        LOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint16_t*)&data[0] << std::dec << ") @addr 0x"
 | 
					        CPPLOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint16_t*)&data[0] << std::dec << ") @addr 0x"
 | 
				
			||||||
                   << std::hex << addr;
 | 
					                   << std::hex << addr;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 1:
 | 
					    case 1:
 | 
				
			||||||
        LOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << (uint16_t)data[0] << std::dec << ") @addr 0x"
 | 
					        CPPLOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << (uint16_t)data[0] << std::dec << ") @addr 0x"
 | 
				
			||||||
                   << std::hex << addr;
 | 
					                   << std::hex << addr;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        LOG(TRACE) << prefix << "write of " << length << " bytes @addr " << addr;
 | 
					        CPPLOG(TRACE) << prefix << "write of " << length << " bytes @addr " << addr;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
@@ -808,7 +797,7 @@ iss::status riscv_hart_m_p<BASE, FEAT>::write(const address_type type, const acc
 | 
				
			|||||||
            case 0x10023000: // UART1 base, TXFIFO reg
 | 
					            case 0x10023000: // UART1 base, TXFIFO reg
 | 
				
			||||||
                uart_buf << (char)data[0];
 | 
					                uart_buf << (char)data[0];
 | 
				
			||||||
                if(((char)data[0]) == '\n' || data[0] == 0) {
 | 
					                if(((char)data[0]) == '\n' || data[0] == 0) {
 | 
				
			||||||
                    // LOG(INFO)<<"UART"<<((paddr.val>>16)&0x3)<<" send
 | 
					                    // CPPLOG(INFO)<<"UART"<<((paddr.val>>16)&0x3)<<" send
 | 
				
			||||||
                    // '"<<uart_buf.str()<<"'";
 | 
					                    // '"<<uart_buf.str()<<"'";
 | 
				
			||||||
                    std::cout << uart_buf.str();
 | 
					                    std::cout << uart_buf.str();
 | 
				
			||||||
                    uart_buf.str("");
 | 
					                    uart_buf.str("");
 | 
				
			||||||
@@ -1108,7 +1097,7 @@ iss::status riscv_hart_m_p<BASE, FEAT>::write_mem(phys_addr_t paddr, unsigned le
 | 
				
			|||||||
    // TODO remove UART, Peripherals should not be part of the ISS
 | 
					    // TODO remove UART, Peripherals should not be part of the ISS
 | 
				
			||||||
    case 0xFFFF0000: // UART0 base, TXFIFO reg
 | 
					    case 0xFFFF0000: // UART0 base, TXFIFO reg
 | 
				
			||||||
        if(((char)data[0]) == '\n' || data[0] == 0) {
 | 
					        if(((char)data[0]) == '\n' || data[0] == 0) {
 | 
				
			||||||
            LOG(INFO) << "UART" << ((paddr.val >> 12) & 0x3) << " send '" << uart_buf.str() << "'";
 | 
					            CPPLOG(INFO) << "UART" << ((paddr.val >> 12) & 0x3) << " send '" << uart_buf.str() << "'";
 | 
				
			||||||
            uart_buf.str("");
 | 
					            uart_buf.str("");
 | 
				
			||||||
        } else if(((char)data[0]) != '\r')
 | 
					        } else if(((char)data[0]) != '\r')
 | 
				
			||||||
            uart_buf << (char)data[0];
 | 
					            uart_buf << (char)data[0];
 | 
				
			||||||
@@ -1128,10 +1117,10 @@ iss::status riscv_hart_m_p<BASE, FEAT>::write_mem(phys_addr_t paddr, unsigned le
 | 
				
			|||||||
                    switch(hostvar >> 48) {
 | 
					                    switch(hostvar >> 48) {
 | 
				
			||||||
                    case 0:
 | 
					                    case 0:
 | 
				
			||||||
                        if(hostvar != 0x1) {
 | 
					                        if(hostvar != 0x1) {
 | 
				
			||||||
                            LOG(FATAL) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
 | 
					                            CPPLOG(FATAL) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
 | 
				
			||||||
                                       << "), stopping simulation";
 | 
					                                       << "), stopping simulation";
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
                            LOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
 | 
					                            CPPLOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
 | 
				
			||||||
                                      << "), stopping simulation";
 | 
					                                      << "), stopping simulation";
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        this->reg.trap_state = std::numeric_limits<uint32_t>::max();
 | 
					                        this->reg.trap_state = std::numeric_limits<uint32_t>::max();
 | 
				
			||||||
@@ -1143,7 +1132,7 @@ iss::status riscv_hart_m_p<BASE, FEAT>::write_mem(phys_addr_t paddr, unsigned le
 | 
				
			|||||||
                    case 0x0101: {
 | 
					                    case 0x0101: {
 | 
				
			||||||
                        char c = static_cast<char>(hostvar & 0xff);
 | 
					                        char c = static_cast<char>(hostvar & 0xff);
 | 
				
			||||||
                        if(c == '\n' || c == 0) {
 | 
					                        if(c == '\n' || c == 0) {
 | 
				
			||||||
                            LOG(INFO) << "tohost send '" << uart_buf.str() << "'";
 | 
					                            CPPLOG(INFO) << "tohost send '" << uart_buf.str() << "'";
 | 
				
			||||||
                            uart_buf.str("");
 | 
					                            uart_buf.str("");
 | 
				
			||||||
                        } else
 | 
					                        } else
 | 
				
			||||||
                            uart_buf << c;
 | 
					                            uart_buf << c;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -68,7 +68,7 @@
 | 
				
			|||||||
namespace iss {
 | 
					namespace iss {
 | 
				
			||||||
namespace arch {
 | 
					namespace arch {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename BASE> class riscv_hart_msu_vp : public BASE {
 | 
					template <typename BASE> class riscv_hart_msu_vp : public BASE, public riscv_hart_common {
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
    const std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}};
 | 
					    const std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}};
 | 
				
			||||||
    const std::array<const char*, 16> trap_str = {{""
 | 
					    const std::array<const char*, 16> trap_str = {{""
 | 
				
			||||||
@@ -377,6 +377,8 @@ protected:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        unsigned get_reg_size(unsigned num) override { return traits<BASE>::reg_bit_widths[num]; }
 | 
					        unsigned get_reg_size(unsigned num) override { return traits<BASE>::reg_bit_widths[num]; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::unordered_map<std::string, uint64_t> get_symbol_table(std::string name) override { return arch.get_sym_table(name); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        riscv_hart_msu_vp<BASE>& arch;
 | 
					        riscv_hart_msu_vp<BASE>& arch;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -591,7 +593,7 @@ template <typename BASE> std::pair<uint64_t, bool> riscv_hart_msu_vp<BASE>::load
 | 
				
			|||||||
                    auto res = this->write(iss::address_type::PHYSICAL, iss::access_type::DEBUG_WRITE, traits<BASE>::MEM,
 | 
					                    auto res = this->write(iss::address_type::PHYSICAL, iss::access_type::DEBUG_WRITE, traits<BASE>::MEM,
 | 
				
			||||||
                                           pseg->get_physical_address(), fsize, reinterpret_cast<const uint8_t* const>(seg_data));
 | 
					                                           pseg->get_physical_address(), fsize, reinterpret_cast<const uint8_t* const>(seg_data));
 | 
				
			||||||
                    if(res != iss::Ok)
 | 
					                    if(res != iss::Ok)
 | 
				
			||||||
                        LOG(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) {
 | 
				
			||||||
@@ -632,11 +634,11 @@ iss::status riscv_hart_msu_vp<BASE>::read(const address_type type, const access_
 | 
				
			|||||||
                                          const unsigned length, uint8_t* const data) {
 | 
					                                          const unsigned length, uint8_t* const data) {
 | 
				
			||||||
#ifndef NDEBUG
 | 
					#ifndef NDEBUG
 | 
				
			||||||
    if(access && iss::access_type::DEBUG) {
 | 
					    if(access && iss::access_type::DEBUG) {
 | 
				
			||||||
        LOG(TRACEALL) << "debug read of " << length << " bytes @addr 0x" << std::hex << addr;
 | 
					        CPPLOG(TRACEALL) << "debug read of " << length << " bytes @addr 0x" << std::hex << addr;
 | 
				
			||||||
    } else if(access && iss::access_type::FETCH) {
 | 
					    } else if(access && iss::access_type::FETCH) {
 | 
				
			||||||
        LOG(TRACEALL) << "fetch of " << length << " bytes  @addr 0x" << std::hex << addr;
 | 
					        CPPLOG(TRACEALL) << "fetch of " << length << " bytes  @addr 0x" << std::hex << addr;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        LOG(TRACE) << "read of " << length << " bytes  @addr 0x" << std::hex << addr;
 | 
					        CPPLOG(TRACE) << "read of " << length << " bytes  @addr 0x" << std::hex << addr;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
@@ -726,23 +728,23 @@ iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access
 | 
				
			|||||||
    const char* prefix = (access && iss::access_type::DEBUG) ? "debug " : "";
 | 
					    const char* prefix = (access && iss::access_type::DEBUG) ? "debug " : "";
 | 
				
			||||||
    switch(length) {
 | 
					    switch(length) {
 | 
				
			||||||
    case 8:
 | 
					    case 8:
 | 
				
			||||||
        LOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint64_t*)&data[0] << std::dec << ") @addr 0x"
 | 
					        CPPLOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint64_t*)&data[0] << std::dec << ") @addr 0x"
 | 
				
			||||||
                   << std::hex << addr;
 | 
					                   << std::hex << addr;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 4:
 | 
					    case 4:
 | 
				
			||||||
        LOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint32_t*)&data[0] << std::dec << ") @addr 0x"
 | 
					        CPPLOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint32_t*)&data[0] << std::dec << ") @addr 0x"
 | 
				
			||||||
                   << std::hex << addr;
 | 
					                   << std::hex << addr;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 2:
 | 
					    case 2:
 | 
				
			||||||
        LOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint16_t*)&data[0] << std::dec << ") @addr 0x"
 | 
					        CPPLOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint16_t*)&data[0] << std::dec << ") @addr 0x"
 | 
				
			||||||
                   << std::hex << addr;
 | 
					                   << std::hex << addr;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 1:
 | 
					    case 1:
 | 
				
			||||||
        LOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << (uint16_t)data[0] << std::dec << ") @addr 0x"
 | 
					        CPPLOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << (uint16_t)data[0] << std::dec << ") @addr 0x"
 | 
				
			||||||
                   << std::hex << addr;
 | 
					                   << std::hex << addr;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        LOG(TRACE) << prefix << "write of " << length << " bytes @addr " << addr;
 | 
					        CPPLOG(TRACE) << prefix << "write of " << length << " bytes @addr " << addr;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
@@ -787,7 +789,7 @@ iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access
 | 
				
			|||||||
            case 0x10023000: // UART1 base, TXFIFO reg
 | 
					            case 0x10023000: // UART1 base, TXFIFO reg
 | 
				
			||||||
                uart_buf << (char)data[0];
 | 
					                uart_buf << (char)data[0];
 | 
				
			||||||
                if(((char)data[0]) == '\n' || data[0] == 0) {
 | 
					                if(((char)data[0]) == '\n' || data[0] == 0) {
 | 
				
			||||||
                    // LOG(INFO)<<"UART"<<((paddr.val>>16)&0x3)<<" send
 | 
					                    // CPPLOG(INFO)<<"UART"<<((paddr.val>>16)&0x3)<<" send
 | 
				
			||||||
                    // '"<<uart_buf.str()<<"'";
 | 
					                    // '"<<uart_buf.str()<<"'";
 | 
				
			||||||
                    std::cout << uart_buf.str();
 | 
					                    std::cout << uart_buf.str();
 | 
				
			||||||
                    uart_buf.str("");
 | 
					                    uart_buf.str("");
 | 
				
			||||||
@@ -1083,7 +1085,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_add
 | 
				
			|||||||
    switch(paddr.val) {
 | 
					    switch(paddr.val) {
 | 
				
			||||||
    case 0xFFFF0000: // UART0 base, TXFIFO reg
 | 
					    case 0xFFFF0000: // UART0 base, TXFIFO reg
 | 
				
			||||||
        if(((char)data[0]) == '\n' || data[0] == 0) {
 | 
					        if(((char)data[0]) == '\n' || data[0] == 0) {
 | 
				
			||||||
            LOG(INFO) << "UART" << ((paddr.val >> 12) & 0x3) << " send '" << uart_buf.str() << "'";
 | 
					            CPPLOG(INFO) << "UART" << ((paddr.val >> 12) & 0x3) << " send '" << uart_buf.str() << "'";
 | 
				
			||||||
            uart_buf.str("");
 | 
					            uart_buf.str("");
 | 
				
			||||||
        } else if(((char)data[0]) != '\r')
 | 
					        } else if(((char)data[0]) != '\r')
 | 
				
			||||||
            uart_buf << (char)data[0];
 | 
					            uart_buf << (char)data[0];
 | 
				
			||||||
@@ -1103,10 +1105,10 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_add
 | 
				
			|||||||
                    switch(hostvar >> 48) {
 | 
					                    switch(hostvar >> 48) {
 | 
				
			||||||
                    case 0:
 | 
					                    case 0:
 | 
				
			||||||
                        if(hostvar != 0x1) {
 | 
					                        if(hostvar != 0x1) {
 | 
				
			||||||
                            LOG(FATAL) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
 | 
					                            CPPLOG(FATAL) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
 | 
				
			||||||
                                       << "), stopping simulation";
 | 
					                                       << "), stopping simulation";
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
                            LOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
 | 
					                            CPPLOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
 | 
				
			||||||
                                      << "), stopping simulation";
 | 
					                                      << "), stopping simulation";
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        this->reg.trap_state = std::numeric_limits<uint32_t>::max();
 | 
					                        this->reg.trap_state = std::numeric_limits<uint32_t>::max();
 | 
				
			||||||
@@ -1118,7 +1120,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_add
 | 
				
			|||||||
                    case 0x0101: {
 | 
					                    case 0x0101: {
 | 
				
			||||||
                        char c = static_cast<char>(hostvar & 0xff);
 | 
					                        char c = static_cast<char>(hostvar & 0xff);
 | 
				
			||||||
                        if(c == '\n' || c == 0) {
 | 
					                        if(c == '\n' || c == 0) {
 | 
				
			||||||
                            LOG(INFO) << "tohost send '" << uart_buf.str() << "'";
 | 
					                            CPPLOG(INFO) << "tohost send '" << uart_buf.str() << "'";
 | 
				
			||||||
                            uart_buf.str("");
 | 
					                            uart_buf.str("");
 | 
				
			||||||
                        } else
 | 
					                        } else
 | 
				
			||||||
                            uart_buf << c;
 | 
					                            uart_buf << c;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -68,7 +68,7 @@
 | 
				
			|||||||
namespace iss {
 | 
					namespace iss {
 | 
				
			||||||
namespace arch {
 | 
					namespace arch {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename BASE, features_e FEAT = FEAT_NONE> class riscv_hart_mu_p : public BASE {
 | 
					template <typename BASE, features_e FEAT = FEAT_NONE> class riscv_hart_mu_p : public BASE, public riscv_hart_common {
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
    const std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}};
 | 
					    const std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}};
 | 
				
			||||||
    const std::array<const char*, 16> trap_str = {{""
 | 
					    const std::array<const char*, 16> trap_str = {{""
 | 
				
			||||||
@@ -353,6 +353,8 @@ protected:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        unsigned get_reg_size(unsigned num) override { return traits<BASE>::reg_bit_widths[num]; }
 | 
					        unsigned get_reg_size(unsigned num) override { return traits<BASE>::reg_bit_widths[num]; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::unordered_map<std::string, uint64_t> get_symbol_table(std::string name) override { return arch.get_sym_table(name); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        riscv_hart_mu_p<BASE, FEAT>& arch;
 | 
					        riscv_hart_mu_p<BASE, FEAT>& arch;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -678,7 +680,7 @@ template <typename BASE, features_e FEAT> std::pair<uint64_t, bool> riscv_hart_m
 | 
				
			|||||||
                    auto res = this->write(iss::address_type::PHYSICAL, iss::access_type::DEBUG_WRITE, traits<BASE>::MEM,
 | 
					                    auto res = this->write(iss::address_type::PHYSICAL, iss::access_type::DEBUG_WRITE, traits<BASE>::MEM,
 | 
				
			||||||
                                           pseg->get_physical_address(), fsize, reinterpret_cast<const uint8_t* const>(seg_data));
 | 
					                                           pseg->get_physical_address(), fsize, reinterpret_cast<const uint8_t* const>(seg_data));
 | 
				
			||||||
                    if(res != iss::Ok)
 | 
					                    if(res != iss::Ok)
 | 
				
			||||||
                        LOG(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) {
 | 
				
			||||||
@@ -818,11 +820,11 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::read(const address_type type, const acc
 | 
				
			|||||||
                                              const unsigned length, uint8_t* const data) {
 | 
					                                              const unsigned length, uint8_t* const data) {
 | 
				
			||||||
#ifndef NDEBUG
 | 
					#ifndef NDEBUG
 | 
				
			||||||
    if(access && iss::access_type::DEBUG) {
 | 
					    if(access && iss::access_type::DEBUG) {
 | 
				
			||||||
        LOG(TRACEALL) << "debug read of " << length << " bytes @addr 0x" << std::hex << addr;
 | 
					        CPPLOG(TRACEALL) << "debug read of " << length << " bytes @addr 0x" << std::hex << addr;
 | 
				
			||||||
    } else if(is_fetch(access)) {
 | 
					    } else if(is_fetch(access)) {
 | 
				
			||||||
        LOG(TRACEALL) << "fetch of " << length << " bytes  @addr 0x" << std::hex << addr;
 | 
					        CPPLOG(TRACEALL) << "fetch of " << length << " bytes  @addr 0x" << std::hex << addr;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        LOG(TRACE) << "read of " << length << " bytes  @addr 0x" << std::hex << addr;
 | 
					        CPPLOG(TRACE) << "read of " << length << " bytes  @addr 0x" << std::hex << addr;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
@@ -913,23 +915,23 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::write(const address_type type, const ac
 | 
				
			|||||||
    const char* prefix = (access && iss::access_type::DEBUG) ? "debug " : "";
 | 
					    const char* prefix = (access && iss::access_type::DEBUG) ? "debug " : "";
 | 
				
			||||||
    switch(length) {
 | 
					    switch(length) {
 | 
				
			||||||
    case 8:
 | 
					    case 8:
 | 
				
			||||||
        LOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint64_t*)&data[0] << std::dec << ") @addr 0x"
 | 
					        CPPLOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint64_t*)&data[0] << std::dec << ") @addr 0x"
 | 
				
			||||||
                   << std::hex << addr;
 | 
					                   << std::hex << addr;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 4:
 | 
					    case 4:
 | 
				
			||||||
        LOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint32_t*)&data[0] << std::dec << ") @addr 0x"
 | 
					        CPPLOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint32_t*)&data[0] << std::dec << ") @addr 0x"
 | 
				
			||||||
                   << std::hex << addr;
 | 
					                   << std::hex << addr;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 2:
 | 
					    case 2:
 | 
				
			||||||
        LOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint16_t*)&data[0] << std::dec << ") @addr 0x"
 | 
					        CPPLOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint16_t*)&data[0] << std::dec << ") @addr 0x"
 | 
				
			||||||
                   << std::hex << addr;
 | 
					                   << std::hex << addr;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 1:
 | 
					    case 1:
 | 
				
			||||||
        LOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << (uint16_t)data[0] << std::dec << ") @addr 0x"
 | 
					        CPPLOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << (uint16_t)data[0] << std::dec << ") @addr 0x"
 | 
				
			||||||
                   << std::hex << addr;
 | 
					                   << std::hex << addr;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        LOG(TRACE) << prefix << "write of " << length << " bytes @addr " << addr;
 | 
					        CPPLOG(TRACE) << prefix << "write of " << length << " bytes @addr " << addr;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
@@ -990,7 +992,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::write(const address_type type, const ac
 | 
				
			|||||||
            case 0x10023000: // UART1 base, TXFIFO reg
 | 
					            case 0x10023000: // UART1 base, TXFIFO reg
 | 
				
			||||||
                uart_buf << (char)data[0];
 | 
					                uart_buf << (char)data[0];
 | 
				
			||||||
                if(((char)data[0]) == '\n' || data[0] == 0) {
 | 
					                if(((char)data[0]) == '\n' || data[0] == 0) {
 | 
				
			||||||
                    // LOG(INFO)<<"UART"<<((addr>>16)&0x3)<<" send
 | 
					                    // CPPLOG(INFO)<<"UART"<<((addr>>16)&0x3)<<" send
 | 
				
			||||||
                    // '"<<uart_buf.str()<<"'";
 | 
					                    // '"<<uart_buf.str()<<"'";
 | 
				
			||||||
                    std::cout << uart_buf.str();
 | 
					                    std::cout << uart_buf.str();
 | 
				
			||||||
                    uart_buf.str("");
 | 
					                    uart_buf.str("");
 | 
				
			||||||
@@ -1326,7 +1328,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::write_mem(phys_addr_t paddr, unsigned l
 | 
				
			|||||||
    // TODO remove UART, Peripherals should not be part of the ISS
 | 
					    // TODO remove UART, Peripherals should not be part of the ISS
 | 
				
			||||||
    case 0xFFFF0000: // UART0 base, TXFIFO reg
 | 
					    case 0xFFFF0000: // UART0 base, TXFIFO reg
 | 
				
			||||||
        if(((char)data[0]) == '\n' || data[0] == 0) {
 | 
					        if(((char)data[0]) == '\n' || data[0] == 0) {
 | 
				
			||||||
            LOG(INFO) << "UART" << ((paddr.val >> 12) & 0x3) << " send '" << uart_buf.str() << "'";
 | 
					            CPPLOG(INFO) << "UART" << ((paddr.val >> 12) & 0x3) << " send '" << uart_buf.str() << "'";
 | 
				
			||||||
            uart_buf.str("");
 | 
					            uart_buf.str("");
 | 
				
			||||||
        } else if(((char)data[0]) != '\r')
 | 
					        } else if(((char)data[0]) != '\r')
 | 
				
			||||||
            uart_buf << (char)data[0];
 | 
					            uart_buf << (char)data[0];
 | 
				
			||||||
@@ -1346,10 +1348,10 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::write_mem(phys_addr_t paddr, unsigned l
 | 
				
			|||||||
                    switch(hostvar >> 48) {
 | 
					                    switch(hostvar >> 48) {
 | 
				
			||||||
                    case 0:
 | 
					                    case 0:
 | 
				
			||||||
                        if(hostvar != 0x1) {
 | 
					                        if(hostvar != 0x1) {
 | 
				
			||||||
                            LOG(FATAL) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
 | 
					                            CPPLOG(FATAL) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
 | 
				
			||||||
                                       << "), stopping simulation";
 | 
					                                       << "), stopping simulation";
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
                            LOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
 | 
					                            CPPLOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
 | 
				
			||||||
                                      << "), stopping simulation";
 | 
					                                      << "), stopping simulation";
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        this->reg.trap_state = std::numeric_limits<uint32_t>::max();
 | 
					                        this->reg.trap_state = std::numeric_limits<uint32_t>::max();
 | 
				
			||||||
@@ -1361,7 +1363,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::write_mem(phys_addr_t paddr, unsigned l
 | 
				
			|||||||
                    case 0x0101: {
 | 
					                    case 0x0101: {
 | 
				
			||||||
                        char c = static_cast<char>(hostvar & 0xff);
 | 
					                        char c = static_cast<char>(hostvar & 0xff);
 | 
				
			||||||
                        if(c == '\n' || c == 0) {
 | 
					                        if(c == '\n' || c == 0) {
 | 
				
			||||||
                            LOG(INFO) << "tohost send '" << uart_buf.str() << "'";
 | 
					                            CPPLOG(INFO) << "tohost send '" << uart_buf.str() << "'";
 | 
				
			||||||
                            uart_buf.str("");
 | 
					                            uart_buf.str("");
 | 
				
			||||||
                        } else
 | 
					                        } else
 | 
				
			||||||
                            uart_buf << c;
 | 
					                            uart_buf << c;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -174,7 +174,7 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::current_thread_query
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename ARCH> status riscv_target_adapter<ARCH>::read_registers(std::vector<uint8_t>& data, std::vector<uint8_t>& avail) {
 | 
					template <typename ARCH> status riscv_target_adapter<ARCH>::read_registers(std::vector<uint8_t>& data, std::vector<uint8_t>& avail) {
 | 
				
			||||||
    LOG(TRACE) << "reading target registers";
 | 
					    CPPLOG(TRACE) << "reading target registers";
 | 
				
			||||||
    // return idx<0?:;
 | 
					    // return idx<0?:;
 | 
				
			||||||
    data.clear();
 | 
					    data.clear();
 | 
				
			||||||
    avail.clear();
 | 
					    avail.clear();
 | 
				
			||||||
@@ -328,9 +328,9 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::add_break(break_type
 | 
				
			|||||||
        auto saddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr});
 | 
					        auto saddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr});
 | 
				
			||||||
        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);
 | 
				
			||||||
        LOG(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;
 | 
				
			||||||
        LOG(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;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -345,13 +345,13 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::remove_break(break_t
 | 
				
			|||||||
        auto saddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr});
 | 
					        auto saddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr});
 | 
				
			||||||
        unsigned handle = target_adapter_base::bp_lut.getEntry(saddr.val);
 | 
					        unsigned handle = target_adapter_base::bp_lut.getEntry(saddr.val);
 | 
				
			||||||
        if(handle) {
 | 
					        if(handle) {
 | 
				
			||||||
            LOG(TRACE) << "Removing breakpoint with handle " << handle << " for addr 0x" << std::hex << saddr.val << std::dec;
 | 
					            CPPLOG(TRACE) << "Removing breakpoint with handle " << handle << " for addr 0x" << std::hex << saddr.val << std::dec;
 | 
				
			||||||
            // TODO: check length of addr range
 | 
					            // TODO: check length of addr range
 | 
				
			||||||
            target_adapter_base::bp_lut.removeEntry(handle);
 | 
					            target_adapter_base::bp_lut.removeEntry(handle);
 | 
				
			||||||
            LOG(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;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        LOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints";
 | 
					        CPPLOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints";
 | 
				
			||||||
        return Err;
 | 
					        return Err;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -61,7 +61,7 @@ bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if&
 | 
				
			|||||||
            try {
 | 
					            try {
 | 
				
			||||||
                auto root = YAML::LoadAll(is);
 | 
					                auto root = YAML::LoadAll(is);
 | 
				
			||||||
                if(root.size() != 1) {
 | 
					                if(root.size() != 1) {
 | 
				
			||||||
                    LOG(ERR) << "Too many root nodes in YAML file " << config_file_name;
 | 
					                    CPPLOG(ERR) << "Too many root nodes in YAML file " << config_file_name;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                for(auto p : root[0]) {
 | 
					                for(auto p : root[0]) {
 | 
				
			||||||
                    auto isa_subset = p.first;
 | 
					                    auto isa_subset = p.first;
 | 
				
			||||||
@@ -87,11 +87,11 @@ bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if&
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } catch(YAML::ParserException& e) {
 | 
					            } catch(YAML::ParserException& e) {
 | 
				
			||||||
                LOG(ERR) << "Could not parse input file " << config_file_name << ", reason: " << e.what();
 | 
					                CPPLOG(ERR) << "Could not parse input file " << config_file_name << ", reason: " << e.what();
 | 
				
			||||||
                return false;
 | 
					                return false;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            LOG(ERR) << "Could not open input file " << config_file_name;
 | 
					            CPPLOG(ERR) << "Could not open input file " << config_file_name;
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -47,7 +47,7 @@ iss::plugin::instruction_count::instruction_count(std::string config_file_name)
 | 
				
			|||||||
            try {
 | 
					            try {
 | 
				
			||||||
                auto root = YAML::LoadAll(is);
 | 
					                auto root = YAML::LoadAll(is);
 | 
				
			||||||
                if(root.size() != 1) {
 | 
					                if(root.size() != 1) {
 | 
				
			||||||
                    LOG(ERR) << "Too many rro nodes in YAML file " << config_file_name;
 | 
					                    CPPLOG(ERR) << "Too many rro nodes in YAML file " << config_file_name;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                for(auto p : root[0]) {
 | 
					                for(auto p : root[0]) {
 | 
				
			||||||
                    auto isa_subset = p.first;
 | 
					                    auto isa_subset = p.first;
 | 
				
			||||||
@@ -69,10 +69,10 @@ iss::plugin::instruction_count::instruction_count(std::string config_file_name)
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                rep_counts.resize(delays.size());
 | 
					                rep_counts.resize(delays.size());
 | 
				
			||||||
            } catch(YAML::ParserException& e) {
 | 
					            } catch(YAML::ParserException& e) {
 | 
				
			||||||
                LOG(ERR) << "Could not parse input file " << config_file_name << ", reason: " << e.what();
 | 
					                CPPLOG(ERR) << "Could not parse input file " << config_file_name << ", reason: " << e.what();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            LOG(ERR) << "Could not open input file " << config_file_name;
 | 
					            CPPLOG(ERR) << "Could not open input file " << config_file_name;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -81,7 +81,7 @@ iss::plugin::instruction_count::~instruction_count() {
 | 
				
			|||||||
    size_t idx = 0;
 | 
					    size_t idx = 0;
 | 
				
			||||||
    for(auto it : delays) {
 | 
					    for(auto it : delays) {
 | 
				
			||||||
        if(rep_counts[idx] > 0 && it.instr_name.find("__" != 0))
 | 
					        if(rep_counts[idx] > 0 && it.instr_name.find("__" != 0))
 | 
				
			||||||
            LOG(INFO) << it.instr_name << ";" << rep_counts[idx];
 | 
					            CPPLOG(INFO) << it.instr_name << ";" << rep_counts[idx];
 | 
				
			||||||
        idx++;
 | 
					        idx++;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										47
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								src/main.cpp
									
									
									
									
									
								
							@@ -35,6 +35,8 @@
 | 
				
			|||||||
#include <iostream>
 | 
					#include <iostream>
 | 
				
			||||||
#include <iss/factory.h>
 | 
					#include <iss/factory.h>
 | 
				
			||||||
#include <iss/semihosting/semihosting.h>
 | 
					#include <iss/semihosting/semihosting.h>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <unordered_map>
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "iss/arch/tgc_mapper.h"
 | 
					#include "iss/arch/tgc_mapper.h"
 | 
				
			||||||
@@ -137,11 +139,11 @@ 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) {
 | 
				
			||||||
            LOG(ERR) << "Could not create cpu for isa " << isa_opt << " and backend " << clim["backend"].as<std::string>() << std::endl;
 | 
					            CPPLOG(ERR) << "Could not create cpu for isa " << isa_opt << " and backend " << clim["backend"].as<std::string>() << std::endl;
 | 
				
			||||||
            return 127;
 | 
					            return 127;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if(!vm) {
 | 
					        if(!vm) {
 | 
				
			||||||
            LOG(ERR) << "Could not create vm for isa " << isa_opt << " and backend " << clim["backend"].as<std::string>() << std::endl;
 | 
					            CPPLOG(ERR) << "Could not create vm for isa " << isa_opt << " and backend " << clim["backend"].as<std::string>() << std::endl;
 | 
				
			||||||
            return 127;
 | 
					            return 127;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if(clim.count("plugin")) {
 | 
					        if(clim.count("plugin")) {
 | 
				
			||||||
@@ -177,7 +179,7 @@ int main(int argc, char* argv[]) {
 | 
				
			|||||||
                    } else
 | 
					                    } else
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        LOG(ERR) << "Unknown plugin name: " << plugin_name << ", valid names are 'ce', 'ic'" << std::endl;
 | 
					                        CPPLOG(ERR) << "Unknown plugin name: " << plugin_name << ", valid names are 'ce', 'ic'" << std::endl;
 | 
				
			||||||
                        return 127;
 | 
					                        return 127;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -199,12 +201,12 @@ int main(int argc, char* argv[]) {
 | 
				
			|||||||
        if(clim.count("elf"))
 | 
					        if(clim.count("elf"))
 | 
				
			||||||
            for(std::string input : clim["elf"].as<std::vector<std::string>>()) {
 | 
					            for(std::string input : clim["elf"].as<std::vector<std::string>>()) {
 | 
				
			||||||
                auto start_addr = vm->get_arch()->load_file(input);
 | 
					                auto start_addr = vm->get_arch()->load_file(input);
 | 
				
			||||||
                if(start_addr.second)
 | 
					                if(start_addr.second) // FIXME: this always evaluates to true as load file always returns <sth, true>
 | 
				
			||||||
                    start_address = start_addr.first;
 | 
					                    start_address = start_addr.first;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        for(std::string input : args) {
 | 
					        for(std::string input : args) {
 | 
				
			||||||
            auto start_addr = vm->get_arch()->load_file(input); // treat remaining arguments as elf files
 | 
					            auto start_addr = vm->get_arch()->load_file(input); // treat remaining arguments as elf files
 | 
				
			||||||
            if(start_addr.second)
 | 
					            if(start_addr.second) // FIXME: this always evaluates to true as load file always returns <sth, true>
 | 
				
			||||||
                start_address = start_addr.first;
 | 
					                start_address = start_addr.first;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if(clim.count("reset")) {
 | 
					        if(clim.count("reset")) {
 | 
				
			||||||
@@ -214,11 +216,42 @@ int main(int argc, char* argv[]) {
 | 
				
			|||||||
        vm->reset(start_address);
 | 
					        vm->reset(start_address);
 | 
				
			||||||
        auto cycles = clim["instructions"].as<uint64_t>();
 | 
					        auto cycles = clim["instructions"].as<uint64_t>();
 | 
				
			||||||
        res = vm->start(cycles, dump);
 | 
					        res = vm->start(cycles, dump);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        auto instr_if = vm->get_arch()->get_instrumentation_if();
 | 
				
			||||||
 | 
					        // this assumes a single input file
 | 
				
			||||||
 | 
					        std::unordered_map<std::string, uint64_t> sym_table;
 | 
				
			||||||
 | 
					        if(args.empty())
 | 
				
			||||||
 | 
					            sym_table = instr_if->get_symbol_table(clim["elf"].as<std::vector<std::string>>()[0]);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            sym_table = instr_if->get_symbol_table(args[0]);
 | 
				
			||||||
 | 
					        if(sym_table.find("begin_signature") != std::end(sym_table) && sym_table.find("end_signature") != std::end(sym_table)) {
 | 
				
			||||||
 | 
					            auto start_addr = sym_table["begin_signature"];
 | 
				
			||||||
 | 
					            auto end_addr = sym_table["end_signature"];
 | 
				
			||||||
 | 
					            std::array<uint8_t, 4> data;
 | 
				
			||||||
 | 
					            std::ofstream file;
 | 
				
			||||||
 | 
					            std::string filename = fmt::format("{}.signature", isa_opt);
 | 
				
			||||||
 | 
					            std::replace(std::begin(filename), std::end(filename), '|', '_');
 | 
				
			||||||
 | 
					            // default riscof requires this filename
 | 
				
			||||||
 | 
					            filename = "DUT-tgc.signature";
 | 
				
			||||||
 | 
					            file.open(filename, std::ios::out);
 | 
				
			||||||
 | 
					            if(!file.is_open()) {
 | 
				
			||||||
 | 
					                LOG(ERR) << "Error opening file " << filename << std::endl;
 | 
				
			||||||
 | 
					                return 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            for(auto addr = start_addr; addr < end_addr; addr += data.size()) {
 | 
				
			||||||
 | 
					                vm->get_arch()->read(iss::address_type::PHYSICAL, iss::access_type::DEBUG_READ, 0 /*MEM*/, addr, data.size(),
 | 
				
			||||||
 | 
					                                     data.data()); // FIXME: get space from iss::arch::traits<ARCH>::mem_type_e::MEM
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // TODO : obey Target endianess
 | 
				
			||||||
 | 
					                uint32_t to_print = (data[3] << 24) + (data[2] << 16) + (data[1] << 8) + data[0];
 | 
				
			||||||
 | 
					                file << std::hex << fmt::format("{:08x}", to_print) << std::dec << std::endl;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    } catch(std::exception& e) {
 | 
					    } catch(std::exception& e) {
 | 
				
			||||||
        LOG(ERR) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit" << std::endl;
 | 
					        CPPLOG(ERR) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit" << std::endl;
 | 
				
			||||||
        res = 2;
 | 
					        res = 2;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // cleanup to let plugins report of needed
 | 
					    // cleanup to let plugins report if needed
 | 
				
			||||||
    for(auto* p : plugin_list) {
 | 
					    for(auto* p : plugin_list) {
 | 
				
			||||||
        delete p;
 | 
					        delete p;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user