Go to the documentation of this file.
45 #include "debug/AddrRanges.hh"
46 #include "debug/Drain.hh"
47 #include "debug/GIC.hh"
48 #include "debug/ITS.hh"
54 #define COMMAND(x, method) { x, DispatchEntry(#x, method) }
61 : its(_its), coroutine(nullptr)
102 a.pkt->dataStatic(ptr);
126 a.pkt->dataStatic(ptr);
152 const Addr address =
base + (device_id *
sizeof(dte));
154 DPRINTF(ITS,
"Writing DTE at address %#x: %#x\n", address, dte);
156 doWrite(yield, address, &dte,
sizeof(dte));
161 Yield &yield,
const Addr itt_base, uint32_t event_id,
ITTE itte)
163 const Addr address = itt_base + (event_id *
sizeof(itte));
165 doWrite(yield, address, &itte,
sizeof(itte));
167 DPRINTF(ITS,
"Writing ITTE at address %#x: %#x\n", address, itte);
172 Yield &yield, uint32_t collection_id,
CTE cte)
175 const Addr address =
base + (collection_id *
sizeof(cte));
177 doWrite(yield, address, &cte,
sizeof(cte));
179 DPRINTF(ITS,
"Writing CTE at address %#x: %#x\n", address, cte);
187 const Addr address =
base + (device_id *
sizeof(dte));
189 doRead(yield, address, &dte,
sizeof(dte));
191 DPRINTF(ITS,
"Reading DTE at address %#x: %#x\n", address, dte);
197 Yield &yield,
const Addr itt_base, uint32_t event_id)
200 const Addr address = itt_base + (event_id *
sizeof(itte));
202 doRead(yield, address, &itte,
sizeof(itte));
204 DPRINTF(ITS,
"Reading ITTE at address %#x: %#x\n", address, itte);
213 const Addr address =
base + (collection_id *
sizeof(cte));
215 doRead(yield, address, &cte,
sizeof(cte));
217 DPRINTF(ITS,
"Reading CTE at address %#x: %#x\n", address, cte);
226 its.gitsControl.quiescent = 0;
234 its.gitsControl.quiescent = 1;
242 const uint32_t device_id = pkt->
req->streamId();
243 const uint32_t event_id = pkt->
getLE<uint32_t>();
247 uint32_t intid = result.first;
276 const auto collection_id = itte.icid;
321 its.gitsControl.quiescent = 0;
329 its.gitsControl.quiescent = 1;
336 return entry !=
cmdDispatcher.end() ? entry->second.name :
"INVALID";
366 const Addr cmd_addr =
369 doRead(yield, cmd_addr, &command,
sizeof(command));
371 DPRINTF(ITS,
"Command %s read from queue at address: %#x\n",
373 DPRINTF(ITS,
"dw0: %#x dw1: %#x dw2: %#x dw3: %#x\n",
374 command.
raw[0], command.
raw[1], command.
raw[2], command.
raw[3]);
384 entry->second.exec(
this, yield, command);
386 panic(
"Unrecognized command type: %u", command.
type);
406 yield, dte.ittAddress, command.
eventId);
413 const auto collection_id = itte.icid;
441 yield, dte.ittAddress, command.
eventId);
448 const auto collection_id = itte.icid;
461 yield, dte.ittAddress, command.
eventId, itte);
480 yield, dte.ittAddress, command.
eventId);
487 const auto collection_id = itte.icid;
515 yield, dte.ittAddress, command.
eventId);
522 const auto collection_id = itte.icid;
562 cte.valid =
bits(command.
raw[2], 63);
563 cte.rdBase =
bits(command.
raw[2], 50, 16);
579 dte.valid =
bits(command.
raw[2], 63);
580 dte.ittAddress =
mbits(command.
raw[2], 51, 8);
581 dte.ittRange =
bits(command.
raw[1], 4, 0);
609 yield, dte.ittAddress, command.
eventId);
612 itte.intType = Gicv3Its::PHYSICAL_INTERRUPT;
614 itte.icid =
bits(command.
raw[2], 15, 0);
617 yield, dte.ittAddress, command.
eventId, itte);
635 const auto pintid =
bits(command.
raw[1], 63, 32);
645 yield, dte.ittAddress, command.
eventId);
648 itte.intType = Gicv3Its::PHYSICAL_INTERRUPT;
649 itte.intNum = pintid;
650 itte.icid =
bits(command.
raw[2], 15, 0);
653 yield, dte.ittAddress, command.
eventId, itte);
659 const uint64_t rd1 =
bits(command.
raw[2], 50, 16);
660 const uint64_t rd2 =
bits(command.
raw[3], 50, 16);
691 yield, dte.ittAddress, command.
eventId);
693 if (!itte.valid || itte.intType == Gicv3Its::VIRTUAL_INTERRUPT) {
698 const auto collection_id1 = itte.icid;
706 const auto collection_id2 =
bits(command.
raw[2], 15, 0);
717 if (second_redist != first_redist) {
721 first_redist->
setClrLPI(itte.intNum,
false);
722 second_redist->
setClrLPI(itte.intNum,
true);
726 itte.icid = collection_id2;
728 yield, dte.ittAddress, command.
eventId, itte);
734 warn(
"ITS %s command unimplemented", __func__);
740 panic(
"ITS %s command unimplemented", __func__);
746 panic(
"ITS %s command unimplemented", __func__);
752 panic(
"ITS %s command unimplemented", __func__);
758 panic(
"ITS %s command unimplemented", __func__);
764 panic(
"ITS %s command unimplemented", __func__);
770 panic(
"ITS %s command unimplemented", __func__);
776 panic(
"ITS %s command unimplemented", __func__);
793 BASER device_baser = 0;
795 device_baser.entrySize =
sizeof(uint64_t) - 1;
798 BASER icollect_baser = 0;
800 icollect_baser.entrySize =
sizeof(uint64_t) - 1;
827 DPRINTF(GIC,
"%s register at addr: %#x\n", __func__,
addr);
881 auto baser_index = relative_addr /
sizeof(uint64_t);
886 panic(
"Unrecognized register access\n");
890 pkt->
setUintX(value, ByteOrder::little);
900 DPRINTF(GIC,
"%s register at addr: %#x\n", __func__,
addr);
904 assert(pkt->
getSize() ==
sizeof(uint32_t));
913 panic(
"GITS_IIDR is Read Only\n");
916 panic(
"GITS_TYPER is Read Only\n");
919 if (pkt->
getSize() ==
sizeof(uint32_t)) {
922 assert(pkt->
getSize() ==
sizeof(uint64_t));
932 assert(pkt->
getSize() ==
sizeof(uint32_t));
941 if (pkt->
getSize() ==
sizeof(uint32_t)) {
944 assert(pkt->
getSize() ==
sizeof(uint64_t));
952 assert(pkt->
getSize() ==
sizeof(uint32_t));
959 panic(
"GITS_READR is Read Only\n");
962 if (gitsControl.enabled) {
970 auto baser_index = relative_addr /
sizeof(uint64_t);
972 const uint64_t table_base =
tableBases[baser_index];
973 const uint64_t w_mask =
tableBases[baser_index].type ?
975 const uint64_t
val = pkt->
getLE<uint64_t>() & w_mask;
980 panic(
"Unrecognized register access\n");
991 const uint32_t id_bits =
gitsTyper.idBits;
992 return event_id >= (1
ULL << (id_bits + 1)) ||
993 event_id >= ((1
ULL << itt_range) + 1);
1013 const auto cid_bits =
gitsTyper.cil == 0 ?
1016 return collection_id >= (1
ULL << cid_bits);
1033 DPRINTF(Drain,
"GICv3 ITS not drained\n");
1085 if (!gitsControl.enabled || !
gitsCbaser.valid)
1098 DPRINTF(ITS,
"Reading command from queue\n");
1105 DPRINTF(ITS,
"Waiting for pending command to finish\n");
1113 if (if_name ==
"dma") {
1158 panic(
"Not in timing or atomic mode\n");
1167 switch (action.
type) {
1187 panic(
"Unknown action\n");
1198 bool terminate =
false;
1201 action = proc->
run(pkt);
1203 switch (action.
type) {
1215 panic(
"Unknown action\n");
1218 }
while (!terminate);
1220 action.
delay = delay;
1228 DPRINTF(ITS,
"Starting Translation Request\n");
1249 auto base_it = std::find_if(
1251 [table] (
const BASER &
b) { return b.type == table; }
1255 "ITS Table not recognised\n");
1257 const BASER
base = *base_it;
1260 switch (
base.pageSize) {
1267 panic(
"Unsupported page size\n");
1275 const uint64_t largest_lpi_id = 1
ULL << (rd1->
lpiIDBits + 1);
1276 uint8_t lpi_pending_table[largest_lpi_id / 8];
1281 sizeof(lpi_pending_table));
1285 sizeof(lpi_pending_table));
1290 0,
sizeof(lpi_pending_table));
bool deviceOutOfRange(uint32_t device_id) const
Returns TRUE if the value supplied has bits above the implemented range or if the value supplied exce...
bool scheduled() const
Determine if the current event is scheduled.
void makeAtomicResponse()
Port & getPort(const std::string &if_name, PortID idx) override
Get a port with a given name and index.
Addr pioAddr
Address that the device listens to.
static const AddrRange GITS_BASER
bool collectionOutOfRange(uint32_t collection_id) const
Returns TRUE if the value supplied has bits above the implemented range or if the value exceeds the t...
AddrRangeList getAddrRanges() const override
Every PIO device is obliged to provide an implementation that returns the address ranges the device r...
Gicv3Redistributor * getRedistributorByAddr(Addr address) const
void movall(Yield &yield, CommandEntry &command)
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
bool isTimingMode() const
Is the system in timing mode?
#define UNSERIALIZE_SCALAR(scalar)
bool deviceOutOfRange(CommandEntry &command) const
void vmapp(Yield &yield, CommandEntry &command)
CallerType: A reference to an object of this class will be passed to the coroutine task.
void doInt(Yield &yield, CommandEntry &command)
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
#define UNSERIALIZE_CONTAINER(member)
void vsync(Yield &yield, CommandEntry &command)
ItsProcess(Gicv3Its &_its)
void writeDeviceTable(Yield &yield, uint32_t device_id, DTE dte)
bool recvTimingResp(PacketPtr pkt)
void moveAllPendingState(Gicv3Redistributor *rd1, Gicv3Redistributor *rd2)
Gicv3Distributor * getDistributor() const
std::pair< uint32_t, Gicv3Redistributor * > translateLPI(Yield &yield, uint32_t device_id, uint32_t event_id)
EventFunctionWrapper commandEvent
static std::string commandName(uint32_t cmd)
std::unique_ptr< Coroutine > coroutine
std::vector< BASER > tableBases
void serialize(CheckpointOut &cp) const override
Serialize an object.
uint64_t Tick
Tick count type.
void doWrite(Yield &yield, Addr addr, void *ptr, size_t size)
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
bool contains(const Addr &a) const
Determine if the range contains an address.
std::shared_ptr< Request > RequestPtr
RequestPtr req
A pointer to the original request.
ItsAction runProcessTiming(ItsProcess *proc, PacketPtr pkt)
void mapi(Yield &yield, CommandEntry &command)
void sync(Yield &yield, CommandEntry &command)
void movi(Yield &yield, CommandEntry &command)
void unserialize(CheckpointIn &cp) override
Unserialize an object.
bool isPendingLPI(uint32_t intid)
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
bool collectionOutOfRange(CommandEntry &command) const
@ Drained
Buffers drained, ready for serialization/handover.
void writeBlob(Addr addr, const void *p, int size) const
Same as tryWriteBlob, but insists on success.
ItsAction run(PacketPtr pkt)
DrainState
Object drain/handover states.
static const uint64_t BASER_WMASK
Addr pageAddress(enum ItsTables table)
bool sizeOutOfRange(uint32_t size) const
Returns TRUE if the value (size) supplied exceeds the maximum allowed by GITS_TYPER....
bool idOutOfRange(uint32_t event_id, uint8_t itt_range) const
Returns TRUE if the eventID supplied has bits above the implemented size or above the itt_range.
void schedule(Event &event, Tick when)
void main(Yield &yield) override
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
bool sizeOutOfRange(CommandEntry &command) const
void mapd(Yield &yield, CommandEntry &command)
bool lpiOutOfRange(uint32_t intid) const
Returns TRUE if the value supplied is larger than that permitted by GICD_TYPER.IDbits or not in the L...
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
Ports are used to interface objects to each other.
const std::string name() const
Returns the Gicv3Its name.
void clear(Yield &yield, CommandEntry &command)
void vmapi(Yield &yield, CommandEntry &command)
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
void writeIrqTranslationTable(Yield &yield, const Addr itt_base, uint32_t event_id, ITTE itte)
AddrRange RangeSize(Addr start, Addr size)
void doRead(Yield &yield, Addr addr, void *ptr, size_t size)
void setUintX(uint64_t w, ByteOrder endian)
Set the value in the word w after truncating it to the length of the packet and then byteswapping it ...
std::unordered_map< std::underlying_type< enum CommandType >::type, DispatchEntry > DispatchTable
Addr pioSize
Size that the device's address range.
bool idOutOfRange(CommandEntry &command, DTE dte) const
constexpr T mbits(T val, unsigned first, unsigned last)
Mask off the given bits in place like bits() but without shifting.
void vmapti(Yield &yield, CommandEntry &command)
uint64_t readDeviceTable(Yield &yield, uint32_t device_id)
ProbePointArg< PacketInfo > Packet
Packet probe point.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
An ItsCommand is created whenever there is a new command in the command queue.
void terminate(Yield &yield)
const std::string & name()
Gicv3Redistributor * getRedistributor(ContextID context_id) const
#define SERIALIZE_SCALAR(scalar)
void vmovp(Yield &yield, CommandEntry &command)
void vmovi(Yield &yield, CommandEntry &command)
void incrementReadPointer()
void mapc(Yield &yield, CommandEntry &command)
Gicv3Its(const Gicv3ItsParams ¶ms)
uint64_t maxCommands() const
static const uint64_t BASER_WMASK_UNIMPL
Gicv3Redistributor * getRedistributor(uint64_t rd_base)
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
virtual const std::string name() const
uint64_t readIrqTranslationTable(Yield &yield, const Addr itt_base, uint32_t event_id)
m5::Coroutine< PacketPtr, ItsAction > Coroutine
void writeIrqCollectionTable(Yield &yield, uint32_t collection_id, CTE cte)
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
void discard(Yield &yield, CommandEntry &command)
void vinvall(Yield &yield, CommandEntry &command)
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
void pushSenderState(SenderState *sender_state)
Push a new sender state to the packet and make the current sender state the predecessor of the new on...
void inv(Yield &yield, CommandEntry &command)
std::enable_if_t<!std::is_same< T, void >::value, T > get()
get() is the way we can extrapolate arguments from the coroutine caller.
static const int INTID_SPURIOUS
Addr start() const
Get the start address of the range.
virtual void main(Yield &yield)=0
ItsCommand(Gicv3Its &_its)
void invall(Yield &yield, CommandEntry &command)
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
#define SERIALIZE_CONTAINER(member)
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
SenderState * popSenderState()
Pop the top of the state stack and return a pointer to it.
ItsAction runProcess(ItsProcess *proc, PacketPtr pkt)
static const uint32_t CTLR_QUIESCENT
void mapti(Yield &yield, CommandEntry &command)
#define COMMAND(x, method)
void translate(PacketPtr pkt)
Tick pioDelay
Delay that the device experinces on an access.
std::ostream CheckpointOut
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
static const uint32_t SMALLEST_LPI_ID
const Params & params() const
Tick sendAtomic(PacketPtr pkt)
Send an atomic request packet, where the data is moved and the state is updated in zero time,...
An ItsTranslation is created whenever a peripheral writes a message in GITS_TRANSLATER (MSI).
void main(Yield &yield) override
void processCommand(Yield &yield, CommandEntry &command)
void memsetBlob(Addr addr, uint8_t v, int size) const
Same as tryMemsetBlob, but insists on success.
void readBlob(Addr addr, void *p, int size) const
Higher level interfaces based on the above.
std::queue< ItsAction > packetsToRetry
static DispatchTable cmdDispatcher
bool isAtomicMode() const
Is the system in atomic mode?
uint64_t readIrqCollectionTable(Yield &yield, uint32_t collection_id)
static const uint32_t IDBITS
uint32_t pendingTranslations
void readCommand(Yield &yield, CommandEntry &command)
ItsAction runProcessAtomic(ItsProcess *proc, PacketPtr pkt)
ItsTranslation(Gicv3Its &_its)
static const uint32_t NUM_BASER_REGS
#define ULL(N)
uint64_t constant
void setClrLPI(uint64_t data, bool set)
@ Draining
Draining buffers pending serialization/handover.
#define panic(...)
This implements a cprintf based panic() function.
ItsProcess is a base coroutine wrapper which is spawned by the Gicv3Its module when the latter needs ...
Generated on Tue Mar 23 2021 19:41:26 for gem5 by doxygen 1.8.17