Go to the documentation of this file.
41 #include "params/SDMAEngine.hh"
48 gfxDoorbell(0), gfxDoorbellOffset(0), gfxWptr(0), pageBase(0),
49 pageRptr(0), pageDoorbell(0), pageDoorbellOffset(0),
50 pageWptr(0), gpuDevice(nullptr), walker(
p.walker)
85 panic(
"Unknown SDMA id");
94 addr = (((
addr >> 12) << 3) << 12) | low_bits;
129 rlcMap.insert(std::make_pair(doorbell, 0));
139 rlcMap.insert(std::make_pair(doorbell, 1));
148 panic(
"No free RLCs. Check they are properly unmapped.");
157 if (
rlcMap[doorbell] == 0) {
160 }
else if (
rlcMap[doorbell] == 1) {
164 panic(
"Cannot unregister unknown RLC queue: %d\n",
rlcMap[doorbell]);
196 if (
rlcMap[doorbellOffset] == 0) {
198 }
else if (
rlcMap[doorbellOffset] == 1) {
201 panic(
"Cannot process unknown RLC queue: %d\n",
240 if (
q->rptr() !=
q->wptr()) {
246 [ = ] (
const uint32_t &
header)
248 dmaReadVirt(
q->rptr(),
sizeof(uint32_t), cb, &cb->dmaBuffer);
250 q->processing(
false);
268 void *dmaBuffer =
nullptr;
274 uint32_t NOP_count = (
header >> 16) & 0x3FFF;
276 if (NOP_count > 0)
q->incRptr(NOP_count * 4);
281 switch (sub_opcode) {
285 [ = ] (
const uint64_t &)
290 panic(
"SDMA_SUBOP_COPY_LINEAR_SUB_WIND not implemented");
293 panic(
"SDMA_SUBOP_COPY_TILED not implemented");
296 panic(
"SDMA_SUBOP_COPY_TILED_SUB_WIND not implemented");
299 panic(
"SDMA_SUBOP_COPY_T2T_SUB_WIND not implemented");
302 panic(
"SDMA_SUBOP_COPY_SOA not implemented");
305 panic(
"SDMA_SUBOP_COPY_DIRTY_PAGE not implemented");
308 panic(
"SDMA_SUBOP_COPY_LINEAR_PHY not implemented");
311 panic(
"SDMA unknown copy sub-opcode.");
317 switch (sub_opcode) {
321 [ = ] (
const uint64_t &)
326 panic(
"SDMA_SUBOP_WRITE_TILED not implemented.\n");
336 [ = ] (
const uint64_t &)
344 [ = ] (
const uint64_t &)
352 [ = ] (
const uint64_t &)
358 warn(
"SDMA_OP_SEM not implemented");
367 [ = ] (
const uint64_t &)
370 switch (sub_opcode) {
372 panic(
"SDMA_SUBOP_POLL_REG_WRITE_MEM not implemented");
375 panic(
"SDMA_SUBOP_POLL_DBIT_WRITE_MEM not implemented");
378 panic(
"SDMA_SUBOP_POLL_MEM_VERIFY not implemented");
386 warn(
"SDMA_OP_SEM not implemented");
391 warn(
"SDMA_OP_ATOMIC not implemented");
396 warn(
"SDMA_OP_CONST_FILL not implemented");
401 switch (sub_opcode) {
406 [ = ] (
const uint64_t &)
411 panic(
"SDMA_SUBOP_PTEPDE_COPY not implemented");
414 panic(
"SDMA_SUBOP_PTEPDE_COPY not implemented");
417 panic(
"SDMA_SUBOP_PTEPDE_RMW not implemented");
428 switch (sub_opcode) {
438 warn(
"SDMA_OP_TIMESTAMP not implemented");
447 [ = ] (
const uint64_t &)
453 warn(
"SDMA_OP_PRE_EXE not implemented");
458 warn(
"SDMA_OP_DUMMY_TRAP not implemented");
462 panic(
"Invalid SDMA packet.\n");
477 uint32_t *dmaBuffer =
new uint32_t[pkt->
count];
488 int bufferSize =
sizeof(uint32_t) * pkt->
count;
489 q->incRptr(bufferSize);
492 for (
int i = 0;
i < pkt->
count; ++
i) {
509 [ = ] (
const uint64_t &) {
writeDone(
q, pkt, dmaBuffer); });
539 uint8_t *dmaBuffer =
new uint8_t[pkt->
count];
541 [ = ] (
const uint64_t &) {
copyReadData(
q, pkt, dmaBuffer); });
551 uint64_t *dmaBuffer64 =
new uint64_t[pkt->
count/8];
552 memcpy(dmaBuffer64, dmaBuffer, pkt->
count);
553 for (
int i = 0;
i < pkt->
count/8; ++
i) {
556 delete [] dmaBuffer64;
560 auto addr_range = *(tgen->begin());
561 Addr tmp_addr = addr_range.paddr;
580 [ = ] (
const uint64_t &) {
copyDone(
q, pkt, dmaBuffer); });
602 q->ib()->size(pkt->
size *
sizeof(uint32_t) + 1);
603 q->ib()->setWptr(pkt->
size *
sizeof(uint32_t));
658 [[maybe_unused]] uint32_t reg_addr = pkt->
regAddr << 2;
659 uint32_t reg_mask = 0x00000000;
661 if (
header->byteEnable & 0x8) reg_mask |= 0xFF000000;
662 if (
header->byteEnable & 0x4) reg_mask |= 0x00FF0000;
663 if (
header->byteEnable & 0x2) reg_mask |= 0x0000FF00;
664 if (
header->byteEnable & 0x1) reg_mask |= 0x000000FF;
665 pkt->
data &= reg_mask;
668 reg_addr, pkt->
data);
670 warn_once(
"SRBM write not performed, no SRBM model. This needs to be fixed"
671 " if correct system simulation is relying on SRBM registers.");
690 "mask=%p, retry=%d, pinterval=%d\n",
header->mode,
header->func,
700 [ = ] (
const uint32_t &dma_buffer) {
703 (
void *)&cb->dmaBuffer);
705 panic(
"SDMA poll mem operation not implemented.");
709 warn_once(
"SDMA poll reg is not implemented. If this is required for "
710 "correctness, an SRBM model needs to be implemented.");
737 [ = ] (
const uint32_t &dma_buffer) {
740 (
void *)&cb->dmaBuffer);
759 return value < reference;
762 return value <= reference;
765 return value == reference;
768 return value != reference;
771 return value >= reference;
774 return value > reference;
777 panic(
"SDMA POLL_REGMEM unknown comparison function.");
794 uint64_t *dmaBuffer =
new uint64_t[pkt->
count];
795 for (
int i = 0;
i < pkt->
count;
i++) {
803 sizeof(uint64_t) * pkt->
count);
808 [ = ] (
const uint64_t &) {
ptePdeDone(
q, pkt, dmaBuffer); });
859 Addr rptr[num_queues];
860 Addr wptr[num_queues];
861 Addr size[num_queues];
862 bool processing[num_queues];
864 for (
int i = 0;
i < num_queues;
i++) {
865 base[
i] = queues[
i]->base();
866 rptr[
i] = queues[
i]->getRptr();
867 wptr[
i] = queues[
i]->getWptr();
868 size[
i] = queues[
i]->size();
869 processing[
i] = queues[
i]->processing();
898 Addr rptr[num_queues];
899 Addr wptr[num_queues];
900 Addr size[num_queues];
901 bool processing[num_queues];
915 for (
int i = 0;
i < num_queues;
i++) {
917 queues[
i]->rptr(rptr[
i]);
918 queues[
i]->wptr(wptr[
i]);
919 queues[
i]->size(size[
i]);
920 queues[
i]->processing(processing[
i]);
928 pkt->
getLE<uint32_t>());
931 switch (mmio_offset) {
957 uint32_t rb_size =
bits(pkt->
getLE<uint32_t>(), 6, 1);
958 assert(rb_size >= 6 && rb_size <= 62);
989 uint32_t rb_size =
bits(pkt->
getLE<uint32_t>(), 6, 1);
990 assert(rb_size >= 6 && rb_size <= 62);
void setPageDoorbellHi(uint32_t data)
void indirectBuffer(SDMAQueue *q, sdmaIndirectBuffer *pkt)
struct gem5::GEM5_PACKED sdmaCopy
SDMA packets.
SDMAEngine(const SDMAEngineParams &p)
struct gem5::GEM5_PACKED sdmaWrite
#define mmSDMA_GFX_RB_WPTR_POLL_ADDR_LO
#define mmSDMA_PAGE_RB_CNTL
#define mmSDMA_GFX_RB_RPTR_ADDR_LO
#define UNSERIALIZE_SCALAR(scalar)
struct gem5::GEM5_PACKED sdmaSRBMWriteHeader
Wraps a std::function object in a DmaCallback.
void setDoorbellType(uint32_t offset, QueueType qt)
Set handles to GPU blocks.
int getIHClientId()
Returns the client id for the Interrupt Handler.
#define SDMA_SUBOP_COPY_SOA
void dmaReadVirt(Addr host_addr, unsigned size, DmaCallback *cb, void *data, Tick delay=0)
Initiate a DMA read from virtual address host_addr.
#define SDMA_SUBOP_POLL_MEM_VERIFY
#define mmSDMA_GFX_RB_BASE
SDMAQueue gfx
Each SDMAEngine processes four queues: paging, gfx, rlc0, and rlc1, where RLC stands for Run List Con...
struct gem5::GEM5_PACKED sdmaTrap
void registerRLCQueue(Addr doorbell, Addr rb_base)
Methods for RLC queues.
uint64_t getPageDoorbellOffset()
#define SDMA_SUBOP_WRITE_LINEAR
uint64_t getGfxDoorbell()
#define SDMA_SUBOP_COPY_TILED
void setPageWptrLo(uint32_t data)
@ SOC15_IH_CLIENTID_SDMA0
#define mmSDMA_GFX_DOORBELL_OFFSET
struct gem5::GEM5_PACKED sdmaPollRegMemHeader
Tick write(PacketPtr pkt) override
Inherited methods.
@ SOC15_IH_CLIENTID_SDMA1
void processRLC0(Addr wptrOffset)
void decodeNext(SDMAQueue *q)
This method checks read and write pointers and starts decoding packets if the read pointer is less th...
Addr getGARTAddr(Addr addr) const
Methods for translation.
#define SDMA_SUBOP_COPY_LINEAR_SUB_WIND
#define SDMA_SUBOP_PTEPDE_RMW
void submitInterruptCookie()
void setGfxRptrHi(uint32_t data)
void writeDone(SDMAQueue *q, sdmaWrite *pkt, uint32_t *dmaBuffer)
void unserialize(CheckpointIn &cp) override
Unserialize an object.
uint64_t getGfxDoorbellOffset()
void setPageDoorbellOffsetHi(uint32_t data)
void setGfxDoorbellLo(uint32_t data)
void fenceDone(SDMAQueue *q, sdmaFence *pkt)
void setPageSize(uint64_t data)
void writeReadData(SDMAQueue *q, sdmaWrite *pkt, uint32_t *dmaBuffer)
#define mmSDMA_GFX_RB_WPTR_POLL_ADDR_HI
bool inAGP(Addr vaddr)
Methods for resolving apertures.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
bool pollRegMemFunc(uint32_t value, uint32_t reference, uint32_t func)
#define SDMA_SUBOP_PTEPDE_COPY_BACKWARDS
#define SDMA_OP_NOP
Commands for the SDMA engine.
#define SDMA_OP_TIMESTAMP
#define mmSDMA_PAGE_RB_RPTR_ADDR_HI
void unregisterRLCQueue(Addr doorbell)
struct gem5::GEM5_PACKED sdmaIndirectBuffer
TranslationGenPtr translate(Addr vaddr, Addr size) override
GPUController will perform DMA operations on VAs, and because page faults are not currently supported...
#define SDMA_SUBOP_TIMESTAMP_GET_GLOBAL
void setPageBaseHi(uint32_t data)
#define mmSDMA_PAGE_DOORBELL
#define mmSDMA_GFX_RB_BASE_HI
#define SDMA_SUBOP_COPY_LINEAR_PHY
void setGfxBaseLo(uint32_t data)
#define mmSDMA_GFX_RB_RPTR_ADDR_HI
Bitfield< 24, 21 > opcode
void setGfxDoorbellHi(uint32_t data)
AMDGPUInterruptHandler * getIH()
Get handles to GPU blocks.
void setGfxRptrLo(uint32_t data)
#define SDMA_SUBOP_COPY_LINEAR
void processPage(Addr wptrOffset)
#define SDMA_OP_CONST_FILL
void pollRegMemRead(SDMAQueue *q, sdmaPollRegMemHeader *header, sdmaPollRegMem *pkt, uint32_t dma_buffer, int count)
void processRLC(Addr doorbellOffset, Addr wptrOffset)
void ptePdeDone(SDMAQueue *q, sdmaPtePde *pkt, uint64_t *dmaBuffer)
void trap(SDMAQueue *q, sdmaTrap *pkt)
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void setGfxDoorbellOffsetHi(uint32_t data)
void ptePde(SDMAQueue *q, sdmaPtePde *pkt)
struct gem5::GEM5_PACKED sdmaPtePde
uint64_t gfxDoorbellOffset
#define mmSDMA_GFX_RB_CNTL
MMIO offsets for SDMA engine.
void serialize(CheckpointOut &cp) const override
Serialize an object.
#define SDMA_SUBOP_COPY_TILED_SUB_WIND
#define SDMA_SUBOP_TIMESTAMP_SET
void copy(SDMAQueue *q, sdmaCopy *pkt)
#define SDMA_SUBOP_TIMESTAMP_GET
void setPageRptrHi(uint32_t data)
Device model for an AMD GPU.
#define mmSDMA_PAGE_RB_WPTR_POLL_ADDR_LO
void serialize(CheckpointOut &cp) const override
Serialize an object.
constexpr T insertBits(T val, unsigned first, unsigned last, B bit_val)
Returns val with bits first to last set to the LSBs of bit_val.
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
void setPageDoorbellLo(uint32_t data)
void setGfxDoorbellOffsetLo(uint32_t data)
#define SERIALIZE_ARRAY(member, size)
void dmaWriteVirt(Addr host_addr, unsigned size, DmaCallback *b, void *data, Tick delay=0)
Initiate a DMA write from virtual address host_addr.
System DMA Engine class for AMD dGPU.
#define mmSDMA_GFX_DOORBELL
#define SDMA_OP_SRBM_WRITE
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
uint64_t pageDoorbellOffset
struct gem5::GEM5_PACKED sdmaSRBMWrite
struct gem5::GEM5_PACKED sdmaFence
#define SERIALIZE_SCALAR(scalar)
Translation range generators.
void pollRegMem(SDMAQueue *q, sdmaPollRegMemHeader *header, sdmaPollRegMem *pkt)
Implements a poll reg/mem packet that polls an SRBM register or a memory location,...
void copyReadData(SDMAQueue *q, sdmaCopy *pkt, uint8_t *dmaBuffer)
#define SDMA_SUBOP_COPY_T2T_SUB_WIND
void setGfxSize(uint64_t data)
#define SDMA_SUBOP_POLL_REG_WRITE_MEM
void processRLC1(Addr wptrOffset)
void decodeHeader(SDMAQueue *q, uint32_t data)
Reads the first DW (32 bits) (i.e., header) of an SDMA packet, which encodes the opcode and sub-opcod...
uint64_t getPageDoorbell()
AMDGPUMemoryManager * getMemMgr()
#define SDMA_SUBOP_WRITE_TILED
void writeRequest(Addr addr, uint8_t *data, int size, Request::Flags flag=0, Event *callback=nullptr)
Write size amount of data to device memory at addr using flags and callback.
std::unordered_map< Addr, int > rlcMap
#define SDMA_SUBOP_PTEPDE_COPY
#define UNSERIALIZE_ARRAY(member, size)
#define mmSDMA_PAGE_DOORBELL_OFFSET
void setPageRptrLo(uint32_t data)
#define mmSDMA_PAGE_RB_BASE
void setGfxWptrLo(uint32_t data)
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
void setGPUDevice(AMDGPUDevice *gpu_device)
struct gem5::GEM5_PACKED sdmaPollRegMem
#define mmSDMA_PAGE_RB_RPTR_ADDR_LO
std::ostream CheckpointOut
void fence(SDMAQueue *q, sdmaFence *pkt)
void srbmWrite(SDMAQueue *q, sdmaSRBMWriteHeader *header, sdmaSRBMWrite *pkt)
void processGfx(Addr wptrOffset)
Given a new write ptr offset, communicated to the GPU through a doorbell write, the SDMA engine proce...
#define SDMA_SUBOP_PTEPDE_GEN
#define SDMA_OP_DUMMY_TRAP
void setPageDoorbellOffsetLo(uint32_t data)
void setDevRequestor(RequestorID mid)
#define SDMA_OP_POLL_REGMEM
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
void setGfxWptrHi(uint32_t data)
#define SDMA_SUBOP_POLL_DBIT_WRITE_MEM
AddrRangeList getAddrRanges() const override
Every PIO device is obliged to provide an implementation that returns the address ranges the device r...
#define SDMA_SUBOP_COPY_DIRTY_PAGE
void setSDMAEngine(Addr offset, SDMAEngine *eng)
void prepareInterruptCookie(ContextID cntxtId, uint32_t ring_id, uint32_t client_id, uint32_t source_id)
void setPageBaseLo(uint32_t data)
void setGfxBaseHi(uint32_t data)
RequestorID vramRequestorId()
Methods related to translations and system/device memory.
void copyDone(SDMAQueue *q, sdmaCopy *pkt, uint8_t *dmaBuffer)
std::unique_ptr< TranslationGen > TranslationGenPtr
#define panic(...)
This implements a cprintf based panic() function.
void writeMMIO(PacketPtr pkt, Addr mmio_offset)
Methods for setting the values of SDMA MMIO registers.
void setPageWptrHi(uint32_t data)
Generated on Wed Jul 13 2022 10:39:18 for gem5 by doxygen 1.8.17