Compare commits
3 Commits
54233b448d
...
31c6bb55f4
Author | SHA1 | Date | |
---|---|---|---|
31c6bb55f4 | |||
63d0162119 | |||
3b294d9da0 |
@ -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
|
#ifdef _MSC_VER
|
||||||
#define _SCL_SECURE_NO_WARNINGS
|
#define _SCL_SECURE_NO_WARNINGS
|
||||||
#define ELFIO_NO_INTTYPES
|
#define ELFIO_NO_INTTYPES
|
||||||
|
@ -35,9 +35,10 @@
|
|||||||
#ifndef _RISCV_HART_COMMON
|
#ifndef _RISCV_HART_COMMON
|
||||||
#define _RISCV_HART_COMMON
|
#define _RISCV_HART_COMMON
|
||||||
|
|
||||||
#include "iss/arch/traits.h"
|
#include <iss/arch/traits.h>
|
||||||
#include "iss/log_categories.h"
|
#include <iss/log_categories.h>
|
||||||
#include "iss/vm_types.h"
|
#include <iss/mem/memory_if.h>
|
||||||
|
#include <iss/vm_types.h>
|
||||||
#include "mstatus.h"
|
#include "mstatus.h"
|
||||||
#include "util/delegate.h"
|
#include "util/delegate.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
@ -53,7 +54,6 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <util/logging.h>
|
#include <util/logging.h>
|
||||||
#include <util/sparse_array.h>
|
#include <util/sparse_array.h>
|
||||||
#include "../mem/memory_if.h"
|
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
#define likely(x) ::__builtin_expect(!!(x), 1)
|
#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&)> read_csr;
|
||||||
std::function<iss::status(unsigned, WORD_TYPE)> write_csr;
|
std::function<iss::status(unsigned, WORD_TYPE)> write_csr;
|
||||||
std::function<iss::status(uint8_t const*)> exec_htif;
|
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, rd_csr_f>& csr_rd_cb;
|
||||||
std::unordered_map<unsigned, wr_csr_f>& csr_wr_cb;
|
std::unordered_map<unsigned, wr_csr_f>& csr_wr_cb;
|
||||||
hart_state<WORD_TYPE>& state;
|
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_wr_cb[minstreth] = MK_CSR_WR_CB(write_instret);
|
||||||
csr_rd_cb[mhartid] = MK_CSR_RD_CB(read_hartid);
|
csr_rd_cb[mhartid] = MK_CSR_RD_CB(read_hartid);
|
||||||
};
|
};
|
||||||
|
|
||||||
~riscv_hart_common() {
|
~riscv_hart_common() {
|
||||||
if(io_buf.str().length()) {
|
if(io_buf.str().length()) {
|
||||||
CPPLOG(INFO) << "tohost send '" << io_buf.str() << "'";
|
CPPLOG(INFO) << "tohost send '" << io_buf.str() << "'";
|
||||||
@ -427,14 +428,12 @@ template <typename BASE, typename LOGCAT = logging::disass> struct riscv_hart_co
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
auto to_it = symbol_table.find("tohost");
|
||||||
tohost = symbol_table.at("tohost");
|
if(to_it != std::end(symbol_table))
|
||||||
} catch(std::out_of_range& e) {
|
tohost = to_it->second;
|
||||||
}
|
auto from_it = symbol_table.find("tohost");
|
||||||
try {
|
if(from_it != std::end(symbol_table))
|
||||||
fromhost = symbol_table.at("fromhost");
|
tohost = from_it->second;
|
||||||
} catch(std::out_of_range& e) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
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); },
|
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); },
|
.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); },
|
.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){
|
.raise_trap =
|
||||||
this->reg.trap_state = 0x80ULL << 24 | (cause << 16) | trap_id;
|
[this](uint16_t trap_id, uint16_t cause, reg_t fault_data) {
|
||||||
this->fault_data = 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_rd_cb{this->csr_rd_cb},
|
||||||
.csr_wr_cb{csr_wr_cb},
|
.csr_wr_cb{csr_wr_cb},
|
||||||
.state{this->state},
|
.state{this->state},
|
||||||
@ -743,12 +742,12 @@ template <typename BASE, typename LOGCAT = logging::disass> struct riscv_hart_co
|
|||||||
|
|
||||||
mem::memory_hierarchy memories;
|
mem::memory_hierarchy memories;
|
||||||
|
|
||||||
virtual mem::memory_if get_mem_if() override {
|
mem::memory_if get_mem_if() override {
|
||||||
assert(false || "This function should nevver be called");
|
assert(false || "This function should never be called");
|
||||||
return mem::memory_if{};
|
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); }
|
void set_irq_num(unsigned i) { mcause_max_irq = 1 << util::ilog2(i); }
|
||||||
|
|
||||||
|
@ -45,10 +45,10 @@
|
|||||||
#ifndef FMT_HEADER_ONLY
|
#ifndef FMT_HEADER_ONLY
|
||||||
#define FMT_HEADER_ONLY
|
#define FMT_HEADER_ONLY
|
||||||
#endif
|
#endif
|
||||||
|
#include <iss/mem/memory_with_htif.h>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <elfio/elfio.hpp>
|
#include <elfio/elfio.hpp>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include "../mem/memory_with_htif.h"
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
@ -157,12 +157,7 @@ protected:
|
|||||||
template <typename BASE, features_e FEAT, typename LOGCAT>
|
template <typename BASE, features_e FEAT, typename LOGCAT>
|
||||||
riscv_hart_m_p<BASE, FEAT, LOGCAT>::riscv_hart_m_p()
|
riscv_hart_m_p<BASE, FEAT, LOGCAT>::riscv_hart_m_p()
|
||||||
: default_mem(base::get_priv_if()) {
|
: default_mem(base::get_priv_if()) {
|
||||||
const std::array<unsigned, 4> rwaddrs{{
|
const std::array<unsigned, 4> rwaddrs{{mepc, mtvec, mscratch, mtval}};
|
||||||
mepc,
|
|
||||||
mtvec,
|
|
||||||
mscratch,
|
|
||||||
mtval
|
|
||||||
}};
|
|
||||||
for(auto addr : rwaddrs) {
|
for(auto addr : rwaddrs) {
|
||||||
this->csr_rd_cb[addr] = MK_CSR_RD_CB(read_plain);
|
this->csr_rd_cb[addr] = MK_CSR_RD_CB(read_plain);
|
||||||
this->csr_wr_cb[addr] = MK_CSR_WR_CB(write_plain);
|
this->csr_wr_cb[addr] = MK_CSR_WR_CB(write_plain);
|
||||||
|
@ -40,24 +40,25 @@
|
|||||||
#include "riscv_hart_common.h"
|
#include "riscv_hart_common.h"
|
||||||
#include "util/logging.h"
|
#include "util/logging.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdint>
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
#include <elfio/elf_types.hpp>
|
#include <elfio/elf_types.hpp>
|
||||||
#include <elfio/elfio.hpp>
|
#include <elfio/elfio.hpp>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#ifndef FMT_HEADER_ONLY
|
#ifndef FMT_HEADER_ONLY
|
||||||
#define FMT_HEADER_ONLY
|
#define FMT_HEADER_ONLY
|
||||||
#endif
|
#endif
|
||||||
|
#include <iss/mem/memory_with_htif.h>
|
||||||
|
#include <iss/mem/mmu.h>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "../mem/mmu.h"
|
|
||||||
#include "../mem/memory_with_htif.h"
|
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace arch {
|
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:
|
public:
|
||||||
using core = BASE;
|
using core = BASE;
|
||||||
using base = riscv_hart_common<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())
|
, mmu(base::get_priv_if())
|
||||||
, default_mem(base::get_priv_if()) {
|
, default_mem(base::get_priv_if()) {
|
||||||
// common regs
|
// common regs
|
||||||
const std::array<unsigned, 17> rwaddrs{{
|
const std::array<unsigned, 17> rwaddrs{{mepc, mtvec, mscratch, mtval, mscratch, sepc, stvec, sscratch, scause, stval, sscratch, uepc,
|
||||||
mepc,
|
utvec, uscratch, ucause, utval, uscratch}};
|
||||||
mtvec,
|
|
||||||
mscratch,
|
|
||||||
mtval,
|
|
||||||
mscratch,
|
|
||||||
sepc,
|
|
||||||
stvec,
|
|
||||||
sscratch,
|
|
||||||
scause,
|
|
||||||
stval,
|
|
||||||
sscratch,
|
|
||||||
uepc,
|
|
||||||
utvec,
|
|
||||||
uscratch,
|
|
||||||
ucause,
|
|
||||||
utval,
|
|
||||||
uscratch
|
|
||||||
}};
|
|
||||||
for(auto addr : rwaddrs) {
|
for(auto addr : rwaddrs) {
|
||||||
this->csr_rd_cb[addr] = MK_CSR_RD_CB(read_plain);
|
this->csr_rd_cb[addr] = MK_CSR_RD_CB(read_plain);
|
||||||
this->csr_wr_cb[addr] = MK_CSR_WR_CB(write_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>
|
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,
|
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
|
#ifndef NDEBUG
|
||||||
if(access && iss::access_type::DEBUG) {
|
if(access && iss::access_type::DEBUG) {
|
||||||
CPPLOG(TRACEALL) << "debug read of " << length << " bytes @addr 0x" << std::hex << addr;
|
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;
|
this->fault_data = addr;
|
||||||
if(is_debug(access))
|
if(is_debug(access))
|
||||||
throw trap_access(0, addr);
|
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;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
try {
|
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>
|
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,
|
iss::status riscv_hart_msu_vp<BASE, FEAT, LOGCAT>::write(const address_type type, const access_type access, const uint32_t space,
|
||||||
const unsigned length, const uint8_t* const data) {
|
const uint64_t addr, const unsigned length, const uint8_t* const data) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
const char* prefix = (access && iss::access_type::DEBUG) ? "debug " : "";
|
const char* prefix = (access && iss::access_type::DEBUG) ? "debug " : "";
|
||||||
switch(length) {
|
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;
|
auto req_priv_lvl = (addr >> 8) & 0x3;
|
||||||
val = state.mstatus & get_mstatus_mask(req_priv_lvl);
|
val = state.mstatus & get_mstatus_mask(req_priv_lvl);
|
||||||
return iss::Ok;
|
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;
|
auto req_priv_lvl = (addr >> 8) & 0x3;
|
||||||
write_mstatus(val, req_priv_lvl);
|
write_mstatus(val, req_priv_lvl);
|
||||||
check_interrupt();
|
check_interrupt();
|
||||||
return iss::Ok;
|
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
|
this->csr[addr] = val & ((1UL << (traits<BASE>::XLEN - 1)) | 0xf); // TODO: make exception code size configurable
|
||||||
return iss::Ok;
|
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];
|
val = this->csr[mie];
|
||||||
if(addr < mie)
|
if(addr < mie)
|
||||||
val &= this->csr[mideleg];
|
val &= this->csr[mideleg];
|
||||||
@ -444,7 +432,8 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
|
|||||||
return iss::Ok;
|
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 req_priv_lvl = (addr >> 8) & 0x3;
|
||||||
auto mask = get_irq_mask(req_priv_lvl);
|
auto mask = get_irq_mask(req_priv_lvl);
|
||||||
this->csr[mie] = (this->csr[mie] & ~mask) | (val & mask);
|
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;
|
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];
|
val = this->csr[mip];
|
||||||
if(addr < mip)
|
if(addr < mip)
|
||||||
val &= this->csr[mideleg];
|
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>
|
||||||
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) {
|
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]
|
// flags are ACTIVE[31:31], CAUSE[30:16], TRAPID[15:0]
|
||||||
// calculate and write mcause val
|
// calculate and write mcause val
|
||||||
if(flags == std::numeric_limits<uint64_t>::max())
|
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
|
#endif
|
||||||
if((flags & 0xffffffff) != 0xffffffff)
|
if((flags & 0xffffffff) != 0xffffffff)
|
||||||
NSCLOG(INFO, LOGCAT) << (trap_id ? "Interrupt" : "Trap") << " with cause '"
|
NSCLOG(INFO, LOGCAT) << (trap_id ? "Interrupt" : "Trap") << " with cause '"
|
||||||
<< (trap_id ? this->irq_str[cause] : this->trap_str[cause]) << "' (" << 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]
|
<< " at address " << buffer.data() << " occurred, changing privilege level from " << this->lvl[this->reg.PRIV]
|
||||||
<< " to " << this->lvl[new_priv];
|
<< " to " << this->lvl[new_priv];
|
||||||
// reset trap state
|
// reset trap state
|
||||||
this->reg.PRIV = new_priv;
|
this->reg.PRIV = new_priv;
|
||||||
this->reg.trap_state = 0;
|
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.
|
// sets the pc to the value stored in the x epc register.
|
||||||
this->reg.NEXT_PC = this->csr[uepc | inst_priv << 8];
|
this->reg.NEXT_PC = this->csr[uepc | inst_priv << 8];
|
||||||
NSCLOG(INFO, LOGCAT) << "Executing xRET , changing privilege level from " << this->lvl[cur_priv] << " to "
|
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();
|
check_interrupt();
|
||||||
}
|
}
|
||||||
this->reg.trap_state = this->reg.pending_trap;
|
this->reg.trap_state = this->reg.pending_trap;
|
||||||
|
@ -40,15 +40,15 @@
|
|||||||
#include "riscv_hart_common.h"
|
#include "riscv_hart_common.h"
|
||||||
#include "util/logging.h"
|
#include "util/logging.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdint>
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
#include <elfio/elf_types.hpp>
|
#include <elfio/elf_types.hpp>
|
||||||
#include <elfio/elfio.hpp>
|
#include <elfio/elfio.hpp>
|
||||||
#ifndef FMT_HEADER_ONLY
|
#ifndef FMT_HEADER_ONLY
|
||||||
#define FMT_HEADER_ONLY
|
#define FMT_HEADER_ONLY
|
||||||
#endif
|
#endif
|
||||||
|
#include <iss/mem/memory_with_htif.h>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include "../mem/memory_with_htif.h"
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
@ -71,7 +71,7 @@ public:
|
|||||||
#else
|
#else
|
||||||
switch(priv_lvl) {
|
switch(priv_lvl) {
|
||||||
case PRIV_U:
|
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:
|
default:
|
||||||
// +-SD
|
// +-SD
|
||||||
// | +-TSR
|
// | +-TSR
|
||||||
@ -97,7 +97,7 @@ public:
|
|||||||
#else
|
#else
|
||||||
switch(priv_lvl) {
|
switch(priv_lvl) {
|
||||||
case PRIV_U:
|
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:
|
default:
|
||||||
// +-TSR
|
// +-TSR
|
||||||
// |+-TW
|
// |+-TW
|
||||||
@ -251,7 +251,7 @@ riscv_hart_mu_p<BASE, FEAT, LOGCAT>::riscv_hart_mu_p()
|
|||||||
|
|
||||||
template <typename BASE, features_e FEAT, typename LOGCAT>
|
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,
|
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
|
#ifndef NDEBUG
|
||||||
if(access && iss::access_type::DEBUG) {
|
if(access && iss::access_type::DEBUG) {
|
||||||
CPPLOG(TRACEALL) << "debug read of " << length << " bytes @addr 0x" << std::hex << addr;
|
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
|
#endif
|
||||||
if((flags & 0xffffffff) != 0xffffffff)
|
if((flags & 0xffffffff) != 0xffffffff)
|
||||||
NSCLOG(INFO, LOGCAT) << (trap_id ? "Interrupt" : "Trap") << " with cause '"
|
NSCLOG(INFO, LOGCAT) << (trap_id ? "Interrupt" : "Trap") << " with cause '"
|
||||||
<< (trap_id ? this->irq_str[cause] : this->trap_str[cause]) << "' (" << 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]
|
<< " at address " << buffer.data() << " occurred, changing privilege level from " << this->lvl[this->reg.PRIV]
|
||||||
<< " to " << this->lvl[new_priv];
|
<< " to " << this->lvl[new_priv];
|
||||||
// reset trap state
|
// reset trap state
|
||||||
this->reg.PRIV = new_priv;
|
this->reg.PRIV = new_priv;
|
||||||
this->reg.trap_state = 0;
|
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.
|
// sets the pc to the value stored in the x epc register.
|
||||||
this->reg.NEXT_PC = this->csr[uepc | inst_priv << 8];
|
this->reg.NEXT_PC = this->csr[uepc | inst_priv << 8];
|
||||||
NSCLOG(INFO, LOGCAT) << "Executing xRET , changing privilege level from " << this->lvl[cur_priv] << " to "
|
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();
|
check_interrupt();
|
||||||
}
|
}
|
||||||
this->reg.trap_state = this->reg.pending_trap;
|
this->reg.trap_state = this->reg.pending_trap;
|
||||||
|
@ -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
|
#ifndef _ISS_ARCH_TGC_MAPPER_H
|
||||||
#define _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
|
#ifdef CORE_TGC5D_XRB_MAC
|
||||||
#include "riscv_hart_mu_p.h"
|
#include "riscv_hart_mu_p.h"
|
||||||
#include <iss/arch/tgc5d_xrb_mac.h>
|
#include <iss/arch/tgc5d_xrb_mac.h>
|
||||||
using tgc5d_xrb_mac_plat_type =
|
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)>;
|
||||||
iss::arch::riscv_hart_mu_p<iss::arch::tgc5d_xrb_mac (iss::arch::features_e)(iss::arch::FEAT_EXT_N)>;
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef CORE_TGC5D_XRB_NN
|
#ifdef CORE_TGC5D_XRB_NN
|
||||||
#include "hwl.h"
|
#include "hwl.h"
|
||||||
|
@ -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>
|
#include <array>
|
||||||
// generated from:
|
// generated from:
|
||||||
// * /scratch/eyck/workarea/Other/riscv-opcodes/csrs.csv
|
// * /scratch/eyck/workarea/Other/riscv-opcodes/csrs.csv
|
||||||
|
@ -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/arch/riscv_hart_common.h"
|
||||||
#include "iss/vm_types.h"
|
#include "iss/vm_types.h"
|
||||||
#include <util/logging.h>
|
#include <util/logging.h>
|
||||||
#include "../mem/memory_if.h"
|
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace mem {
|
namespace mem {
|
||||||
|
@ -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 "memory_if.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@ -5,12 +39,12 @@ namespace iss {
|
|||||||
namespace mem {
|
namespace mem {
|
||||||
void memory_hierarchy::root(memory_elem& e) {
|
void memory_hierarchy::root(memory_elem& e) {
|
||||||
hierarchy.push_front(&e);
|
hierarchy.push_front(&e);
|
||||||
root_set=true;
|
root_set = true;
|
||||||
update_chain();
|
update_chain();
|
||||||
}
|
}
|
||||||
void memory_hierarchy::prepend(memory_elem& e) {
|
void memory_hierarchy::prepend(memory_elem& e) {
|
||||||
if(root_set)
|
if(root_set)
|
||||||
hierarchy.insert(hierarchy.begin()+1, &e);
|
hierarchy.insert(hierarchy.begin() + 1, &e);
|
||||||
else
|
else
|
||||||
hierarchy.push_front(&e);
|
hierarchy.push_front(&e);
|
||||||
update_chain();
|
update_chain();
|
||||||
@ -22,15 +56,19 @@ void memory_hierarchy::append(memory_elem& e) {
|
|||||||
void memory_hierarchy::insert_before(memory_elem&) {}
|
void memory_hierarchy::insert_before(memory_elem&) {}
|
||||||
void memory_hierarchy::insert_after(memory_elem&) {}
|
void memory_hierarchy::insert_after(memory_elem&) {}
|
||||||
void memory_hierarchy::replace_last(memory_elem& e) {
|
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();
|
hierarchy.pop_back();
|
||||||
|
if(it != std::end(owned_elems))
|
||||||
|
owned_elems.erase(it);
|
||||||
hierarchy.push_back(&e);
|
hierarchy.push_back(&e);
|
||||||
|
update_chain();
|
||||||
}
|
}
|
||||||
void memory_hierarchy::update_chain() {
|
void memory_hierarchy::update_chain() {
|
||||||
bool tail = false;
|
bool tail = false;
|
||||||
for(size_t i = 0; i < hierarchy.size(); ++i) {
|
for(size_t i = 1; i < hierarchy.size(); ++i) {
|
||||||
hierarchy[i]->register_csrs();
|
hierarchy[i - 1]->set_next(hierarchy[i]->get_mem_if());
|
||||||
if(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) {
|
void memory_hierarchy::replace_last(std::unique_ptr<memory_elem>&& p) {
|
||||||
auto e = hierarchy.back();
|
|
||||||
replace_last(*p);
|
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));
|
owned_elems.push_back(std::move(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,11 +37,11 @@
|
|||||||
|
|
||||||
#include "iss/vm_types.h"
|
#include "iss/vm_types.h"
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <vector>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <util/delegate.h>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <util/delegate.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace mem {
|
namespace mem {
|
||||||
@ -58,7 +58,6 @@ struct memory_elem {
|
|||||||
virtual ~memory_elem() = default;
|
virtual ~memory_elem() = default;
|
||||||
virtual memory_if get_mem_if() = 0;
|
virtual memory_if get_mem_if() = 0;
|
||||||
virtual void set_next(memory_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()}; }
|
virtual std::tuple<uint64_t, uint64_t> get_range() { return {0, std::numeric_limits<uint64_t>::max()}; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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_
|
#ifndef _MEMORY_WITH_HTIF_
|
||||||
#define _MEMORY_WITH_HTIF_
|
#define _MEMORY_WITH_HTIF_
|
||||||
|
|
||||||
|
#include "memory_if.h"
|
||||||
#include "iss/arch/riscv_hart_common.h"
|
#include "iss/arch/riscv_hart_common.h"
|
||||||
#include "iss/vm_types.h"
|
#include "iss/vm_types.h"
|
||||||
#include <util/logging.h>
|
#include <util/logging.h>
|
||||||
#include <util/sparse_array.h>
|
#include <util/sparse_array.h>
|
||||||
#include "../mem/memory_if.h"
|
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace mem {
|
namespace mem {
|
||||||
|
@ -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/arch/riscv_hart_common.h"
|
||||||
#include "iss/vm_types.h"
|
#include "iss/vm_types.h"
|
||||||
#include <util/logging.h>
|
#include <util/logging.h>
|
||||||
#include "../mem/memory_if.h"
|
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace mem {
|
namespace mem {
|
||||||
@ -21,7 +54,6 @@ enum {
|
|||||||
PTE_SOFT = 0x300 // Reserved for Software
|
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); }
|
template <typename T> inline bool PTE_TABLE(T PTE) { return (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V); }
|
||||||
|
|
||||||
struct vm_info {
|
struct vm_info {
|
||||||
@ -73,7 +105,7 @@ inline void write_reg_with_offset(uint32_t& reg, uint8_t offs, const uint8_t* co
|
|||||||
break;
|
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 {
|
template <typename WORD_TYPE> struct mmu : public memory_elem {
|
||||||
using this_class = mmu<WORD_TYPE>;
|
using this_class = mmu<WORD_TYPE>;
|
||||||
using reg_t = 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 PGSIZE = 1 << PGSHIFT;
|
||||||
constexpr static reg_t PGMASK = PGSIZE - 1;
|
constexpr static reg_t PGMASK = PGSIZE - 1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mmu(arch::priv_if<WORD_TYPE> hart_if)
|
mmu(arch::priv_if<WORD_TYPE> hart_if)
|
||||||
: hart_if(hart_if) {
|
: hart_if(hart_if) {
|
||||||
hart_if.csr_rd_cb[satp] = MK_CSR_RD_CB(read_satp);
|
hart_if.csr_rd_cb[satp] = MK_CSR_RD_CB(read_satp);
|
||||||
hart_if.csr_wr_cb[satp] = MK_CSR_WR_CB(write_satp);
|
hart_if.csr_wr_cb[satp] = MK_CSR_WR_CB(write_satp);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~mmu() = default;
|
virtual ~mmu() = default;
|
||||||
|
|
||||||
@ -123,7 +153,7 @@ private:
|
|||||||
auto len1 = split_addr - addr;
|
auto len1 = split_addr - addr;
|
||||||
auto res = down_stream_mem.wr_mem(access, addr, len1, data);
|
auto res = down_stream_mem.wr_mem(access, addr, len1, data);
|
||||||
if(res == iss::Ok)
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -144,9 +174,9 @@ private:
|
|||||||
iss::status read_satp(unsigned addr, reg_t& val) {
|
iss::status read_satp(unsigned addr, reg_t& val) {
|
||||||
auto tvm = bit_sub<20, 1>(hart_if.state.mstatus());
|
auto tvm = bit_sub<20, 1>(hart_if.state.mstatus());
|
||||||
if(hart_if.PRIV == arch::PRIV_S & tvm != 0) {
|
if(hart_if.PRIV == arch::PRIV_S & tvm != 0) {
|
||||||
hart_if.raise_trap(2, 0, hart_if.PC);
|
hart_if.raise_trap(2, 0, hart_if.PC);
|
||||||
// hart_if.reg.trap_state = (1 << 31) | (2 << 16);
|
// hart_if.reg.trap_state = (1 << 31) | (2 << 16);
|
||||||
// hart_if.fault_data = hart_if.reg.PC;
|
// hart_if.fault_data = hart_if.reg.PC;
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
val = satp;
|
val = satp;
|
||||||
@ -156,9 +186,9 @@ private:
|
|||||||
iss::status write_satp(unsigned addr, reg_t val) {
|
iss::status write_satp(unsigned addr, reg_t val) {
|
||||||
reg_t tvm = hart_if.state.mstatus.TVM;
|
reg_t tvm = hart_if.state.mstatus.TVM;
|
||||||
if(hart_if.PRIV == arch::PRIV_S & tvm != 0) {
|
if(hart_if.PRIV == arch::PRIV_S & tvm != 0) {
|
||||||
hart_if.raise_trap(2, 0, hart_if.PC);
|
hart_if.raise_trap(2, 0, hart_if.PC);
|
||||||
// hart_if.reg.trap_state = (1 << 31) | (2 << 16);
|
// hart_if.reg.trap_state = (1 << 31) | (2 << 16);
|
||||||
// hart_if.fault_data = hart_if.reg.PC;
|
// hart_if.fault_data = hart_if.reg.PC;
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
satp = val;
|
satp = val;
|
||||||
@ -216,7 +246,7 @@ protected:
|
|||||||
memory_if down_stream_mem;
|
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;
|
const auto type = access & iss::access_type::FUNC;
|
||||||
auto it = ptw.find(addr >> PGSHIFT);
|
auto it = ptw.find(addr >> PGSHIFT);
|
||||||
if(it != ptw.end()) {
|
if(it != ptw.end()) {
|
||||||
@ -235,8 +265,8 @@ template <typename WORD_TYPE> uint64_t mmu<WORD_TYPE>::virt2phys(iss::access_ty
|
|||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
uint32_t mode = type != iss::access_type::FETCH && hart_if.state.mstatus.MPRV ? // MPRV
|
uint32_t mode = type != iss::access_type::FETCH && hart_if.state.mstatus.MPRV ? // MPRV
|
||||||
hart_if.state.mstatus.MPP
|
hart_if.state.mstatus.MPP
|
||||||
: hart_if.PRIV;
|
: hart_if.PRIV;
|
||||||
|
|
||||||
const vm_info& vm = vmt[static_cast<uint16_t>(type) / 2];
|
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
|
// verify bits xlen-1:va_bits-1 are all equal
|
||||||
const int va_bits = PGSHIFT + vm.levels * vm.idxbits;
|
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 reg_t masked_msbs = (addr >> (va_bits - 1)) & mask;
|
||||||
const int levels = (masked_msbs != 0 && masked_msbs != mask) ? 0 : vm.levels;
|
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
|
// check that physical address of PTE is legal
|
||||||
reg_t pte = 0;
|
reg_t pte = 0;
|
||||||
const uint8_t res = down_stream_mem.rd_mem(iss::access_type::READ, base + idx * vm.ptesize, vm.ptesize,
|
const uint8_t res = down_stream_mem.rd_mem(iss::access_type::READ, base + idx * vm.ptesize, vm.ptesize, (uint8_t*)&pte);
|
||||||
(uint8_t*)&pte);
|
|
||||||
if(res != 0)
|
if(res != 0)
|
||||||
throw arch::trap_load_access_fault(addr);
|
throw arch::trap_load_access_fault(addr);
|
||||||
const reg_t ppn = pte >> PTE_PPN_SHIFT;
|
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();
|
ptw.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace mem
|
} // namespace mem
|
||||||
} // namespace iss
|
} // namespace iss
|
||||||
|
@ -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/arch/riscv_hart_common.h"
|
||||||
#include "iss/vm_types.h"
|
#include "iss/vm_types.h"
|
||||||
#include <util/logging.h>
|
#include <util/logging.h>
|
||||||
#include "../mem/memory_if.h"
|
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace mem {
|
namespace mem {
|
||||||
|
@ -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 "semihosting.h"
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
@ -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_
|
#ifndef _SEMIHOSTING_H_
|
||||||
#define _SEMIHOSTING_H_
|
#define _SEMIHOSTING_H_
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (C) 2017, 2018 MINRES Technologies GmbH
|
* Copyright (C) 2017 - 2025 MINRES Technologies GmbH
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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);
|
gp.set_extension(preExt);
|
||||||
}
|
}
|
||||||
auto pre_delay = delay;
|
auto pre_delay = delay;
|
||||||
dbus->b_transport(gp, delay);
|
sckt->b_transport(gp, delay);
|
||||||
if(pre_delay > delay) {
|
if(pre_delay > delay) {
|
||||||
quantum_keeper.reset();
|
quantum_keeper.reset();
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (C) 2017-2021 MINRES Technologies GmbH
|
* Copyright (C) 2017 - 2025 MINRES Technologies GmbH
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -1,9 +1,36 @@
|
|||||||
/*
|
/*******************************************************************************
|
||||||
* sc_core_adapter.h
|
* Copyright (C) 2023 - 2025 MINRES Technologies GmbH
|
||||||
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Created on: Jul 5, 2023
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* Author: eyck
|
* 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_
|
#ifndef _SYSC_SC_CORE_ADAPTER_H_
|
||||||
#define _SYSC_SC_CORE_ADAPTER_H_
|
#define _SYSC_SC_CORE_ADAPTER_H_
|
||||||
@ -11,6 +38,7 @@
|
|||||||
#include "sc_core_adapter_if.h"
|
#include "sc_core_adapter_if.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iss/iss.h>
|
#include <iss/iss.h>
|
||||||
|
#include <iss/mem/memory_if.h>
|
||||||
#include <iss/vm_types.h>
|
#include <iss/vm_types.h>
|
||||||
#include <scc/report.h>
|
#include <scc/report.h>
|
||||||
#include <util/ities.h>
|
#include <util/ities.h>
|
||||||
@ -18,11 +46,16 @@
|
|||||||
namespace sysc {
|
namespace sysc {
|
||||||
template <typename PLAT> class sc_core_adapter : public PLAT, public sc_core_adapter_if {
|
template <typename PLAT> class sc_core_adapter : public PLAT, public sc_core_adapter_if {
|
||||||
public:
|
public:
|
||||||
|
using this_class = sc_core_adapter<PLAT>;
|
||||||
using reg_t = typename iss::arch::traits<typename PLAT::core>::reg_t;
|
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 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)
|
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; }
|
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 {
|
iss::mem::memory_if get_mem_if() override {
|
||||||
if(addr.access && iss::access_type::DEBUG)
|
return iss::mem::memory_if{.rd_mem{util::delegate<iss::mem::rd_mem_func_sig>::from<this_class, &this_class::read_mem>(this)},
|
||||||
return owner->read_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err;
|
.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 {
|
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 {
|
iss::status write_mem(iss::access_type access, uint64_t addr, unsigned length, uint8_t const* data) {
|
||||||
if(addr.access && iss::access_type::DEBUG)
|
if(access && iss::access_type::DEBUG)
|
||||||
return owner->write_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err;
|
return owner->write_mem_dbg(addr, length, data) ? iss::Ok : iss::Err;
|
||||||
if(addr.val == this->tohost) {
|
if(addr == this->tohost) {
|
||||||
reg_t cur_data = *reinterpret_cast<const reg_t*>(data);
|
reg_t cur_data = *reinterpret_cast<const reg_t*>(data);
|
||||||
// Extract Device (bits 63:56)
|
// Extract Device (bits 63:56)
|
||||||
uint8_t device = sizeof(reg_t) == 4 ? 0 : (cur_data >> 56) & 0xFF;
|
uint8_t device = sizeof(reg_t) == 4 ? 0 : (cur_data >> 56) & 0xFF;
|
||||||
@ -117,31 +155,20 @@ public:
|
|||||||
this->interrupt_sim = payload_addr;
|
this->interrupt_sim = payload_addr;
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
}
|
}
|
||||||
auto res = owner->write_mem(addr.val, length, data) ? iss::Ok : iss::Err;
|
auto res = owner->write_mem(addr, 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));
|
|
||||||
}
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
iss::status read_csr(unsigned addr, reg_t& val) override {
|
iss::status read_time(unsigned addr, reg_t& val) {
|
||||||
if((addr == iss::arch::time || addr == iss::arch::timeh)) {
|
uint64_t time_val = owner->mtime_i.get_interface() ? owner->mtime_i.read() : 0;
|
||||||
uint64_t time_val = owner->mtime_i.get_interface() ? owner->mtime_i.read() : 0;
|
if(addr == iss::arch::time) {
|
||||||
if(addr == iss::arch::time) {
|
val = static_cast<reg_t>(time_val);
|
||||||
val = static_cast<reg_t>(time_val);
|
} else if(addr == iss::arch::timeh) {
|
||||||
} else if(addr == iss::arch::timeh) {
|
if(sizeof(reg_t) != 4)
|
||||||
if(sizeof(reg_t) != 4)
|
return iss::Err;
|
||||||
return iss::Err;
|
val = static_cast<reg_t>(time_val >> 32);
|
||||||
val = static_cast<reg_t>(time_val >> 32);
|
|
||||||
}
|
|
||||||
return iss::Ok;
|
|
||||||
} else {
|
|
||||||
return PLAT::read_csr(addr, val);
|
|
||||||
}
|
}
|
||||||
|
return iss::Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wait_until(uint64_t flags) override {
|
void wait_until(uint64_t flags) override {
|
||||||
|
@ -1,9 +1,36 @@
|
|||||||
/*
|
/*******************************************************************************
|
||||||
* sc_core_adapter.h
|
* Copyright (C) 2023 MINRES Technologies GmbH
|
||||||
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Created on: Jul 5, 2023
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* Author: eyck
|
* 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_
|
#ifndef _SYSC_SC_CORE_ADAPTER_IF_H_
|
||||||
#define _SYSC_SC_CORE_ADAPTER_IF_H_
|
#define _SYSC_SC_CORE_ADAPTER_IF_H_
|
||||||
|
Reference in New Issue
Block a user