Go to the documentation of this file.
36 #include "debug/AMDGPUDevice.hh"
46 #include "params/AMDGPUDevice.hh"
54 :
PciDevice(
p), gpuMemMgr(
p.memory_manager), deviceIH(
p.device_ih),
55 sdma0(
p.sdma0), sdma1(
p.sdma1), pm4PktProc(
p.pm4_pkt_proc), cp(
p.cp),
56 checkpoint_before_mmios(
p.checkpoint_before_mmios),
57 init_interrupt_count(0), _lastVMID(0),
58 deviceMem(
name() +
".deviceMem",
p.memories, false,
"", false)
62 romBin.open(
p.rom_binary, std::ios::binary);
69 for (
auto&
m :
p.memories) {
82 if (
p.trace_file !=
"") {
100 uint64_t rom_data = 0;
102 memcpy(&rom_data,
rom.data() + rom_offset, pkt->
getSize());
103 pkt->
setUintX(rom_data, ByteOrder::little);
106 pkt->
getAddr(), rom_offset, rom_data);
119 for (
auto &
r : ranges) {
120 if (
r.start() != 0) {
121 ret_ranges.push_back(
r);
223 switch (aperture_offset) {
231 uint32_t value = pkt->
getLE<uint32_t>() | 0x1;
233 pkt->
setLE<uint32_t>(value);
277 pkt->
getLE<uint64_t>());
281 pkt->
getLE<uint64_t>());
293 pkt->
getLE<uint64_t>() + 1);
300 panic(
"RLC queues not yet supported. Run with the environment "
301 "variable HSA_ENABLE_SDMA set to False");
304 panic(
"Write to unkown queue type!");
307 warn(
"Unknown doorbell offset: %lx\n",
offset);
364 panic(
"Request with address out of mapped range!");
392 panic(
"Request with address out of mapped range!");
451 panic(
"No SDMA with id %d\n",
id);
476 uint64_t regs_size =
regs.size();
477 uint64_t doorbells_size =
doorbells.size();
478 uint64_t sdma_engs_size =
sdmaEngs.size();
485 uint32_t reg_addrs[regs_size];
486 uint64_t reg_values[regs_size];
487 uint32_t doorbells_offset[doorbells_size];
488 QueueType doorbells_queues[doorbells_size];
489 uint32_t sdma_engs_offset[sdma_engs_size];
490 int sdma_engs[sdma_engs_size];
493 for (
auto & it :
regs) {
494 reg_addrs[idx] = it.first;
495 reg_values[idx] = it.second;
501 doorbells_offset[idx] = it.first;
502 doorbells_queues[idx] = it.second;
508 sdma_engs_offset[idx] = it.first;
509 sdma_engs[idx] = it.second ==
sdma0 ? 0 : 1;
516 sizeof(doorbells_offset[0]));
518 sizeof(doorbells_queues[0]));
520 sizeof(sdma_engs_offset[0]));
533 uint64_t regs_size = 0;
534 uint64_t doorbells_size = 0;
535 uint64_t sdma_engs_size = 0;
542 uint32_t reg_addrs[regs_size];
543 uint64_t reg_values[regs_size];
547 sizeof(reg_values)/
sizeof(reg_values[0]));
549 for (
int idx = 0; idx < regs_size; ++idx) {
550 regs.insert(std::make_pair(reg_addrs[idx], reg_values[idx]));
554 if (doorbells_size > 0) {
555 uint32_t doorbells_offset[doorbells_size];
556 QueueType doorbells_queues[doorbells_size];
559 sizeof(doorbells_offset[0]));
561 sizeof(doorbells_queues[0]));
563 for (
int idx = 0; idx < doorbells_size; ++idx) {
564 regs.insert(std::make_pair(doorbells_offset[idx],
565 doorbells_queues[idx]));
566 doorbells[doorbells_offset[idx]] = doorbells_queues[idx];
570 if (sdma_engs_size > 0) {
571 uint32_t sdma_engs_offset[sdma_engs_size];
572 int sdma_engs[sdma_engs_size];
575 sizeof(sdma_engs_offset[0]));
578 for (
int idx = 0; idx < sdma_engs_size; ++idx) {
580 sdmaEngs.insert(std::make_pair(sdma_engs_offset[idx], sdma));
594 idMap.insert(std::make_pair(pasid, vmid));
600 panic(
"All VMIDs have been assigned");
612 auto result =
idMap.find(pasid);
613 assert(result !=
idMap.end());
614 if (result ==
idMap.end())
return;
615 uint16_t vmid = result->second;
634 std::unordered_map<uint16_t, std::set<int>>&
void readMMIO(PacketPtr pkt, Addr offset)
Tick curTick()
The universal simulation clock.
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
bool isROM(Addr addr) const
void setGPUDevice(AMDGPUDevice *gpu_device)
AddrRangeList getAddrRanges() const override
Every PIO device is obliged to provide an implementation that returns the address ranges the device r...
PCIConfig config
The current config space.
uint64_t getUintX(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness and zero-extended to 64 bits.
AMDGPUMemoryManager * gpuMemMgr
Blocks of the GPU.
static constexpr uint32_t SDMA1_BASE
#define UNSERIALIZE_SCALAR(scalar)
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
void setDoorbellType(uint32_t offset, QueueType qt)
Set handles to GPU blocks.
static constexpr uint32_t NBIO_BASE
AddrRange RangeSize(Addr start, Addr size)
SDMAEngine * getSDMAEngine(Addr offset)
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
static constexpr uint32_t IH_OFFSET_SHIFT
std::unordered_map< uint64_t, uint32_t > gartTable
Copy of GART table.
Addr getMmioAperture(Addr addr)
SDMAEngine * getSDMAById(int id)
static constexpr uint32_t MMHUB_OFFSET_SHIFT
void writeMMIO(PacketPtr pkt, Addr mmio_offset)
Methods for setting the values of interrupt handler MMIO registers.
void writeMMIO(PacketPtr pkt, Addr mmio_offset)
void deallocateAllQueues()
void intrPost()
Methods inherited from PciDevice.
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
constexpr int DOORBELL_BAR
std::unordered_map< uint16_t, uint16_t > idMap
std::unordered_map< Addr, uint16_t > doorbellVMIDMap
Addr gartBase()
Return base address of GART table in framebuffer.
constexpr int FRAMEBUFFER_BAR
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void setGPUDevice(AMDGPUDevice *gpu_device)
HSAPacketProcessor & hsaPacketProc()
void readMMIOTrace(std::string trace_file)
Read an MMIO trace gathered from a real system and place the MMIO values read and written into the MM...
void makeAtomicResponse()
Addr getFrameAperture(Addr addr)
void process(PM4Queue *q, Addr wptrOffset)
This method start processing a PM4Queue from the current read pointer to the newly communicated write...
Tick readConfig(PacketPtr pkt) override
Read from the PCI config space data that is stored locally.
void mapDoorbellToVMID(Addr doorbell, uint16_t vmid)
void writeMMIO(PacketPtr pkt, Addr offset)
void exitSimLoop(const std::string &message, int exit_code, Tick when, Tick repeat, bool serialize)
Schedule an event to exit the simulation loop (returning to Python) at the end of the current cycle (...
std::unordered_map< uint32_t, SDMAEngine * > sdmaEngs
virtual Tick writeConfig(PacketPtr pkt)
Write to the PCI config space data that is stored locally.
AMDGPUDevice(const AMDGPUDeviceParams &p)
static constexpr uint32_t GRBM_OFFSET_SHIFT
void updateRptr(const uint32_t &data)
void processPage(Addr wptrOffset)
Tick writeConfig(PacketPtr pkt) override
Write to the PCI config space data that is stored locally.
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
void setGPUDevice(AMDGPUDevice *gpu_device)
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
uint64_t Tick
Tick count type.
void setRegVal(uint32_t addr, uint32_t value)
uint16_t allocateVMID(uint16_t pasid)
AMDMMIOReader mmioReader
MMIO reader to populate device registers map.
PCI device, base implementation is only config space.
bool checkpoint_before_mmios
Initial checkpoint support variables.
void readROM(PacketPtr pkt)
bool getBAR(Addr addr, int &num, Addr &offs)
Which base address register (if any) maps the given address?
Device model for an AMD GPU.
void serialize(CheckpointOut &cp) const override
Checkpoint support.
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 dispatchAccess(PacketPtr pkt, bool read)
Convert a PCI packet into a response.
static constexpr uint32_t SDMA_OFFSET_SHIFT
#define SERIALIZE_ARRAY(member, size)
void readFrame(PacketPtr pkt, Addr offset)
Helper methods to handle specific BAR read/writes.
void readDoorbell(PacketPtr pkt, Addr offset)
System DMA Engine class for AMD dGPU.
void setGPUDevice(AMDGPUDevice *gpu_device)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
constexpr uint32_t ROM_SIZE
const std::string & name()
#define SERIALIZE_SCALAR(scalar)
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
constexpr uint32_t VGA_ROM_DEFAULT
std::unordered_map< uint16_t, std::set< int > > & getUsedVMIDs()
void readFromTrace(PacketPtr pkt, int barnum, Addr offset)
Get the next MMIO read from the trace file to an offset in a BAR and write the value to the packet pr...
static constexpr uint32_t IH_BASE
RequestorID getRequestorID() const
Get the requestorID for the memory manager.
void writeMMIO(PacketPtr pkt, Addr offset)
virtual Tick readConfig(PacketPtr pkt)
Read from the PCI config space data that is stored locally.
void readMMIO(PacketPtr pkt, Addr offset)
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.
#define UNSERIALIZE_ARRAY(member, size)
PM4Queue * getQueue(Addr offset, bool gfx=false)
Based on an offset communicated through doorbell write, the PM4PacketProcessor identifies which queue...
HWScheduler * hwScheduler()
AddrRange romRange
VGA ROM methods.
static constexpr uint32_t MMHUB_BASE
std::unordered_map< uint16_t, std::set< int > > usedVMIDs
void updateReadIndex(Addr offset, uint64_t rd_idx)
Update read index on doorbell rings.
void insertQId(uint16_t vmid, int id)
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
void setGPUDevice(AMDGPUDevice *gpu_device)
void deallocateVmid(uint16_t vmid)
virtual Tick read(PacketPtr pkt)=0
Pure virtual function that the device must implement.
void deallocatePasid(uint16_t pasid)
std::array< uint8_t, ROM_SIZE > rom
std::ostream CheckpointOut
static constexpr int AMDGPU_VM_COUNT
memory::PhysicalMemory deviceMem
void setLE(T v)
Set the value in the data pointer to v as little endian.
uint32_t getRegVal(uint32_t addr)
Register value getter/setter.
void write(Addr db_addr, uint64_t doorbell_reg)
void writeFrame(PacketPtr pkt, Addr offset)
void processGfx(Addr wptrOffset)
Given a new write ptr offset, communicated to the GPU through a doorbell write, the SDMA engine proce...
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
PM4PacketProcessor * pm4PktProc
void setSDMAEngine(Addr offset, SDMAEngine *eng)
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 ...
AddrRangeList getAddrRanges() const override
Determine the address ranges that this device responds to.
std::unordered_map< uint32_t, QueueType > doorbells
static constexpr uint32_t GRBM_BASE
static constexpr uint32_t SDMA0_BASE
AMDGPUInterruptHandler * deviceIH
#define panic(...)
This implements a cprintf based panic() function.
T * getPtr()
get a pointer to the data ptr.
#define PCI0_INTERRUPT_PIN
void writeMMIO(PacketPtr pkt, Addr mmio_offset)
Methods for setting the values of SDMA MMIO registers.
void writeDoorbell(PacketPtr pkt, Addr offset)
Generated on Wed Jul 13 2022 10:39:18 for gem5 by doxygen 1.8.17