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:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user