blob: 44b603c2c21eb7657877b8805ddd6e4668dac3cc [file] [log] [blame]
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MPACT_CHERIOT__CHERIOT_RENODE_H_
#define MPACT_CHERIOT__CHERIOT_RENODE_H_
#include <cstddef>
#include <cstdint>
#include <string>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "cheriot/cheriot_cli_forwarder.h"
#include "cheriot/cheriot_instrumentation_control.h"
#include "cheriot/cheriot_renode_cli_top.h"
#include "cheriot/cheriot_state.h"
#include "cheriot/cheriot_top.h"
#include "cheriot/debug_command_shell.h"
#include "mpact/sim/generic/core_debug_interface.h"
#include "mpact/sim/generic/data_buffer.h"
#include "mpact/sim/util/memory/atomic_memory.h"
#include "mpact/sim/util/memory/memory_interface.h"
#include "mpact/sim/util/memory/memory_use_profiler.h"
#include "mpact/sim/util/memory/single_initiator_router.h"
#include "mpact/sim/util/memory/tagged_flat_demand_memory.h"
#include "mpact/sim/util/memory/tagged_memory_interface.h"
#include "mpact/sim/util/other/instruction_profiler.h"
#include "mpact/sim/util/program_loader/elf_program_loader.h"
#include "mpact/sim/util/renode/renode_debug_interface.h"
#include "mpact/sim/util/renode/socket_cli.h"
#include "riscv//riscv_arm_semihost.h"
#include "riscv//riscv_clint.h"
// This file defines a wrapper class for the CheriotTop that adds Arm
// semihosting. In addition, the .cc class defines a global namespace
// function that is used by the renode wrapper to create a top simulator
// instance.
//
// In addition, when the configuration specifies a command line interface port,
// an object of the SocketCLI class is instantiated to provide a command line
// interface accessible over a socket. In this case the wrapper no longer
// directly calls the top simulator control class, but routes the calls through
// a combined ReNode/CLI interface that manages the priorities and access of
// ReNode and command line commands to the simulator control class.
extern ::mpact::sim::util::renode::RenodeDebugInterface *CreateMpactSim(
std::string name, ::mpact::sim::util::MemoryInterface *renode_sysbus);
namespace mpact {
namespace sim {
namespace cheriot {
using ::mpact::sim::generic::DataBufferFactory;
using ::mpact::sim::riscv::RiscVArmSemihost;
using ::mpact::sim::riscv::RiscVClint;
using ::mpact::sim::util::AtomicMemory;
using ::mpact::sim::util::ElfProgramLoader;
using ::mpact::sim::util::InstructionProfiler;
using ::mpact::sim::util::MemoryInterface;
using ::mpact::sim::util::SingleInitiatorRouter;
using ::mpact::sim::util::TaggedFlatDemandMemory;
using ::mpact::sim::util::TaggedMemoryInterface;
using ::mpact::sim::util::TaggedMemoryUseProfiler;
using ::mpact::sim::util::renode::SocketCLI;
class CheriotRenode : public util::renode::RenodeDebugInterface {
public:
// Supported IRQ request types.
enum class IrqType {
kMachineSoftwareInterrupt = 0x3,
kMachineExternalInterrupt = 0xb,
};
enum RenodeState {
kIdle = 0,
kStepping = 1,
kRunning = 2,
};
enum CLIState {
kDisconnected = 0,
kConnected = 1,
};
enum class CheriotCpuType {
kBase = 0,
kRvv = 1,
kRvvFp = 2,
};
using ::mpact::sim::generic::CoreDebugInterface::HaltReason;
using ::mpact::sim::generic::CoreDebugInterface::RunStatus;
using RenodeCpuRegister = ::mpact::sim::util::renode::RenodeCpuRegister;
// Constructor takes a name and a memory interface that is used for memory
// transactions routed to the system bus.
CheriotRenode(std::string name, MemoryInterface *renode_sysbus);
~CheriotRenode() override;
absl::StatusOr<uint64_t> LoadExecutable(const char *elf_file_name,
bool for_symbols_only) override;
// Step the core by num instructions.
absl::StatusOr<int> Step(int num) override;
// Returns the reason for the most recent halt.
absl::StatusOr<HaltReasonValueType> GetLastHaltReason() override;
// Read/write the numeric id registers.
absl::StatusOr<uint64_t> ReadRegister(uint32_t reg_id) override;
absl::Status WriteRegister(uint32_t reg_id, uint64_t value) override;
// Get register data buffer call. Not implemented, stubbed out to return null.
// Read/write the buffers to memory.
absl::StatusOr<size_t> ReadMemory(uint64_t address, void *buf,
size_t length) override;
absl::StatusOr<size_t> WriteMemory(uint64_t address, const void *buf,
size_t length) override;
// Return register information.
int32_t GetRenodeRegisterInfoSize() const override;
absl::Status GetRenodeRegisterInfo(int32_t index, int32_t max_len, char *name,
RenodeCpuRegister &info) override;
// Set configuration value.
absl::Status SetConfig(const char *config_names[],
const char *config_values[], int size) override;
// Set IRQ value for supported IRQs. Supported irq_nums are:
// MachineSoftwareInterrupt = 0x3
// handled by the clint for now: MachineTimerInterrupt = 0x7
// MachineExternalInterrupt = 0xb
// These correspond to the msip and meip bits of the mip register.
absl::Status SetIrqValue(int32_t irq_num, bool irq_value) override;
absl::Status InitializeSimulator(const std::string &cpu_type);
private:
std::string name_;
MemoryInterface *renode_sysbus_ = nullptr;
TaggedMemoryInterface *data_memory_ = nullptr;
TaggedMemoryInterface *tagged_sysbus_ = nullptr;
CheriotState *cheriot_state_ = nullptr;
DecoderInterface *cheriot_decoder_ = nullptr;
CheriotTop *cheriot_top_ = nullptr;
RiscVArmSemihost *semihost_ = nullptr;
SingleInitiatorRouter *router_ = nullptr;
SingleInitiatorRouter *renode_router_ = nullptr;
DataBufferFactory db_factory_;
AtomicMemory *atomic_memory_ = nullptr;
TaggedFlatDemandMemory *tagged_memory_ = nullptr;
RiscVClint *clint_ = nullptr;
SocketCLI *socket_cli_ = nullptr;
CheriotRenodeCLITop *cheriot_renode_cli_top_ = nullptr;
CheriotCLIForwarder *cheriot_cli_forwarder_ = nullptr;
ElfProgramLoader *program_loader_ = nullptr;
DebugCommandShell *cmd_shell_ = nullptr;
InstructionProfiler *inst_profiler_ = nullptr;
TaggedMemoryUseProfiler *mem_profiler_ = nullptr;
CheriotInstrumentationControl *instrumentation_control_ = nullptr;
CheriotCpuType cpu_type_ = CheriotCpuType::kBase;
};
} // namespace cheriot
} // namespace sim
} // namespace mpact
#endif // MPACT_CHERIOT__CHERIOT_RENODE_H_