dev,gpu-compute: Use a TranslationGen in DmaVirtDevice.

Use a TranslationGen to iterate over the translations for a region,
rather than using a ChunkGenerator with a fixed page size the device
needs to know.

Change-Id: I5da565232bd5282074ef279ca74e556daeffef70
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/50763
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Matthew Poremba <matthew.poremba@amd.com>
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Maintainer: Matthew Poremba <matthew.poremba@amd.com>
This commit is contained in:
Gabe Black
2021-09-21 17:12:00 -07:00
parent 74c246d15b
commit 07c613ff5e
6 changed files with 25 additions and 39 deletions

View File

@@ -36,11 +36,6 @@
namespace gem5
{
DmaVirtDevice::DmaVirtDevice(const Params& p)
: DmaDevice(p), pageBytes(p.system->getPageBytes())
{
}
void
DmaVirtDevice::dmaReadVirt(Addr host_addr, unsigned size,
DmaCallback *cb, void *data, Tick delay)
@@ -68,17 +63,13 @@ DmaVirtDevice::dmaVirt(DmaFnPtr dmaFn, Addr addr, unsigned size,
// move the buffer data pointer with the chunks
uint8_t *loc_data = (uint8_t*)data;
for (ChunkGenerator gen(addr, size, pageBytes); !gen.done(); gen.next()) {
Addr phys;
// translate pages into their corresponding frames
translateOrDie(gen.addr(), phys);
TranslationGenPtr gen = translate(addr, size);
for (const auto &range: *gen) {
fatal_if(range.fault, "Failed translation: vaddr 0x%x", range.vaddr);
Event *event = cb ? cb->getChunkEvent() : nullptr;
(this->*dmaFn)(phys, gen.size(), event, loc_data, delay);
loc_data += gen.size();
(this->*dmaFn)(range.paddr, range.size, event, loc_data, delay);
loc_data += range.size;
}
}

View File

@@ -35,15 +35,13 @@
#define __DEV_DMA_VIRT_DEVICE_HH__
#include "dev/dma_device.hh"
#include "mem/translation_gen.hh"
namespace gem5
{
class DmaVirtDevice : public DmaDevice
{
private:
Addr pageBytes;
protected:
/**
* Wraps a std::function object in a DmaCallback. Much cleaner than
@@ -72,7 +70,7 @@ class DmaVirtDevice : public DmaDevice
};
public:
DmaVirtDevice(const Params& p);
DmaVirtDevice(const Params& p) : DmaDevice(p) { }
virtual ~DmaVirtDevice() { }
/**
@@ -119,13 +117,15 @@ class DmaVirtDevice : public DmaDevice
DmaCallback *cb, void *data, Tick delay = 0);
/**
* Function used to translate from virtual to physical addresses. All
* classes inheriting from DmaVirtDevice must define this.
* Function used to translate a range of addresses from virtual to
* physical addresses. All classes inheriting from DmaVirtDevice must
* define this.
*
* @param vaddr Input virtual address
* @param paddr Output physical address written by reference
* @param vaddr Virtual address of the start of the range
* @param size Size of the range in bytes
* @return A translation generator for this range
*/
virtual void translateOrDie(Addr vaddr, Addr &paddr) = 0;
virtual TranslationGenPtr translate(Addr vaddr, Addr size) = 0;
};
} // namespace gem5

View File

@@ -162,16 +162,15 @@ HSAPacketProcessor::read(Packet *pkt)
return pioDelay;
}
void
HSAPacketProcessor::translateOrDie(Addr vaddr, Addr &paddr)
TranslationGenPtr
HSAPacketProcessor::translate(Addr vaddr, Addr size)
{
// Grab the process and try to translate the virtual address with it; with
// new extensions, it will likely be wrong to just arbitrarily grab context
// zero.
auto process = sys->threads[0]->getProcessPtr();
if (!process->pTable->translate(vaddr, paddr))
fatal("failed translation: vaddr 0x%x\n", vaddr);
return process->pTable->translateRange(vaddr, size);
}
/**

View File

@@ -348,7 +348,7 @@ class HSAPacketProcessor: public DmaVirtDevice
typedef HSAPacketProcessorParams Params;
HSAPacketProcessor(const Params &p);
~HSAPacketProcessor();
void translateOrDie(Addr vaddr, Addr &paddr) override;
TranslationGenPtr translate(Addr vaddr, Addr size) override;
void setDeviceQueueDesc(uint64_t hostReadIndexPointer,
uint64_t basePointer,
uint64_t queue_id,

View File

@@ -65,19 +65,15 @@ GPUCommandProcessor::hsaPacketProc()
return *hsaPP;
}
void
GPUCommandProcessor::translateOrDie(Addr vaddr, Addr &paddr)
TranslationGenPtr
GPUCommandProcessor::translate(Addr vaddr, Addr size)
{
/**
* Grab the process and try to translate the virtual address with it;
* with new extensions, it will likely be wrong to just arbitrarily
* grab context zero.
*/
// Grab the process and try to translate the virtual address with it; with
// new extensions, it will likely be wrong to just arbitrarily grab context
// zero.
auto process = sys->threads[0]->getProcessPtr();
if (!process->pTable->translate(vaddr, paddr)) {
fatal("failed translation: vaddr 0x%x\n", vaddr);
}
return process->pTable->translateRange(vaddr, size);
}
/**

View File

@@ -135,7 +135,7 @@ class GPUCommandProcessor : public DmaVirtDevice
typedef void (DmaDevice::*DmaFnPtr)(Addr, int, Event*, uint8_t*, Tick);
void initABI(HSAQueueEntry *task);
HSAPacketProcessor *hsaPP;
void translateOrDie(Addr vaddr, Addr &paddr) override;
TranslationGenPtr translate(Addr vaddr, Addr size) override;
/**
* Perform a DMA read of the read_dispatch_id_field_base_byte_offset