move dma allocator to driver

This commit is contained in:
Marcel Lütke Dreimann
2022-08-22 15:37:26 +02:00
parent 2c36153691
commit 40f696dcc8
11 changed files with 83 additions and 64 deletions

View File

@@ -15,7 +15,7 @@ struct gpgpu::Session : Genode::Session
enum { CAP_QUOTA = 1 };
virtual int say_hello(int& i) = 0;
virtual void register_vm(Genode::Ram_dataspace_capability& ram_cap) = 0;
virtual void register_vm(Genode::size_t size, Genode::Ram_dataspace_capability& ram_cap) = 0;
virtual int start_task(unsigned long kconf) = 0;
/*******************
@@ -23,7 +23,7 @@ struct gpgpu::Session : Genode::Session
*******************/
GENODE_RPC(Rpc_say_hello, int, say_hello, int&);
GENODE_RPC(Rpc_register_vm, void, register_vm, Genode::Ram_dataspace_capability&);
GENODE_RPC(Rpc_register_vm, void, register_vm, Genode::size_t, Genode::Ram_dataspace_capability&);
GENODE_RPC(Rpc_start_task, int, start_task, unsigned long);
GENODE_RPC_INTERFACE(Rpc_say_hello, Rpc_register_vm, Rpc_start_task);

View File

@@ -164,7 +164,29 @@ void gpgpu_genode::registerInterruptHandler()
irq->ack_irq();
}
addr_t gpgpu_genode::mapMemory(Genode::Ram_dataspace_capability& ram_cap_vm)
Genode::Ram_dataspace_capability gpgpu_genode::allocRamCap(Genode::size_t size, Genode::addr_t& mapped_base, Genode::addr_t& base)
{
return env.rm().attach(ram_cap_vm);
// get some memory
Genode::size_t donate = size;
Genode::Ram_dataspace_capability ram_cap =
Genode::retry<Genode::Out_of_ram>(
[&] () {
return Genode::retry<Genode::Out_of_caps>(
[&] () { return pci.alloc_dma_buffer(size, Genode::UNCACHED); },
[&] () { pci.upgrade_caps(2); });
},
[&] () {
pci.upgrade_ram(donate);
donate = donate * 2 > size ? 4096 : donate * 2;
});
// get virt and phys base
mapped_base = env.rm().attach(ram_cap);
base = pci.dma_addr(ram_cap);
return ram_cap;
}
void gpgpu_genode::freeRamCap(Genode::Ram_dataspace_capability& ram_cap)
{
pci.free_dma_buffer(ram_cap);
}

View File

@@ -134,10 +134,19 @@ public:
/**
* @brief
*
* @param ram_cap
* @return addr_t
* @param size
* @param mapped_base
* @param base
* @return Genode::Ram_dataspace_capability&
*/
addr_t mapMemory(Genode::Ram_dataspace_capability& ram_cap);
Genode::Ram_dataspace_capability allocRamCap(Genode::size_t size, Genode::addr_t& mapped_base, Genode::addr_t& base);
/**
* @brief
*
* @param ram_cap
*/
void freeRamCap(Genode::Ram_dataspace_capability& ram_cap);
};
#endif // GPGPU_GENODE_H

View File

@@ -5,7 +5,7 @@
#include "../uos-intel-gpgpu/driver/gpgpu_driver.h"
#include "gpgpu_genode.h"
//#define TEST // test stubs only (works with qemu)
#define TEST // test stubs only (works with qemu)
#ifdef TEST
#include "../uos-intel-gpgpu/stubs.h"
#else

View File

