Go to the documentation of this file.
40 #include "debug/AddrRanges.hh"
41 #include "debug/Drain.hh"
42 #include "debug/GIC.hh"
43 #include "debug/ITS.hh"
49 #define COMMAND(x, method) { x, DispatchEntry(#x, method) }
56 : its(_its), coroutine(nullptr)
97 a.pkt->dataStatic(ptr);
121 a.pkt->dataStatic(ptr);
147 const Addr address =
base + (device_id *
sizeof(dte));
149 DPRINTF(ITS,
"Writing DTE at address %#x: %#x\n", address, dte);
151 doWrite(yield, address, &dte,
sizeof(dte));
156 Yield &yield,
const Addr itt_base, uint32_t event_id,
ITTE itte)
158 const Addr address = itt_base + (event_id *
sizeof(itte));
160 doWrite(yield, address, &itte,
sizeof(itte));
162 DPRINTF(ITS,
"Writing ITTE at address %#x: %#x\n", address, itte);
167 Yield &yield, uint32_t collection_id,
CTE cte)
170 const Addr address =
base + (collection_id *
sizeof(cte));
172 doWrite(yield, address, &cte,
sizeof(cte));
174 DPRINTF(ITS,
"Writing CTE at address %#x: %#x\n", address, cte);
182 const Addr address =
base + (device_id *
sizeof(dte));
184 doRead(yield, address, &dte,
sizeof(dte));
186 DPRINTF(ITS,
"Reading DTE at address %#x: %#x\n", address, dte);
192 Yield &yield,
const Addr itt_base, uint32_t event_id)
195 const Addr address = itt_base + (event_id *
sizeof(itte));
197 doRead(yield, address, &itte,
sizeof(itte));
199 DPRINTF(ITS,
"Reading ITTE at address %#x: %#x\n", address, itte);
208 const Addr address =
base + (collection_id *
sizeof(cte));
210 doRead(yield, address, &cte,
sizeof(cte));
212 DPRINTF(ITS,
"Reading CTE at address %#x: %#x\n", address, cte);
221 its.gitsControl.quiescent = 0;
229 its.gitsControl.quiescent = 1;
237 const uint32_t device_id = pkt->
req->streamId();
238 const uint32_t event_id = pkt->
getLE<uint32_t>();
242 uint32_t intid = result.first;
271 const auto collection_id = itte.icid;
316 its.gitsControl.quiescent = 0;
324 its.gitsControl.quiescent = 1;
331 return entry !=
cmdDispatcher.end() ? entry->second.name :
"INVALID";
361 const Addr cmd_addr =
364 doRead(yield, cmd_addr, &command,
sizeof(command));
366 DPRINTF(ITS,
"Command %s read from queue at address: %#x\n",
368 DPRINTF(ITS,
"dw0: %#x dw1: %#x dw2: %#x dw3: %#x\n",
369 command.
raw[0], command.
raw[1], command.
raw[2], command.
raw[3]);
379 entry->second.exec(
this, yield, command);
381 panic(
"Unrecognized command type: %u", command.
type);
401 yield, dte.ittAddress, command.
eventId);
408 const auto collection_id = itte.icid;
436 yield, dte.ittAddress, command.
eventId);
443 const auto collection_id = itte.icid;
456 yield, dte.ittAddress, command.
eventId, itte);
475 yield, dte.ittAddress, command.
eventId);
482 const auto collection_id = itte.icid;
510 yield, dte.ittAddress, command.
eventId);
517 const auto collection_id = itte.icid;
557 cte.valid =
bits(command.
raw[2], 63);
558 cte.rdBase =
bits(command.
raw[2], 50, 16);
574 dte.valid =
bits(command.
raw[2], 63);
575 dte.ittAddress =
mbits(command.
raw[2], 51, 8);
576 dte.ittRange =
bits(command.
raw[1], 4, 0);
604 yield, dte.ittAddress, command.
eventId);
607 itte.intType = Gicv3Its::PHYSICAL_INTERRUPT;
609 itte.icid =
bits(command.
raw[2], 15, 0);
612 yield, dte.ittAddress, command.
eventId, itte);
630 const auto pintid =
bits(command.
raw[1], 63, 32);
640 yield, dte.ittAddress, command.
eventId);
643 itte.intType = Gicv3Its::PHYSICAL_INTERRUPT;
644 itte.intNum = pintid;
645 itte.icid =
bits(command.
raw[2], 15, 0);
648 yield, dte.ittAddress, command.
eventId, itte);
654 const uint64_t rd1 =
bits(command.
raw[2], 50, 16);
655 const uint64_t rd2 =
bits(command.
raw[3], 50, 16);
686 yield, dte.ittAddress, command.
eventId);
688 if (!itte.valid || itte.intType == Gicv3Its::VIRTUAL_INTERRUPT) {
693 const auto collection_id1 = itte.icid;
701 const auto collection_id2 =
bits(command.
raw[2], 15, 0);
712 if (second_redist != first_redist) {
716 first_redist->
setClrLPI(itte.intNum,
false);
717 second_redist->
setClrLPI(itte.intNum,
true);
721 itte.icid = collection_id2;
723 yield, dte.ittAddress, command.
eventId, itte);
729 warn(
"ITS %s command unimplemented", __func__);
735 panic(
"ITS %s command unimplemented", __func__);
741 panic(
"ITS %s command unimplemented", __func__);
747 panic(
"ITS %s command unimplemented", __func__);
753 panic(
"ITS %s command unimplemented", __func__);
759 panic(
"ITS %s command unimplemented", __func__);
765 panic(
"ITS %s command unimplemented", __func__);
771 panic(
"ITS %s command unimplemented", __func__);
788 BASER device_baser = 0;
790 device_baser.entrySize =
sizeof(uint64_t) - 1;
793 BASER icollect_baser = 0;
795 icollect_baser.entrySize =
sizeof(uint64_t) - 1;
822 DPRINTF(GIC,
"%s register at addr: %#x\n", __func__,
addr);
876 auto baser_index = relative_addr /
sizeof(uint64_t);
881 panic(
"Unrecognized register access\n");
885 pkt->
setUintX(value, ByteOrder::little);
895 DPRINTF(GIC,
"%s register at addr: %#x\n", __func__,
addr);
899 assert(pkt->
getSize() ==
sizeof(uint32_t));
908 panic(
"GITS_IIDR is Read Only\n");
911 panic(
"GITS_TYPER is Read Only\n");
914 if (pkt->
getSize() ==
sizeof(uint32_t)) {
917 assert(pkt->
getSize() ==
sizeof(uint64_t));
927 assert(pkt->
getSize() ==
sizeof(uint32_t));
936 if (pkt->
getSize() ==
sizeof(uint32_t)) {
939 assert(pkt->
getSize() ==
sizeof(uint64_t));
947 assert(pkt->
getSize() ==
sizeof(uint32_t));
954 panic(
"GITS_READR is Read Only\n");
957 if (gitsControl.enabled) {
965 auto baser_index = relative_addr /
sizeof(uint64_t);
967 const uint64_t table_base =
tableBases[baser_index];
968 const uint64_t w_mask =
tableBases[baser_index].type ?
970 const uint64_t
val = pkt->
getLE<uint64_t>() & w_mask;
975 panic(
"Unrecognized register access\n");
986 const uint32_t id_bits =
gitsTyper.idBits;
987 return event_id >= (1
ULL << (id_bits + 1)) ||
988 event_id >= ((1
ULL << itt_range) + 1);
1008 const auto cid_bits =
gitsTyper.cil == 0 ?
1011 return collection_id >= (1
ULL << cid_bits);
1028 DPRINTF(Drain,
"GICv3 ITS not drained\n");
1080 if (!gitsControl.enabled || !
gitsCbaser.valid)
1093 DPRINTF(ITS,
"Reading command from queue\n");
1100 DPRINTF(ITS,
"Waiting for pending command to finish\n");
1108 if (if_name ==
"dma") {
1153 panic(
"Not in timing or atomic mode\n");
1162 switch (action.
type) {
1182 panic(
"Unknown action\n");
1193 bool terminate =
false;
1196 action = proc->
run(pkt);
1198 switch (action.
type) {
1210 panic(
"Unknown action\n");
1213 }
while (!terminate);
1215 action.
delay = delay;
1223 DPRINTF(ITS,
"Starting Translation Request\n");
1244 auto base_it = std::find_if(
1246 [table] (
const BASER &
b) { return b.type == table; }
1250 "ITS Table not recognised\n");
1252 const BASER
base = *base_it;
1255 switch (
base.pageSize) {
1262 panic(
"Unsupported page size\n");
1270 const uint64_t largest_lpi_id = 1
ULL << (rd1->
lpiIDBits + 1);
1271 uint8_t lpi_pending_table[largest_lpi_id / 8];
1276 sizeof(lpi_pending_table));
1280 sizeof(lpi_pending_table));
1285 0,
sizeof(lpi_pending_table));
1291 Gicv3ItsParams::create()
std::enable_if<!std::is_same< T, void >::value, T >::type get()
get() is the way we can extrapolate arguments from the coroutine caller.
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)
Gicv3Its(const Gicv3ItsParams *params)
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.
T mbits(T val, int first, int last)
Mask off the given bits in place like bits() but without shifting.
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
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)
const Params * params() const
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)
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
static const uint32_t SMALLEST_LPI_ID
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 ...
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Generated on Wed Sep 30 2020 14:02:10 for gem5 by doxygen 1.8.17