diff --git a/src/dev/dma_virt_device.cc b/src/dev/dma_virt_device.cc index 2a392c24de..b377a03055 100644 --- a/src/dev/dma_virt_device.cc +++ b/src/dev/dma_virt_device.cc @@ -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; } } diff --git a/src/dev/dma_virt_device.hh b/src/dev/dma_virt_device.hh index 5c36d7b120..e38d291f56 100644 --- a/src/dev/dma_virt_device.hh +++ b/src/dev/dma_virt_device.hh @@ -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 diff --git a/src/dev/hsa/hsa_packet_processor.cc b/src/dev/hsa/hsa_packet_processor.cc index 22124b1a27..44c0e874d9 100644 --- a/src/dev/hsa/hsa_packet_processor.cc +++ b/src/dev/hsa/hsa_packet_processor.cc @@ -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); } /** diff --git a/src/dev/hsa/hsa_packet_processor.hh b/src/dev/hsa/hsa_packet_processor.hh index aabe24e1a9..144fe42078 100644 --- a/src/dev/hsa/hsa_packet_processor.hh +++ b/src/dev/hsa/hsa_packet_processor.hh @@ -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, diff --git a/src/gpu-compute/gpu_command_processor.cc b/src/gpu-compute/gpu_command_processor.cc index 88d7703d6c..a444c9dec7 100644 --- a/src/gpu-compute/gpu_command_processor.cc +++ b/src/gpu-compute/gpu_command_processor.cc @@ -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); } /** diff --git a/src/gpu-compute/gpu_command_processor.hh b/src/gpu-compute/gpu_command_processor.hh index 1c36c2b1d9..c9084d12b2 100644 --- a/src/gpu-compute/gpu_command_processor.hh +++ b/src/gpu-compute/gpu_command_processor.hh @@ -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