3 Commits

Author SHA1 Message Date
31c6bb55f4 applies clang format 2025-03-16 14:38:45 +01:00
63d0162119 adds license header 2025-03-16 13:33:01 +01:00
3b294d9da0 fixes sc_core_adapter wrt refactored memory hierarchy 2025-03-16 12:29:03 +01:00
19 changed files with 528 additions and 160 deletions

View File

@ -1,3 +1,37 @@
/*******************************************************************************
* Copyright (C) 2024 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Contributors:
* eyck@minres.com - initial implementation
******************************************************************************/
#ifdef _MSC_VER
#define _SCL_SECURE_NO_WARNINGS
#define ELFIO_NO_INTTYPES
@ -32,4 +66,4 @@ int main(int argc, char** argv) {
dump::segment_datas(std::cout, reader);
return 0;
}
}

View File

@ -35,9 +35,10 @@
#ifndef _RISCV_HART_COMMON
#define _RISCV_HART_COMMON
#include "iss/arch/traits.h"
#include "iss/log_categories.h"
#include "iss/vm_types.h"
#include <iss/arch/traits.h>
#include <iss/log_categories.h>
#include <iss/mem/memory_if.h>
#include <iss/vm_types.h>
#include "mstatus.h"
#include "util/delegate.h"
#include <array>
@ -53,7 +54,6 @@
#include <unordered_map>
#include <util/logging.h>
#include <util/sparse_array.h>
#include "../mem/memory_if.h"
#if defined(__GNUC__)
#define likely(x) ::__builtin_expect(!!(x), 1)
@ -249,7 +249,7 @@ template <typename WORD_TYPE> struct priv_if {
std::function<iss::status(unsigned, WORD_TYPE&)> read_csr;
std::function<iss::status(unsigned, WORD_TYPE)> write_csr;
std::function<iss::status(uint8_t const*)> exec_htif;
std::function<void(uint16_t,uint16_t,WORD_TYPE)> raise_trap; // trap_id, cause, fault_data
std::function<void(uint16_t, uint16_t, WORD_TYPE)> raise_trap; // trap_id, cause, fault_data
std::unordered_map<unsigned, rd_csr_f>& csr_rd_cb;
std::unordered_map<unsigned, wr_csr_f>& csr_wr_cb;
hart_state<WORD_TYPE>& state;
@ -365,6 +365,7 @@ template <typename BASE, typename LOGCAT = logging::disass> struct riscv_hart_co
csr_wr_cb[minstreth] = MK_CSR_WR_CB(write_instret);
csr_rd_cb[mhartid] = MK_CSR_RD_CB(read_hartid);
};
~riscv_hart_common() {
if(io_buf.str().length()) {
CPPLOG(INFO) << "tohost send '" << io_buf.str() << "'";
@ -427,14 +428,12 @@ template <typename BASE, typename LOGCAT = logging::disass> struct riscv_hart_co
#endif
}
}
try {
tohost = symbol_table.at("tohost");
} catch(std::out_of_range& e) {
}
try {
fromhost = symbol_table.at("fromhost");
} catch(std::out_of_range& e) {
}
auto to_it = symbol_table.find("tohost");
if(to_it != std::end(symbol_table))
tohost = to_it->second;
auto from_it = symbol_table.find("tohost");
if(from_it != std::end(symbol_table))
tohost = from_it->second;
}
return true;
}
@ -689,11 +688,11 @@ template <typename BASE, typename LOGCAT = logging::disass> struct riscv_hart_co
return priv_if<reg_t>{.read_csr = [this](unsigned addr, reg_t& val) -> iss::status { return read_csr(addr, val); },
.write_csr = [this](unsigned addr, reg_t val) -> iss::status { return write_csr(addr, val); },
.exec_htif = [this](uint8_t const* data) -> iss::status { return execute_htif(data); },
.raise_trap = [this](uint16_t trap_id, uint16_t cause, reg_t fault_data){
this->reg.trap_state = 0x80ULL << 24 | (cause << 16) | trap_id;
this->fault_data = fault_data;
},
.raise_trap =
[this](uint16_t trap_id, uint16_t cause, reg_t fault_data) {
this->reg.trap_state = 0x80ULL << 24 | (cause << 16) | trap_id;
this->fault_data = fault_data;
},
.csr_rd_cb{this->csr_rd_cb},
.csr_wr_cb{csr_wr_cb},
.state{this->state},
@ -743,12 +742,12 @@ template <typename BASE, typename LOGCAT = logging::disass> struct riscv_hart_co
mem::memory_hierarchy memories;
virtual mem::memory_if get_mem_if() override {
assert(false || "This function should nevver be called");
mem::memory_if get_mem_if() override {
assert(false || "This function should never be called");
return mem::memory_if{};
}
virtual void set_next(mem::memory_if mem_if) { memory = mem_if; };
void set_next(mem::memory_if mem_if) override { memory = mem_if; };
void set_irq_num(unsigned i) { mcause_max_irq = 1 << util::ilog2(i); }

View File

@ -45,10 +45,10 @@
#ifndef FMT_HEADER_ONLY
#define FMT_HEADER_ONLY
#endif
#include <iss/mem/memory_with_htif.h>
#include <array>
#include <elfio/elfio.hpp>
#include <fmt/format.h>
#include "../mem/memory_with_htif.h"
#include <unordered_map>
namespace iss {
@ -157,12 +157,7 @@ protected:
template <typename BASE, features_e FEAT, typename LOGCAT>
riscv_hart_m_p<BASE, FEAT, LOGCAT>::riscv_hart_m_p()
: default_mem(base::get_priv_if()) {
const std::array<unsigned, 4> rwaddrs{{
mepc,
mtvec,
mscratch,
mtval
}};
const std::array<unsigned, 4> rwaddrs{{mepc, mtvec, mscratch, mtval}};
for(auto addr : rwaddrs) {
this->csr_rd_cb[addr] = MK_CSR_RD_CB(read_plain);
this->csr_wr_cb[addr] = MK_CSR_WR_CB(write_plain);

View File

@ -40,24 +40,25 @@
#include "riscv_hart_common.h"
#include "util/logging.h"
#include <algorithm>
#include <cstdint>
#include <array>
#include <cstdint>
#include <elfio/elf_types.hpp>
#include <elfio/elfio.hpp>
#include <limits>
#ifndef FMT_HEADER_ONLY
#define FMT_HEADER_ONLY
#endif
#include <iss/mem/memory_with_htif.h>
#include <iss/mem/mmu.h>
#include <fmt/format.h>
#include <type_traits>
#include <unordered_map>
#include "../mem/mmu.h"
#include "../mem/memory_with_htif.h"
namespace iss {
namespace arch {
template <typename BASE, features_e FEAT = FEAT_NONE, typename LOGCAT = logging::disass> class riscv_hart_msu_vp : public riscv_hart_common<BASE> {
template <typename BASE, features_e FEAT = FEAT_NONE, typename LOGCAT = logging::disass>
class riscv_hart_msu_vp : public riscv_hart_common<BASE> {
public:
using core = BASE;
using base = riscv_hart_common<BASE>;
@ -171,25 +172,8 @@ riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::riscv_hart_msu_vp()
, mmu(base::get_priv_if())
, default_mem(base::get_priv_if()) {
// common regs
const std::array<unsigned, 17> rwaddrs{{
mepc,
mtvec,
mscratch,
mtval,
mscratch,
sepc,
stvec,
sscratch,
scause,
stval,
sscratch,
uepc,
utvec,
uscratch,
ucause,
utval,
uscratch
}};
const std::array<unsigned, 17> rwaddrs{{mepc, mtvec, mscratch, mtval, mscratch, sepc, stvec, sscratch, scause, stval, sscratch, uepc,
utvec, uscratch, ucause, utval, uscratch}};
for(auto addr : rwaddrs) {
this->csr_rd_cb[addr] = MK_CSR_RD_CB(read_plain);
this->csr_wr_cb[addr] = MK_CSR_WR_CB(write_plain);
@ -246,7 +230,7 @@ riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::riscv_hart_msu_vp()
template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::read(const address_type type, const access_type access, const uint32_t space,
const uint64_t addr, const unsigned length, uint8_t* const data) {
const uint64_t addr, const unsigned length, uint8_t* const data) {
#ifndef NDEBUG
if(access && iss::access_type::DEBUG) {
CPPLOG(TRACEALL) << "debug read of " << length << " bytes @addr 0x" << std::hex << addr;
@ -264,7 +248,7 @@ iss::status riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::read(const address_type type,
this->fault_data = addr;
if(is_debug(access))
throw trap_access(0, addr);
this->reg.trap_state = (1UL<< 31); // issue trap 0
this->reg.trap_state = (1UL << 31); // issue trap 0
return iss::Err;
}
try {
@ -328,8 +312,8 @@ iss::status riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::read(const address_type type,
}
template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::write(const address_type type, const access_type access, const uint32_t space, const uint64_t addr,
const unsigned length, const uint8_t* const data) {
iss::status riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::write(const address_type type, const access_type access, const uint32_t space,
const uint64_t addr, const unsigned length, const uint8_t* const data) {
#ifndef NDEBUG
const char* prefix = (access && iss::access_type::DEBUG) ? "debug " : "";
switch(length) {
@ -417,25 +401,29 @@ iss::status riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::write(const address_type type
}
}
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::read_status(unsigned addr, reg_t& val) {
template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::read_status(unsigned addr, reg_t& val) {
auto req_priv_lvl = (addr >> 8) & 0x3;
val = state.mstatus & get_mstatus_mask(req_priv_lvl);
return iss::Ok;
}
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::write_status(unsigned addr, reg_t val) {
template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::write_status(unsigned addr, reg_t val) {
auto req_priv_lvl = (addr >> 8) & 0x3;
write_mstatus(val, req_priv_lvl);
check_interrupt();
return iss::Ok;
}
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::write_cause(unsigned addr, reg_t val) {
template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::write_cause(unsigned addr, reg_t val) {
this->csr[addr] = val & ((1UL << (traits<BASE>::XLEN - 1)) | 0xf); // TODO: make exception code size configurable
return iss::Ok;
}
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::read_ie(unsigned addr, reg_t& val) {
template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::read_ie(unsigned addr, reg_t& val) {
val = this->csr[mie];
if(addr < mie)
val &= this->csr[mideleg];
@ -444,7 +432,8 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return iss::Ok;
}
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::write_ie(unsigned addr, reg_t val) {
template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::write_ie(unsigned addr, reg_t val) {
auto req_priv_lvl = (addr >> 8) & 0x3;
auto mask = get_irq_mask(req_priv_lvl);
this->csr[mie] = (this->csr[mie] & ~mask) | (val & mask);
@ -452,7 +441,8 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return iss::Ok;
}
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::read_ip(unsigned addr, reg_t& val) {
template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::read_ip(unsigned addr, reg_t& val) {
val = this->csr[mip];
if(addr < mip)
val &= this->csr[mideleg];
@ -494,8 +484,8 @@ template <typename BASE, features_e FEAT, typename LOGCAT> void riscv_hart_msu_v
}
}
template <typename BASE, features_e FEAT, typename LOGCAT> uint64_t riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::enter_trap(uint64_t flags, uint64_t addr, uint64_t instr) {
template <typename BASE, features_e FEAT, typename LOGCAT>
uint64_t riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::enter_trap(uint64_t flags, uint64_t addr, uint64_t instr) {
// flags are ACTIVE[31:31], CAUSE[30:16], TRAPID[15:0]
// calculate and write mcause val
if(flags == std::numeric_limits<uint64_t>::max())
@ -624,9 +614,9 @@ template <typename BASE, features_e FEAT, typename LOGCAT> uint64_t riscv_hart_m
#endif
if((flags & 0xffffffff) != 0xffffffff)
NSCLOG(INFO, LOGCAT) << (trap_id ? "Interrupt" : "Trap") << " with cause '"
<< (trap_id ? this->irq_str[cause] : this->trap_str[cause]) << "' (" << cause << ")"
<< " at address " << buffer.data() << " occurred, changing privilege level from " << this->lvl[this->reg.PRIV]
<< " to " << this->lvl[new_priv];
<< (trap_id ? this->irq_str[cause] : this->trap_str[cause]) << "' (" << cause << ")"
<< " at address " << buffer.data() << " occurred, changing privilege level from " << this->lvl[this->reg.PRIV]
<< " to " << this->lvl[new_priv];
// reset trap state
this->reg.PRIV = new_priv;
this->reg.trap_state = 0;
@ -667,7 +657,7 @@ template <typename BASE, features_e FEAT, typename LOGCAT> uint64_t riscv_hart_m
// sets the pc to the value stored in the x epc register.
this->reg.NEXT_PC = this->csr[uepc | inst_priv << 8];
NSCLOG(INFO, LOGCAT) << "Executing xRET , changing privilege level from " << this->lvl[cur_priv] << " to "
<< this->lvl[this->reg.PRIV];
<< this->lvl[this->reg.PRIV];
check_interrupt();
}
this->reg.trap_state = this->reg.pending_trap;

View File

@ -40,15 +40,15 @@
#include "riscv_hart_common.h"
#include "util/logging.h"
#include <algorithm>
#include <cstdint>
#include <array>
#include <cstdint>
#include <elfio/elf_types.hpp>
#include <elfio/elfio.hpp>
#ifndef FMT_HEADER_ONLY
#define FMT_HEADER_ONLY
#endif
#include <iss/mem/memory_with_htif.h>
#include <fmt/format.h>
#include "../mem/memory_with_htif.h"
#include <unordered_map>
namespace iss {
@ -71,7 +71,7 @@ public:
#else
switch(priv_lvl) {
case PRIV_U:
return FEAT & features_e::FEAT_EXT_N? 0x00000011UL : 0UL; // 0b1...0 0001 0001
return FEAT & features_e::FEAT_EXT_N ? 0x00000011UL : 0UL; // 0b1...0 0001 0001
default:
// +-SD
// | +-TSR
@ -97,7 +97,7 @@ public:
#else
switch(priv_lvl) {
case PRIV_U:
return FEAT & features_e::FEAT_EXT_N? 0x8000000000000011ULL : 0ULL; // 0b1...0 0001 0001
return FEAT & features_e::FEAT_EXT_N ? 0x8000000000000011ULL : 0ULL; // 0b1...0 0001 0001
default:
// +-TSR
// |+-TW
@ -251,7 +251,7 @@ riscv_hart_mu_p<BASE, FEAT, LOGCAT>::riscv_hart_mu_p()
template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read(const address_type type, const access_type access, const uint32_t space,
const uint64_t addr,const unsigned length, uint8_t* const data) {
const uint64_t addr, const unsigned length, uint8_t* const data) {
#ifndef NDEBUG
if(access && iss::access_type::DEBUG) {
CPPLOG(TRACEALL) << "debug read of " << length << " bytes @addr 0x" << std::hex << addr;
@ -618,9 +618,9 @@ uint64_t riscv_hart_mu_p<BASE, FEAT, LOGCAT>::enter_trap(uint64_t flags, uint64_
#endif
if((flags & 0xffffffff) != 0xffffffff)
NSCLOG(INFO, LOGCAT) << (trap_id ? "Interrupt" : "Trap") << " with cause '"
<< (trap_id ? this->irq_str[cause] : this->trap_str[cause]) << "' (" << cause << ")"
<< " at address " << buffer.data() << " occurred, changing privilege level from " << this->lvl[this->reg.PRIV]
<< " to " << this->lvl[new_priv];
<< (trap_id ? this->irq_str[cause] : this->trap_str[cause]) << "' (" << cause << ")"
<< " at address " << buffer.data() << " occurred, changing privilege level from " << this->lvl[this->reg.PRIV]
<< " to " << this->lvl[new_priv];
// reset trap state
this->reg.PRIV = new_priv;
this->reg.trap_state = 0;
@ -653,7 +653,7 @@ template <typename BASE, features_e FEAT, typename LOGCAT> uint64_t riscv_hart_m
// sets the pc to the value stored in the x epc register.
this->reg.NEXT_PC = this->csr[uepc | inst_priv << 8];
NSCLOG(INFO, LOGCAT) << "Executing xRET , changing privilege level from " << this->lvl[cur_priv] << " to "
<< this->lvl[this->reg.PRIV];
<< this->lvl[this->reg.PRIV];
check_interrupt();
}
this->reg.trap_state = this->reg.pending_trap;

View File

@ -1,3 +1,37 @@
/*******************************************************************************
* Copyright (C) 2023 - 2025 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Contributors:
* eyck@minres.com - initial implementation
******************************************************************************/
#ifndef _ISS_ARCH_TGC_MAPPER_H
#define _ISS_ARCH_TGC_MAPPER_H
@ -28,8 +62,7 @@ using tgc5d_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc5d, (iss::arch:
#ifdef CORE_TGC5D_XRB_MAC
#include "riscv_hart_mu_p.h"
#include <iss/arch/tgc5d_xrb_mac.h>
using tgc5d_xrb_mac_plat_type =
iss::arch::riscv_hart_mu_p<iss::arch::tgc5d_xrb_mac (iss::arch::features_e)(iss::arch::FEAT_EXT_N)>;
using tgc5d_xrb_mac_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc5d_xrb_mac(iss::arch::features_e)(iss::arch::FEAT_EXT_N)>;
#endif
#ifdef CORE_TGC5D_XRB_NN
#include "hwl.h"

View File

@ -1,3 +1,37 @@
/*******************************************************************************
* Copyright (C) 2025 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Contributors:
* eyck@minres.com - initial implementation
******************************************************************************/
#include <array>
// generated from:
// * /scratch/eyck/workarea/Other/riscv-opcodes/csrs.csv

View File

@ -1,8 +1,41 @@
/*******************************************************************************
* Copyright (C) 2025 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Contributors:
* eyck@minres.com - initial implementation
******************************************************************************/
#include "memory_if.h"
#include "iss/arch/riscv_hart_common.h"
#include "iss/vm_types.h"
#include <util/logging.h>
#include "../mem/memory_if.h"
namespace iss {
namespace mem {

View File

@ -1,3 +1,37 @@
/*******************************************************************************
* Copyright (C) 2025 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Contributors:
* eyck@minres.com - initial implementation
******************************************************************************/
#include "memory_if.h"
#include <algorithm>
@ -5,12 +39,12 @@ namespace iss {
namespace mem {
void memory_hierarchy::root(memory_elem& e) {
hierarchy.push_front(&e);
root_set=true;
root_set = true;
update_chain();
}
void memory_hierarchy::prepend(memory_elem& e) {
if(root_set)
hierarchy.insert(hierarchy.begin()+1, &e);
hierarchy.insert(hierarchy.begin() + 1, &e);
else
hierarchy.push_front(&e);
update_chain();
@ -22,15 +56,19 @@ void memory_hierarchy::append(memory_elem& e) {
void memory_hierarchy::insert_before(memory_elem&) {}
void memory_hierarchy::insert_after(memory_elem&) {}
void memory_hierarchy::replace_last(memory_elem& e) {
auto old = hierarchy.back();
auto it = std::find_if(std::begin(owned_elems), std::end(owned_elems),
[old](std::unique_ptr<memory_elem> const& p) { return p.get() == old; });
hierarchy.pop_back();
if(it != std::end(owned_elems))
owned_elems.erase(it);
hierarchy.push_back(&e);
update_chain();
}
void memory_hierarchy::update_chain() {
bool tail = false;
for(size_t i = 0; i < hierarchy.size(); ++i) {
hierarchy[i]->register_csrs();
if(i)
hierarchy[i - 1]->set_next(hierarchy[i]->get_mem_if());
for(size_t i = 1; i < hierarchy.size(); ++i) {
hierarchy[i - 1]->set_next(hierarchy[i]->get_mem_if());
}
}
@ -55,11 +93,7 @@ void memory_hierarchy::insert_after(std::unique_ptr<memory_elem>&& p) {
}
void memory_hierarchy::replace_last(std::unique_ptr<memory_elem>&& p) {
auto e = hierarchy.back();
replace_last(*p);
auto it = std::find_if(std::begin(owned_elems), std::end(owned_elems), [e](std::unique_ptr<memory_elem> const& p) {return p.get()==e;});
if(it!=std::end(owned_elems))
owned_elems.erase(it);
owned_elems.push_back(std::move(p));
}

View File

@ -37,11 +37,11 @@
#include "iss/vm_types.h"
#include <deque>
#include <vector>
#include <functional>
#include <limits>
#include <util/delegate.h>
#include <memory>
#include <util/delegate.h>
#include <vector>
namespace iss {
namespace mem {
@ -58,7 +58,6 @@ struct memory_elem {
virtual ~memory_elem() = default;
virtual memory_if get_mem_if() = 0;
virtual void set_next(memory_if) = 0;
virtual void register_csrs() {}
virtual std::tuple<uint64_t, uint64_t> get_range() { return {0, std::numeric_limits<uint64_t>::max()}; }
};

View File

@ -1,11 +1,45 @@
/*******************************************************************************
* Copyright (C) 2025 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Contributors:
* eyck@minres.com - initial implementation
******************************************************************************/
#ifndef _MEMORY_WITH_HTIF_
#define _MEMORY_WITH_HTIF_
#include "memory_if.h"
#include "iss/arch/riscv_hart_common.h"
#include "iss/vm_types.h"
#include <util/logging.h>
#include <util/sparse_array.h>
#include "../mem/memory_if.h"
namespace iss {
namespace mem {

View File

@ -1,8 +1,41 @@
/*******************************************************************************
* Copyright (C) 2025 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Contributors:
* eyck@minres.com - initial implementation
******************************************************************************/
#include "memory_if.h"
#include "iss/arch/riscv_hart_common.h"
#include "iss/vm_types.h"
#include <util/logging.h>
#include "../mem/memory_if.h"
namespace iss {
namespace mem {
@ -21,7 +54,6 @@ enum {
PTE_SOFT = 0x300 // Reserved for Software
};
template <typename T> inline bool PTE_TABLE(T PTE) { return (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V); }
struct vm_info {
@ -73,7 +105,7 @@ inline void write_reg_with_offset(uint32_t& reg, uint8_t offs, const uint8_t* co
break;
}
}
//TODO: update vminfo on trap enter and leave as well as mstatus write, reset
// TODO: update vminfo on trap enter and leave as well as mstatus write, reset
template <typename WORD_TYPE> struct mmu : public memory_elem {
using this_class = mmu<WORD_TYPE>;
using reg_t = WORD_TYPE;
@ -82,13 +114,11 @@ template <typename WORD_TYPE> struct mmu : public memory_elem {
constexpr static reg_t PGSIZE = 1 << PGSHIFT;
constexpr static reg_t PGMASK = PGSIZE - 1;
mmu(arch::priv_if<WORD_TYPE> hart_if)
: hart_if(hart_if) {
hart_if.csr_rd_cb[satp] = MK_CSR_RD_CB(read_satp);
hart_if.csr_wr_cb[satp] = MK_CSR_WR_CB(write_satp);
}
}
virtual ~mmu() = default;
@ -123,7 +153,7 @@ private:
auto len1 = split_addr - addr;
auto res = down_stream_mem.wr_mem(access, addr, len1, data);
if(res == iss::Ok)
res = down_stream_mem.wr_mem(access, split_addr, length - len1, data + len1);
res = down_stream_mem.wr_mem(access, split_addr, length - len1, data + len1);
return res;
}
}
@ -144,9 +174,9 @@ private:
iss::status read_satp(unsigned addr, reg_t& val) {
auto tvm = bit_sub<20, 1>(hart_if.state.mstatus());
if(hart_if.PRIV == arch::PRIV_S & tvm != 0) {
hart_if.raise_trap(2, 0, hart_if.PC);
// hart_if.reg.trap_state = (1 << 31) | (2 << 16);
// hart_if.fault_data = hart_if.reg.PC;
hart_if.raise_trap(2, 0, hart_if.PC);
// hart_if.reg.trap_state = (1 << 31) | (2 << 16);
// hart_if.fault_data = hart_if.reg.PC;
return iss::Err;
}
val = satp;
@ -156,9 +186,9 @@ private:
iss::status write_satp(unsigned addr, reg_t val) {
reg_t tvm = hart_if.state.mstatus.TVM;
if(hart_if.PRIV == arch::PRIV_S & tvm != 0) {
hart_if.raise_trap(2, 0, hart_if.PC);
// hart_if.reg.trap_state = (1 << 31) | (2 << 16);
// hart_if.fault_data = hart_if.reg.PC;
hart_if.raise_trap(2, 0, hart_if.PC);
// hart_if.reg.trap_state = (1 << 31) | (2 << 16);
// hart_if.fault_data = hart_if.reg.PC;
return iss::Err;
}
satp = val;
@ -216,7 +246,7 @@ protected:
memory_if down_stream_mem;
};
template <typename WORD_TYPE> uint64_t mmu<WORD_TYPE>::virt2phys(iss::access_type access, uint64_t addr) {
template <typename WORD_TYPE> uint64_t mmu<WORD_TYPE>::virt2phys(iss::access_type access, uint64_t addr) {
const auto type = access & iss::access_type::FUNC;
auto it = ptw.find(addr >> PGSHIFT);
if(it != ptw.end()) {
@ -235,8 +265,8 @@ template <typename WORD_TYPE> uint64_t mmu<WORD_TYPE>::virt2phys(iss::access_ty
#endif
} else {
uint32_t mode = type != iss::access_type::FETCH && hart_if.state.mstatus.MPRV ? // MPRV
hart_if.state.mstatus.MPP
: hart_if.PRIV;
hart_if.state.mstatus.MPP
: hart_if.PRIV;
const vm_info& vm = vmt[static_cast<uint16_t>(type) / 2];
@ -246,7 +276,7 @@ template <typename WORD_TYPE> uint64_t mmu<WORD_TYPE>::virt2phys(iss::access_ty
// verify bits xlen-1:va_bits-1 are all equal
const int va_bits = PGSHIFT + vm.levels * vm.idxbits;
const reg_t mask = (reg_t(1) << (sizeof(reg_t)*8 - (va_bits - 1))) - 1;
const reg_t mask = (reg_t(1) << (sizeof(reg_t) * 8 - (va_bits - 1))) - 1;
const reg_t masked_msbs = (addr >> (va_bits - 1)) & mask;
const int levels = (masked_msbs != 0 && masked_msbs != mask) ? 0 : vm.levels;
@ -257,8 +287,7 @@ template <typename WORD_TYPE> uint64_t mmu<WORD_TYPE>::virt2phys(iss::access_ty
// check that physical address of PTE is legal
reg_t pte = 0;
const uint8_t res = down_stream_mem.rd_mem(iss::access_type::READ, base + idx * vm.ptesize, vm.ptesize,
(uint8_t*)&pte);
const uint8_t res = down_stream_mem.rd_mem(iss::access_type::READ, base + idx * vm.ptesize, vm.ptesize, (uint8_t*)&pte);
if(res != 0)
throw arch::trap_load_access_fault(addr);
const reg_t ppn = pte >> PTE_PPN_SHIFT;
@ -320,6 +349,5 @@ template <typename WORD_TYPE> inline void mmu<WORD_TYPE>::update_vm_info() {
ptw.clear();
}
} // namespace mem
} // namespace iss

View File

@ -1,8 +1,41 @@
/*******************************************************************************
* Copyright (C) 2025 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Contributors:
* eyck@minres.com - initial implementation
******************************************************************************/
#include "memory_if.h"
#include "iss/arch/riscv_hart_common.h"
#include "iss/vm_types.h"
#include <util/logging.h>
#include "../mem/memory_if.h"
namespace iss {
namespace mem {

View File

@ -1,3 +1,37 @@
/*******************************************************************************
* Copyright (C) 2025 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Contributors:
* eyck@minres.com - initial implementation
******************************************************************************/
#include "semihosting.h"
#include <chrono>
#include <cstdint>

View File

@ -1,3 +1,37 @@
/*******************************************************************************
* Copyright (C) 2025 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Contributors:
* eyck@minres.com - initial implementation
******************************************************************************/
#ifndef _SEMIHOSTING_H_
#define _SEMIHOSTING_H_
#include <chrono>
@ -58,4 +92,4 @@ template <typename T> struct semihosting_callback {
};
template <typename T> using semihosting_cb_t = std::function<void(iss::arch_if*, T*, T*)>;
#endif
#endif

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (C) 2017, 2018 MINRES Technologies GmbH
* Copyright (C) 2017 - 2025 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -419,7 +419,7 @@ template <unsigned int BUSWIDTH> bool core_complex<BUSWIDTH>::read_mem(uint64_t
gp.set_extension(preExt);
}
auto pre_delay = delay;
dbus->b_transport(gp, delay);
sckt->b_transport(gp, delay);
if(pre_delay > delay) {
quantum_keeper.reset();
} else {

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (C) 2017-2021 MINRES Technologies GmbH
* Copyright (C) 2017 - 2025 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -1,9 +1,36 @@
/*
* sc_core_adapter.h
/*******************************************************************************
* Copyright (C) 2023 - 2025 MINRES Technologies GmbH
* All rights reserved.
*
* Created on: Jul 5, 2023
* Author: eyck
*/
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Contributors:
* eyck@minres.com - initial implementation
******************************************************************************/
#ifndef _SYSC_SC_CORE_ADAPTER_H_
#define _SYSC_SC_CORE_ADAPTER_H_
@ -11,6 +38,7 @@
#include "sc_core_adapter_if.h"
#include <iostream>
#include <iss/iss.h>
#include <iss/mem/memory_if.h>
#include <iss/vm_types.h>
#include <scc/report.h>
#include <util/ities.h>
@ -18,11 +46,16 @@
namespace sysc {
template <typename PLAT> class sc_core_adapter : public PLAT, public sc_core_adapter_if {
public:
using this_class = sc_core_adapter<PLAT>;
using reg_t = typename iss::arch::traits<typename PLAT::core>::reg_t;
using phys_addr_t = typename iss::arch::traits<typename PLAT::core>::phys_addr_t;
using heart_state_t = typename PLAT::hart_state_type;
sc_core_adapter(sysc::tgfs::core_complex_if* owner)
: owner(owner) {}
: owner(owner) {
this->csr_rd_cb[iss::arch::time] = MK_CSR_RD_CB(read_time);
if(sizeof(reg_t) == 4)
this->csr_rd_cb[iss::arch::timeh] = MK_CSR_RD_CB(read_time);
this->memories.replace_last(*this);
}
iss::arch_if* get_arch_if() override { return this; }
@ -60,18 +93,23 @@ public:
}
};
iss::status read_mem(phys_addr_t addr, unsigned length, uint8_t* const data) override {
if(addr.access && iss::access_type::DEBUG)
return owner->read_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err;
iss::mem::memory_if get_mem_if() override {
return iss::mem::memory_if{.rd_mem{util::delegate<iss::mem::rd_mem_func_sig>::from<this_class, &this_class::read_mem>(this)},
.wr_mem{util::delegate<iss::mem::wr_mem_func_sig>::from<this_class, &this_class::write_mem>(this)}};
}
iss::status read_mem(iss::access_type access, uint64_t addr, unsigned length, uint8_t* data) {
if(access && iss::access_type::DEBUG)
return owner->read_mem_dbg(addr, length, data) ? iss::Ok : iss::Err;
else {
return owner->read_mem(addr.val, length, data, is_fetch(addr.access)) ? iss::Ok : iss::Err;
return owner->read_mem(addr, length, data, is_fetch(access)) ? iss::Ok : iss::Err;
}
}
iss::status write_mem(phys_addr_t addr, unsigned length, const uint8_t* const data) override {
if(addr.access && iss::access_type::DEBUG)
return owner->write_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err;
if(addr.val == this->tohost) {
iss::status write_mem(iss::access_type access, uint64_t addr, unsigned length, uint8_t const* data) {
if(access && iss::access_type::DEBUG)
return owner->write_mem_dbg(addr, length, data) ? iss::Ok : iss::Err;
if(addr == this->tohost) {
reg_t cur_data = *reinterpret_cast<const reg_t*>(data);
// Extract Device (bits 63:56)
uint8_t device = sizeof(reg_t) == 4 ? 0 : (cur_data >> 56) & 0xFF;
@ -117,31 +155,20 @@ public:
this->interrupt_sim = payload_addr;
return iss::Ok;
}
auto res = owner->write_mem(addr.val, length, data) ? iss::Ok : iss::Err;
// clear MTIP on mtimecmp write
if(addr.val == 0x2004000) {
reg_t val;
this->read_csr(iss::arch::mip, val);
if(val & (1ULL << 7))
this->write_csr(iss::arch::mip, val & ~(1ULL << 7));
}
auto res = owner->write_mem(addr, length, data) ? iss::Ok : iss::Err;
return res;
}
iss::status read_csr(unsigned addr, reg_t& val) override {
if((addr == iss::arch::time || addr == iss::arch::timeh)) {
uint64_t time_val = owner->mtime_i.get_interface() ? owner->mtime_i.read() : 0;
if(addr == iss::arch::time) {
val = static_cast<reg_t>(time_val);
} else if(addr == iss::arch::timeh) {
if(sizeof(reg_t) != 4)
return iss::Err;
val = static_cast<reg_t>(time_val >> 32);
}
return iss::Ok;
} else {
return PLAT::read_csr(addr, val);
iss::status read_time(unsigned addr, reg_t& val) {
uint64_t time_val = owner->mtime_i.get_interface() ? owner->mtime_i.read() : 0;
if(addr == iss::arch::time) {
val = static_cast<reg_t>(time_val);
} else if(addr == iss::arch::timeh) {
if(sizeof(reg_t) != 4)
return iss::Err;
val = static_cast<reg_t>(time_val >> 32);
}
return iss::Ok;
}
void wait_until(uint64_t flags) override {

View File

@ -1,9 +1,36 @@
/*
* sc_core_adapter.h
/*******************************************************************************
* Copyright (C) 2023 MINRES Technologies GmbH
* All rights reserved.
*
* Created on: Jul 5, 2023
* Author: eyck
*/
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Contributors:
* eyck@minres.com - initial implementation
******************************************************************************/
#ifndef _SYSC_SC_CORE_ADAPTER_IF_H_
#define _SYSC_SC_CORE_ADAPTER_IF_H_