44#include "debug/Plic.hh"
47#include "params/Plic.hh"
48#include "params/PlicBase.hh"
54using namespace RiscvISA;
60 registers(params.
name, pioAddr, this),
63 fatal_if(params.hart_config !=
"" && params.n_contexts != 0,
64 "the hart_config and n_contexts can't be set simultaneously");
66 if (params.n_contexts != 0) {
67 initContextFromNContexts(params.n_contexts);
69 if (params.hart_config !=
"") {
70 initContextFromHartConfig(params.hart_config);
78 assert(src_id < nSrc && src_id >= 0);
81 int src_index = src_id >> 5;
82 int src_offset = src_id & 0x1F;
85 std::bitset<32> pending_bits(pending);
86 pending_bits[src_offset] = 1;
87 pending = (uint32_t) pending_bits.to_ulong();
96 "Int post request - source: %#x, current priority: %#x\n",
107 assert(src_id <
nSrc);
111 int src_index = src_id >> 5;
112 int src_offset = src_id & 0x1F;
114 std::bitset<32> pending_bits(pending);
115 pending_bits[src_offset] = 0;
116 pending = (uint32_t) pending_bits.to_ulong();
124 "Int clear request - source: %#x, current priority: %#x\n",
137 "Read request - addr: %#x, size: %#x, atomic:%d\n",
157 "Write request - addr: %#x, size: %#x\n",
197 "Device init - %d contexts, %d sources, %d pending registers\n",
206 using namespace std::placeholders;
210 reserved.emplace_back(
"reserved0", reserve0_size);
213 reserved.emplace_back(
"reserved1", reserve1_size);
216 reserved.emplace_back(
"reserved2", reserve2_size);
219 reserved.emplace_back(
"reserved3", reserve3_size);
233 std::string(
"priority") + std::to_string(
i), 0);
237 std::string(
"pending") + std::to_string(
i), 0);
244 std::string(
"enable") + std::to_string(
i)
245 +
"_" + std::to_string(j), 0);
248 std::string(
"enable_hole") + std::to_string(
i), enable_hole_size);
251 std::string(
"threshold") + std::to_string(
i), 0);
253 std::string(
"claim") + std::to_string(
i), 0);
255 std::string(
"claim_hole") + std::to_string(
i), claim_hole_size);
306 int src_index = src_id >> 5;
307 int src_offset = src_id & 0x1F;
319 "Priority updated - src: %d, val: %d\n",
325 const int src32_id,
const int context_id)
329 for (
int i = 0;
i < 32;
i ++) {
330 int src_id = (src32_id << 5) +
i;
337 "Enable updated - context: %d, src32: %d, val: %#x\n",
338 context_id, src32_id,
reg.get());
343 const int context_id)
348 "Threshold updated - context: %d, val: %d\n",
349 context_id,
reg.get());
355 if (
lastID[context_id] == 0) {
358 int src_index = max_int_id >> 5;
359 int src_offset = max_int_id & 0x1F;
363 lastID[context_id] = max_int_id;
365 "Claim success - context: %d, interrupt ID: %d\n",
366 context_id, max_int_id);
368 reg.update(max_int_id);
372 "Claim already cleared - context: %d, interrupt ID: %d\n",
373 context_id, max_int_id);
377 warn(
"PLIC claim repeated (not completed) - context: %d, last: %d",
378 context_id,
lastID[context_id]);
379 return lastID[context_id];
395 "Complete - context: %d, interrupt ID: %d\n",
396 context_id,
reg.get());
408 uint32_t max_priority;
413 new_output.maxID[
i] = max_id;
414 new_output.maxPriority[
i] = max_priority;
427 DPRINTF(
Plic,
"Update scheduled - tick: %d\n", next_update);
436 for (uint32_t
i = 0;
i < (uint32_t)n_contexts;
i += 2) {
446 uint32_t hart_id = 0;
447 for (
char c: hart_config) {
453 contextConfigs.emplace_back(hart_id, ExceptionCode::INT_EXT_MACHINE);
456 contextConfigs.emplace_back(hart_id, ExceptionCode::INT_EXT_SUPER);
459 fatal(
"hart_config should not contains the value: %c",
c);
495 DPRINTF(
Plic,
"Int posted - thread: %d, int id: %d, ",
498 tc->getCpuPtr()->postInterrupt(tc->threadId(), int_id, 0);
501 DPRINTF(
Plic,
"Int filtered - thread: %d, int id: %d, ",
505 tc->getCpuPtr()->clearInterrupt(tc->threadId(), int_id, 0);
522 for (
auto const ®_inner:
reg) {
523 paramOut(cp, reg_inner.name(), reg_inner);
533 paramOut(cp, std::string(
"output_tick") +
534 std::to_string(n_outputs), it.first);
536 std::to_string(n_outputs), it.second.maxID);
538 std::to_string(n_outputs), it.second.maxPriority);
565 for (
auto ®_inner:
reg) {
566 paramIn(cp, reg_inner.name(), reg_inner);
575 for (
int i = 0;
i < n_outputs;
i++) {
579 paramIn(cp, std::string(
"output_tick") +
580 std::to_string(
i), output_tick);
582 std::to_string(
i), output_id);
584 std::to_string(
i), output_pri);
Tick pioDelay
Delay that the device experinces on an access.
Addr pioSize
Size that the device's address range.
Tick cyclesToTicks(Cycles c) const
Cycles is a wrapper class for representing cycle counts, i.e.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
T * getPtr()
get a pointer to the data ptr.
AtomicOpFunctor * getAtomicOp() const
Accessor function to atomic op.
MemCmd cmd
The command field of the packet.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
std::vector< Register32 > priority
const Addr thresholdPadding
std::vector< Register32 > pending
std::vector< RegisterRaz > enable_holes
const Addr thresholdStart
std::vector< Register32 > threshold
std::vector< std::vector< Register32 > > enable
std::vector< RegisterRaz > reserved
std::vector< RegisterRaz > claim_holes
std::vector< Register32 > claim
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
std::vector< uint32_t > lastID
std::map< Tick, PlicOutput > outputQueue
void updateOutput()
Trigger:
gem5::Plic::PlicRegisters registers
Plic(const Params ¶ms)
void post(int src_id) override
Interrupt interface.
std::vector< std::pair< uint32_t, ExceptionCode > > contextConfigs
PLIC hart/pmode address configs, stored in the format {hartID, pmode}.
EventFunctionWrapper update
Tick read(PacketPtr pkt) override
PioDevice funcitons.
PlicRegisters::Register32 Register32
void writeEnable(Register32 ®, const uint32_t &data, const int src32_id, const int context_id)
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void clear(int src_id) override
void writeThreshold(Register32 ®, const uint32_t &data, const int context_id)
uint32_t readClaim(Register32 ®, const int context_id)
void initContextFromHartConfig(const std::string &hart_config)
std::vector< std::vector< uint32_t > > effPriority
void propagateOutput()
Trigger:
int nSrc32
Number of 32-bit pending registers needed = ceil(nSrc / 32)
void init() override
SimObject functions.
std::vector< uint32_t > pendingPriority
void writeClaim(Register32 ®, const uint32_t &data, const int context_id)
void serialize(CheckpointOut &cp) const override
Serialize an object.
void initContextFromNContexts(int n_contexts)
The function for handling context config from params.
void writePriority(Register32 ®, const uint32_t &data, const int src_id)
Register read / write callbacks.
void addRegister(RegisterAdder reg)
virtual void read(Addr addr, void *buf, Addr bytes)
virtual void write(Addr addr, const void *buf, Addr bytes)
static constexpr T divCeil(const T &a, const U &b)
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
bool scheduled() const
Determine if the current event is scheduled.
void schedule(Event &event, Tick when)
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
#define fatal(...)
This implements a cprintf based fatal() function.
#define UNSERIALIZE_CONTAINER(member)
#define SERIALIZE_CONTAINER(member)
Bitfield< 3, 0 > priority
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Tick curTick()
The universal simulation clock.
std::ostream CheckpointOut
void paramOut(CheckpointOut &cp, const std::string &name, ExtMachInst const &machInst)
void paramIn(CheckpointIn &cp, const std::string &name, ExtMachInst &machInst)
void arrayParamOut(CheckpointOut &cp, const std::string &name, const CircleBuf< T > ¶m)
uint64_t Tick
Tick count type.
void arrayParamIn(CheckpointIn &cp, const std::string &name, CircleBuf< T > ¶m)
Declaration of the Packet class.
#define UNSERIALIZE_SCALAR(scalar)
#define SERIALIZE_SCALAR(scalar)
NOTE: This implementation of PLIC is based on he riscv-plic-spec repository: https://github....
std::vector< uint32_t > maxPriority
std::vector< uint32_t > maxID
const std::string & name()