@@ -28,9 +28,10 @@ int gpgpu::Session_component::say_hello(int& i)
return 42;
}
void gpgpu::Session_component::register_vm(Genode::Ram_dataspace_capability& ram_cap)
void gpgpu::Session_component::register_vm(Genode::size_t size, Genode::Ram_dataspace_capability& ram_cap_vm)
{
mapped_base = _global_gpgpu_genode->mapMemory(ram_cap);
ram_cap = _global_gpgpu_genode->allocRamCap(size, mapped_base, base);
ram_cap_vm = ram_cap;
}
int gpgpu::Session_component::start_task(unsigned long kconf)
@@ -40,21 +41,25 @@ int gpgpu::Session_component::start_task(unsigned long kconf)
kc->buffConfigs = (struct buffer_config*)((Genode::addr_t)kc->buffConfigs + mapped_base);
for(int i = 0; i < kc->buffCount; i++)
{
if(kc->buffConfigs[i].non_pointer_type)
if(kc->buffConfigs[i].non_pointer_type) // for non pointer set virt addr
{
kc->buffConfigs[i].buffer = (void*)((Genode::addr_t)kc->buffConfigs[i].buffer + mapped_base);
kc->buffConfigs[i].buffer = (void*)((Genode::addr_t)kc->buffConfigs[i].buffer + mapped_base);
}
else // for pointer set phys addr
{
kc->buffConfigs[i].buffer = (void*)((Genode::addr_t)kc->buffConfigs[i].buffer + base);
}
}
kc->kernelName = (char*)((Genode::addr_t)kc->kernelName + mapped_base);
kc->binary = (Genode::uint8_t*)((Genode::addr_t)kc->binary + mapped_base);
// at this point all IO buffers should have phys addrs and all others have driver virt addrs
// set maximum frequency
GPGPU_Driver& gpgpudriver = GPGPU_Driver::getInstance();
gpgpudriver.setMaxFreq();
//GPGPU_Driver& gpgpudriver = GPGPU_Driver::getInstance();
//gpgpudriver.setMaxFreq();
// start gpu task
gpgpudriver.enqueueRun(*kc);
//gpgpudriver.enqueueRun(*kc);
kc->finished = true;
/*
Kernel* kernel = (Kernel*)_global_gpgpu_genode->aligned_alloc(0, sizeof(Kernel));
@@ -64,9 +69,21 @@ int gpgpu::Session_component::start_task(unsigned long kconf)
*/
static int id = 0;
Genode::log("Kernel ", id);
for(int i = 0; i < kc->buffCount; i++)
{
Genode::log("\tBuffer ", i);
Genode::log("\t\taddr: ", (void*)kc->buffConfigs[i].buffer);
Genode::log("\t\tsize: ", (int)kc->buffConfigs[i].buffer_size);
}
return id++;
}
gpgpu::Session_component::~Session_component()
{
_global_gpgpu_genode->freeRamCap(ram_cap);
}
gpgpu::Session_component* gpgpu::Root_component::_create_session(const char *)
{
return new (md_alloc()) gpgpu::Session_component();

View File

@@ -16,13 +16,17 @@ namespace gpgpu {
struct gpgpu::Session_component : Genode::Rpc_object<Session>
{
VGpu vgpu;
Genode::Ram_dataspace_capability ram_cap;
Genode::addr_t mapped_base;
Genode::addr_t base;
Session_component() : vgpu(), mapped_base(0) {}
Session_component() : vgpu(), ram_cap(), mapped_base(0), base(0) {}
~Session_component();
int say_hello(int& i) override;
void register_vm(Genode::Ram_dataspace_capability& ram_cap) override;
void register_vm(Genode::size_t size, Genode::Ram_dataspace_capability& ram_cap) override;
int start_task(unsigned long kconf) override;
};

View File

@@ -17,9 +17,9 @@ struct gpgpu::Session_client : Genode::Rpc_client<gpgpu::Session>
return call<Rpc_start_task>(kconf);
}
void register_vm(Genode::Ram_dataspace_capability& ram_cap) override
void register_vm(Genode::size_t size, Genode::Ram_dataspace_capability& ram_cap) override
{
call<Rpc_register_vm>(ram_cap);
call<Rpc_register_vm>(size, ram_cap);
}
int say_hello(int& i) override

View File

@@ -56,7 +56,7 @@ append_platform_drv_config
append config {
<start name="gpgpu">
<provides> <service name="gpgpu"/> </provides>
<resource name="RAM" quantum="32M"/>
<resource name="RAM" quantum="1024M"/>
</start>
<start name="hello_gpgpu">
<resource name="RAM" quantum="1024M"/>

View File

@@ -353,10 +353,11 @@ clCreateBuffer(cl_context context,
else
{
clmem->ocl_allocated = false;
Genode::error("[OCL] Memory mapping is currently unsupported!");
}
clmem->virt_vm = host_ptr;
clmem->bc.buffer = (void*)g_cl_genode->virt_to_phys((Genode::addr_t)host_ptr);
clmem->bc.buffer = host_ptr;
clmem->bc.buffer_size = (uint32_t)size;
clmem->bc.non_pointer_type = false;

View File

@@ -1,36 +1,21 @@
#include "cl_genode.h"
cl_genode::cl_genode(Genode::Env& env, unsigned long size) : env(env), heap{ env.ram(), env.rm() }, allocator(&heap), ram_cap(), mapped_base(0), base(0), pci(env), backend_driver(env)
cl_genode::cl_genode(Genode::Env& env, unsigned long size) : env(env), heap{ env.ram(), env.rm() }, allocator(&heap), mapped_base(0), backend_driver(env)
{
// get some memory
Genode::size_t donate = size;
ram_cap =
Genode::retry<Genode::Out_of_ram>(
[&] () {
return Genode::retry<Genode::Out_of_caps>(
[&] () { return pci.alloc_dma_buffer(size, Genode::UNCACHED); },
[&] () { pci.upgrade_caps(2); });
},
[&] () {
pci.upgrade_ram(donate);
donate = donate * 2 > size ? 4096 : donate * 2;
});
// get shared memory with driver
Genode::Ram_dataspace_capability ram_cap;
backend_driver.register_vm(size, ram_cap);
// get virt and phys base
// attach it to vm
mapped_base = env.rm().attach(ram_cap);
base = pci.dma_addr(ram_cap);
// use it in allocator
allocator.add_range(mapped_base, size);
// map it for backend driver
backend_driver.register_vm(ram_cap);
}
cl_genode::~cl_genode()
{
// release pci dev and free allocator memory
env.ram().free(ram_cap);
}
void* cl_genode::aligned_alloc(Genode::uint32_t alignment, Genode::uint32_t size)
@@ -79,10 +64,7 @@ int cl_genode::enqueue_task(struct kernel_config* kconf)
// convert virt vm addr to offset
for(int i = 0; i < kconf->buffCount; i++)
{
if(kconf->buffConfigs[i].non_pointer_type)
{
kconf->buffConfigs[i].buffer = (void*)((Genode::addr_t)kconf->buffConfigs[i].buffer - mapped_base);
}
kconf->buffConfigs[i].buffer = (void*)((Genode::addr_t)kconf->buffConfigs[i].buffer - mapped_base);
}
kconf->buffConfigs = (struct buffer_config*)((Genode::addr_t)kconf->buffConfigs - mapped_base);
kconf->kernelName = (char*)((Genode::addr_t)kconf->kernelName - mapped_base);

View File

@@ -27,12 +27,7 @@ private:
// allocator
Genode::Heap heap;
Genode::Allocator_avl allocator;
Genode::Ram_dataspace_capability ram_cap;
Genode::addr_t mapped_base;
Genode::addr_t base;
// pci
Platform::Connection pci;
// rpc
gpgpu::Connection backend_driver;
@@ -88,17 +83,6 @@ public:
return allocator;
}
/**
* @brief converts a virtual address into a physical address
*
* @param virt the virtual address
* @return addr_t the physical address
*/
Genode::addr_t virt_to_phys(Genode::addr_t virt) const
{
return virt - mapped_base + base;
}
/**
* @brief
*