mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-24 07:46:42 +00:00
gpu/intel: free DMA, clear ggtt
* free DMA caps in case platform client's session is closed * clear GGTT of platform client upon session close issue #4233
This commit is contained in:
parent
6c003a13d2
commit
1727de30b7
@ -85,23 +85,8 @@ struct Igd::Device
|
|||||||
Env &_env;
|
Env &_env;
|
||||||
Allocator &_md_alloc;
|
Allocator &_md_alloc;
|
||||||
|
|
||||||
/***********
|
|
||||||
** Timer **
|
|
||||||
***********/
|
|
||||||
|
|
||||||
Timer::Connection _timer { _env };
|
|
||||||
|
|
||||||
enum { WATCHDOG_TIMEOUT = 1*1000*1000, };
|
enum { WATCHDOG_TIMEOUT = 1*1000*1000, };
|
||||||
|
|
||||||
struct Timer_delayer : Genode::Mmio::Delayer
|
|
||||||
{
|
|
||||||
Timer::Connection &_timer;
|
|
||||||
Timer_delayer(Timer::Connection &timer) : _timer(timer) { }
|
|
||||||
|
|
||||||
void usleep(uint64_t us) override { _timer.usleep(us); }
|
|
||||||
|
|
||||||
} _delayer { _timer };
|
|
||||||
|
|
||||||
/*********
|
/*********
|
||||||
** PCI **
|
** PCI **
|
||||||
*********/
|
*********/
|
||||||
@ -193,7 +178,7 @@ struct Igd::Device
|
|||||||
** MMIO **
|
** MMIO **
|
||||||
**********/
|
**********/
|
||||||
|
|
||||||
Genode::Constructible<Igd::Mmio> _mmio { };
|
Igd::Mmio &_mmio { _resources.mmio() };
|
||||||
|
|
||||||
/************
|
/************
|
||||||
** MEMORY **
|
** MEMORY **
|
||||||
@ -732,7 +717,7 @@ struct Igd::Device
|
|||||||
{
|
{
|
||||||
Execlist &el = *engine.execlist;
|
Execlist &el = *engine.execlist;
|
||||||
|
|
||||||
int const port = _mmio->read<Igd::Mmio::EXECLIST_STATUS_RSCUNIT::Execlist_write_pointer>();
|
int const port = _mmio.read<Igd::Mmio::EXECLIST_STATUS_RSCUNIT::Execlist_write_pointer>();
|
||||||
|
|
||||||
el.schedule(port);
|
el.schedule(port);
|
||||||
|
|
||||||
@ -742,10 +727,10 @@ struct Igd::Device
|
|||||||
desc[1] = el.elem0().high();
|
desc[1] = el.elem0().high();
|
||||||
desc[0] = el.elem0().low();
|
desc[0] = el.elem0().low();
|
||||||
|
|
||||||
_mmio->write<Igd::Mmio::EXECLIST_SUBMITPORT_RSCUNIT>(desc[3]);
|
_mmio.write<Igd::Mmio::EXECLIST_SUBMITPORT_RSCUNIT>(desc[3]);
|
||||||
_mmio->write<Igd::Mmio::EXECLIST_SUBMITPORT_RSCUNIT>(desc[2]);
|
_mmio.write<Igd::Mmio::EXECLIST_SUBMITPORT_RSCUNIT>(desc[2]);
|
||||||
_mmio->write<Igd::Mmio::EXECLIST_SUBMITPORT_RSCUNIT>(desc[1]);
|
_mmio.write<Igd::Mmio::EXECLIST_SUBMITPORT_RSCUNIT>(desc[1]);
|
||||||
_mmio->write<Igd::Mmio::EXECLIST_SUBMITPORT_RSCUNIT>(desc[0]);
|
_mmio.write<Igd::Mmio::EXECLIST_SUBMITPORT_RSCUNIT>(desc[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vgpu *_unschedule_current_vgpu()
|
Vgpu *_unschedule_current_vgpu()
|
||||||
@ -774,19 +759,19 @@ struct Igd::Device
|
|||||||
|
|
||||||
Engine<Rcs_context> &rcs = gpu->rcs;
|
Engine<Rcs_context> &rcs = gpu->rcs;
|
||||||
|
|
||||||
_mmio->flush_gfx_tlb();
|
_mmio.flush_gfx_tlb();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX check if HWSP is shared across contexts and if not when
|
* XXX check if HWSP is shared across contexts and if not when
|
||||||
* we actually need to write the register
|
* we actually need to write the register
|
||||||
*/
|
*/
|
||||||
Mmio::HWS_PGA_RCSUNIT::access_t const addr = rcs.hw_status_page();
|
Mmio::HWS_PGA_RCSUNIT::access_t const addr = rcs.hw_status_page();
|
||||||
_mmio->write_post<Igd::Mmio::HWS_PGA_RCSUNIT>(addr);
|
_mmio.write_post<Igd::Mmio::HWS_PGA_RCSUNIT>(addr);
|
||||||
|
|
||||||
_submit_execlist(rcs);
|
_submit_execlist(rcs);
|
||||||
|
|
||||||
_active_vgpu = gpu;
|
_active_vgpu = gpu;
|
||||||
_timer.trigger_once(WATCHDOG_TIMEOUT);
|
_resources.timer().trigger_once(WATCHDOG_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********
|
/**********
|
||||||
@ -795,7 +780,7 @@ struct Igd::Device
|
|||||||
|
|
||||||
void _clear_rcs_iir(Mmio::GT_0_INTERRUPT_IIR::access_t const v)
|
void _clear_rcs_iir(Mmio::GT_0_INTERRUPT_IIR::access_t const v)
|
||||||
{
|
{
|
||||||
_mmio->write_post<Mmio::GT_0_INTERRUPT_IIR>(v);
|
_mmio.write_post<Mmio::GT_0_INTERRUPT_IIR>(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -830,7 +815,7 @@ struct Igd::Device
|
|||||||
|
|
||||||
uint32_t _get_free_fence()
|
uint32_t _get_free_fence()
|
||||||
{
|
{
|
||||||
return _mmio->find_free_fence();
|
return _mmio.find_free_fence();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t _update_fence(uint32_t const id,
|
uint32_t _update_fence(uint32_t const id,
|
||||||
@ -839,12 +824,12 @@ struct Igd::Device
|
|||||||
uint32_t const pitch,
|
uint32_t const pitch,
|
||||||
bool const tile_x)
|
bool const tile_x)
|
||||||
{
|
{
|
||||||
return _mmio->update_fence(id, lower, upper, pitch, tile_x);
|
return _mmio.update_fence(id, lower, upper, pitch, tile_x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _clear_fence(uint32_t const id)
|
void _clear_fence(uint32_t const id)
|
||||||
{
|
{
|
||||||
_mmio->clear_fence(id);
|
_mmio.clear_fence(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
@ -857,10 +842,10 @@ struct Igd::Device
|
|||||||
|
|
||||||
Genode::error("watchdog triggered: engine stuck,"
|
Genode::error("watchdog triggered: engine stuck,"
|
||||||
" vGPU=", _active_vgpu->id());
|
" vGPU=", _active_vgpu->id());
|
||||||
_mmio->dump();
|
_mmio.dump();
|
||||||
_mmio->error_dump();
|
_mmio.error_dump();
|
||||||
_mmio->fault_dump();
|
_mmio.fault_dump();
|
||||||
_mmio->execlist_status_dump();
|
_mmio.execlist_status_dump();
|
||||||
|
|
||||||
_active_vgpu->rcs.context->dump();
|
_active_vgpu->rcs.context->dump();
|
||||||
_active_vgpu->rcs.context->dump_hw_status_page();
|
_active_vgpu->rcs.context->dump_hw_status_page();
|
||||||
@ -883,11 +868,11 @@ struct Igd::Device
|
|||||||
|
|
||||||
void _device_reset_and_init()
|
void _device_reset_and_init()
|
||||||
{
|
{
|
||||||
_mmio->reset();
|
_mmio.reset();
|
||||||
_mmio->clear_errors();
|
_mmio.clear_errors();
|
||||||
_mmio->init();
|
_mmio.init();
|
||||||
_mmio->enable_intr();
|
_mmio.enable_intr();
|
||||||
_mmio->forcewake_enable();
|
_mmio.forcewake_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -928,11 +913,9 @@ struct Igd::Device
|
|||||||
|
|
||||||
/* map PCI resources */
|
/* map PCI resources */
|
||||||
addr_t gttmmadr_base = _resources.map_gttmmadr();
|
addr_t gttmmadr_base = _resources.map_gttmmadr();
|
||||||
_mmio.construct(_delayer, gttmmadr_base);
|
|
||||||
|
|
||||||
/* GGTT */
|
/* GGTT */
|
||||||
Ram_dataspace_capability scratch_page_ds = _pci_backend_alloc.alloc(PAGE_SIZE);
|
addr_t const scratch_page = _resources.scratch_page();
|
||||||
addr_t const scratch_page = Dataspace_client(scratch_page_ds).phys_addr();
|
|
||||||
|
|
||||||
/* reserverd size for framebuffer */
|
/* reserverd size for framebuffer */
|
||||||
size_t const aperture_reserved = resources.gmadr_platform_size();
|
size_t const aperture_reserved = resources.gmadr_platform_size();
|
||||||
@ -940,18 +923,17 @@ struct Igd::Device
|
|||||||
size_t const ggtt_size = (1u << MGGC_0_2_0_PCI::Gtt_graphics_memory_size::get(v)) << 20;
|
size_t const ggtt_size = (1u << MGGC_0_2_0_PCI::Gtt_graphics_memory_size::get(v)) << 20;
|
||||||
addr_t const ggtt_base = gttmmadr_base + (_resources.gttmmadr_size() / 2);
|
addr_t const ggtt_base = gttmmadr_base + (_resources.gttmmadr_size() / 2);
|
||||||
size_t const gmadr_size = _resources.gmadr_size();
|
size_t const gmadr_size = _resources.gmadr_size();
|
||||||
_ggtt.construct(*_mmio, ggtt_base, ggtt_size, gmadr_size, scratch_page, aperture_reserved);
|
_ggtt.construct(_mmio, ggtt_base, ggtt_size, gmadr_size, scratch_page, aperture_reserved);
|
||||||
_ggtt->dump();
|
_ggtt->dump();
|
||||||
|
|
||||||
_vgpu_avail = (gmadr_size - aperture_reserved) / Vgpu::APERTURE_SIZE;
|
_vgpu_avail = (gmadr_size - aperture_reserved) / Vgpu::APERTURE_SIZE;
|
||||||
|
|
||||||
_device_reset_and_init();
|
_device_reset_and_init();
|
||||||
|
|
||||||
|
_mmio.dump();
|
||||||
|
_mmio.context_status_pointer_dump();
|
||||||
|
|
||||||
_mmio->dump();
|
_resources.timer().sigh(_watchdog_timeout_sigh);
|
||||||
_mmio->context_status_pointer_dump();
|
|
||||||
|
|
||||||
_timer.sigh(_watchdog_timeout_sigh);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
@ -1105,7 +1087,7 @@ struct Igd::Device
|
|||||||
uint32_t set_tiling(Ggtt::Offset const start, size_t const size,
|
uint32_t set_tiling(Ggtt::Offset const start, size_t const size,
|
||||||
uint32_t const mode)
|
uint32_t const mode)
|
||||||
{
|
{
|
||||||
uint32_t const id = _mmio->find_free_fence();
|
uint32_t const id = _mmio.find_free_fence();
|
||||||
if (id == INVALID_FENCE) {
|
if (id == INVALID_FENCE) {
|
||||||
Genode::warning("could not find free FENCE");
|
Genode::warning("could not find free FENCE");
|
||||||
return id;
|
return id;
|
||||||
@ -1130,15 +1112,15 @@ struct Igd::Device
|
|||||||
|
|
||||||
unsigned handle_irq()
|
unsigned handle_irq()
|
||||||
{
|
{
|
||||||
Mmio::MASTER_INT_CTL::access_t master = _mmio->read<Mmio::MASTER_INT_CTL>();
|
Mmio::MASTER_INT_CTL::access_t master = _mmio.read<Mmio::MASTER_INT_CTL>();
|
||||||
|
|
||||||
/* handle render interrupts only */
|
/* handle render interrupts only */
|
||||||
if (Mmio::MASTER_INT_CTL::Render_interrupts_pending::get(master) == 0)
|
if (Mmio::MASTER_INT_CTL::Render_interrupts_pending::get(master) == 0)
|
||||||
return master;
|
return master;
|
||||||
|
|
||||||
_mmio->disable_master_irq();
|
_mmio.disable_master_irq();
|
||||||
|
|
||||||
Mmio::GT_0_INTERRUPT_IIR::access_t const v = _mmio->read<Mmio::GT_0_INTERRUPT_IIR>();
|
Mmio::GT_0_INTERRUPT_IIR::access_t const v = _mmio.read<Mmio::GT_0_INTERRUPT_IIR>();
|
||||||
|
|
||||||
bool const ctx_switch = Mmio::GT_0_INTERRUPT_IIR::Cs_ctx_switch_interrupt::get(v);
|
bool const ctx_switch = Mmio::GT_0_INTERRUPT_IIR::Cs_ctx_switch_interrupt::get(v);
|
||||||
(void)ctx_switch;
|
(void)ctx_switch;
|
||||||
@ -1153,10 +1135,10 @@ struct Igd::Device
|
|||||||
notify_gpu->user_complete();
|
notify_gpu->user_complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool const fault_valid = _mmio->fault_regs_valid();
|
bool const fault_valid = _mmio.fault_regs_valid();
|
||||||
if (fault_valid) { Genode::error("FAULT_REG valid"); }
|
if (fault_valid) { Genode::error("FAULT_REG valid"); }
|
||||||
|
|
||||||
_mmio->update_context_status_pointer();
|
_mmio.update_context_status_pointer();
|
||||||
|
|
||||||
if (user_complete) {
|
if (user_complete) {
|
||||||
_unschedule_current_vgpu();
|
_unschedule_current_vgpu();
|
||||||
@ -1176,7 +1158,7 @@ struct Igd::Device
|
|||||||
return master;
|
return master;
|
||||||
}
|
}
|
||||||
|
|
||||||
void enable_master_irq() { _mmio->enable_master_irq(); }
|
void enable_master_irq() { _mmio.enable_master_irq(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -1623,9 +1605,10 @@ struct Main
|
|||||||
Genode::Sliced_heap _root_heap { _env.ram(), _env.rm() };
|
Genode::Sliced_heap _root_heap { _env.ram(), _env.rm() };
|
||||||
Gpu::Root _gpu_root { _env, _root_heap };
|
Gpu::Root _gpu_root { _env, _root_heap };
|
||||||
|
|
||||||
Genode::Heap _device_md_alloc;
|
Genode::Heap _device_md_alloc { _env.ram(), _env.rm() };
|
||||||
Genode::Constructible<Igd::Device> _device { };
|
Genode::Constructible<Igd::Device> _device { };
|
||||||
Igd::Resources _gpu_resources { _env, *this, &Main::ack_irq };
|
Igd::Resources _gpu_resources { _env, _device_md_alloc,
|
||||||
|
*this, &Main::ack_irq };
|
||||||
|
|
||||||
Genode::Irq_session_client _irq { _gpu_resources.gpu_client().irq(0) };
|
Genode::Irq_session_client _irq { _gpu_resources.gpu_client().irq(0) };
|
||||||
Genode::Signal_handler<Main> _irq_dispatcher {
|
Genode::Signal_handler<Main> _irq_dispatcher {
|
||||||
@ -1635,24 +1618,21 @@ struct Main
|
|||||||
|
|
||||||
Main(Genode::Env &env)
|
Main(Genode::Env &env)
|
||||||
:
|
:
|
||||||
_env(env), _device_md_alloc(_env.ram(), _env.rm())
|
_env(env)
|
||||||
{
|
{
|
||||||
/* IRQ */
|
/* IRQ */
|
||||||
_irq.sigh(_irq_dispatcher);
|
_irq.sigh(_irq_dispatcher);
|
||||||
_irq.ack_irq();
|
_irq.ack_irq();
|
||||||
|
|
||||||
/* platform service */
|
|
||||||
_platform_root.construct(_env, _device_md_alloc, _gpu_resources);
|
|
||||||
|
|
||||||
/* GPU */
|
/* GPU */
|
||||||
try {
|
try {
|
||||||
_device.construct(_env, _device_md_alloc, _gpu_resources);
|
_device.construct(_env, _device_md_alloc, _gpu_resources);
|
||||||
} catch (...) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_gpu_root.manage(*_device);
|
_gpu_root.manage(*_device);
|
||||||
_env.parent().announce(_env.ep().manage(_gpu_root));
|
_env.parent().announce(_env.ep().manage(_gpu_root));
|
||||||
|
} catch (...) { }
|
||||||
|
|
||||||
|
/* platform service */
|
||||||
|
_platform_root.construct(_env, _device_md_alloc, _gpu_resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_irq()
|
void handle_irq()
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* \brief Platform service implementation
|
* \brief Platform service implementation
|
||||||
* \author Sebastian Sumpf
|
* \author Sebastian Sumpf
|
||||||
* \author Josef Soentgen
|
|
||||||
* \date 2021-07-16
|
* \date 2021-07-16
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -196,6 +195,23 @@ class Platform::Session_component : public Rpc_object<Session>
|
|||||||
Device_component _device_component;
|
Device_component _device_component;
|
||||||
Connection &_platform;
|
Connection &_platform;
|
||||||
Device_capability _bridge;
|
Device_capability _bridge;
|
||||||
|
Igd::Resources &_resources;
|
||||||
|
|
||||||
|
struct Dma_cap
|
||||||
|
{
|
||||||
|
Ram_dataspace_capability cap;
|
||||||
|
|
||||||
|
Dma_cap(Ram_dataspace_capability cap)
|
||||||
|
: cap(cap) { }
|
||||||
|
|
||||||
|
virtual ~Dma_cap() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* track DMA memory allocations so we can free them at session
|
||||||
|
* destruction
|
||||||
|
*/
|
||||||
|
Registry<Registered<Dma_cap>> _dma_registry { };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -204,7 +220,8 @@ class Platform::Session_component : public Rpc_object<Session>
|
|||||||
_env(env),
|
_env(env),
|
||||||
_device_component(env, resources),
|
_device_component(env, resources),
|
||||||
_platform(resources.platform()),
|
_platform(resources.platform()),
|
||||||
_bridge(resources.host_bridge_cap())
|
_bridge(resources.host_bridge_cap()),
|
||||||
|
_resources(resources)
|
||||||
{
|
{
|
||||||
_env.ep().rpc_ep().manage(&_device_component);
|
_env.ep().rpc_ep().manage(&_device_component);
|
||||||
}
|
}
|
||||||
@ -212,13 +229,21 @@ class Platform::Session_component : public Rpc_object<Session>
|
|||||||
~Session_component()
|
~Session_component()
|
||||||
{
|
{
|
||||||
_env.ep().rpc_ep().dissolve(&_device_component);
|
_env.ep().rpc_ep().dissolve(&_device_component);
|
||||||
|
|
||||||
|
/* clear ggtt */
|
||||||
|
_resources.gtt_platform_reset();
|
||||||
|
|
||||||
|
/* free DMA allocations */
|
||||||
|
_dma_registry.for_each([&](Dma_cap &dma) {
|
||||||
|
_platform.free_dma_buffer(dma.cap);
|
||||||
|
destroy(&_resources.heap(), &dma);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Device_capability first_device(unsigned device_class, unsigned class_mask) override
|
Device_capability first_device(unsigned device_class, unsigned) override
|
||||||
{
|
{
|
||||||
enum { ISA_BRIDGE = 0x601u << 8 };
|
if (device_class == _resources.isa_bridge_class())
|
||||||
if (device_class == ISA_BRIDGE)
|
return _resources.isa_bridge_cap();
|
||||||
return _platform.first_device(device_class, class_mask);
|
|
||||||
|
|
||||||
return _bridge;
|
return _bridge;
|
||||||
}
|
}
|
||||||
@ -232,15 +257,10 @@ class Platform::Session_component : public Rpc_object<Session>
|
|||||||
return Device_capability();
|
return Device_capability();
|
||||||
}
|
}
|
||||||
|
|
||||||
void release_device(Device_capability device) override
|
void release_device(Device_capability) override
|
||||||
{
|
{
|
||||||
if (device.valid() == false) return;
|
|
||||||
|
|
||||||
if (_device_component.cap() == device || device == _bridge) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_platform.release_device(device);
|
|
||||||
}
|
|
||||||
|
|
||||||
Device_capability device(Device_name const & /* string */) override
|
Device_capability device(Device_name const & /* string */) override
|
||||||
{
|
{
|
||||||
@ -250,12 +270,20 @@ class Platform::Session_component : public Rpc_object<Session>
|
|||||||
|
|
||||||
Ram_dataspace_capability alloc_dma_buffer(size_t size, Cache cache) override
|
Ram_dataspace_capability alloc_dma_buffer(size_t size, Cache cache) override
|
||||||
{
|
{
|
||||||
return _platform.alloc_dma_buffer(size, cache);
|
Ram_dataspace_capability cap = _platform.alloc_dma_buffer(size, cache);
|
||||||
|
new (&_resources.heap()) Registered<Dma_cap>(_dma_registry, cap);
|
||||||
|
return cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_dma_buffer(Ram_dataspace_capability cap) override
|
void free_dma_buffer(Ram_dataspace_capability cap) override
|
||||||
{
|
{
|
||||||
|
if (!cap.valid()) return;
|
||||||
|
|
||||||
|
_dma_registry.for_each([&](Dma_cap &dma) {
|
||||||
|
if ((dma.cap == cap) == false) return;
|
||||||
_platform.free_dma_buffer(cap);
|
_platform.free_dma_buffer(cap);
|
||||||
|
destroy(&_resources.heap(), &dma);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addr_t dma_addr(Ram_dataspace_capability cap) override
|
addr_t dma_addr(Ram_dataspace_capability cap) override
|
||||||
|
@ -31,8 +31,22 @@ class Igd::Resources : Genode::Noncopyable
|
|||||||
|
|
||||||
using Io_mem_connection = Genode::Io_mem_connection;
|
using Io_mem_connection = Genode::Io_mem_connection;
|
||||||
using Io_mem_dataspace_capability = Genode::Io_mem_dataspace_capability;
|
using Io_mem_dataspace_capability = Genode::Io_mem_dataspace_capability;
|
||||||
|
using Ram_dataspace_capability = Genode::Ram_dataspace_capability;
|
||||||
|
|
||||||
Genode::Env &_env;
|
Genode::Env &_env;
|
||||||
|
Genode::Heap &_heap;
|
||||||
|
|
||||||
|
/* timer */
|
||||||
|
Timer::Connection _timer { _env };
|
||||||
|
|
||||||
|
struct Timer_delayer : Genode::Mmio::Delayer
|
||||||
|
{
|
||||||
|
Timer::Connection &_timer;
|
||||||
|
Timer_delayer(Timer::Connection &timer) : _timer(timer) { }
|
||||||
|
|
||||||
|
void usleep(uint64_t us) override { _timer.usleep(us); }
|
||||||
|
|
||||||
|
} _delayer { _timer };
|
||||||
|
|
||||||
/* irq callback */
|
/* irq callback */
|
||||||
Main &_obj;
|
Main &_obj;
|
||||||
@ -43,15 +57,26 @@ class Igd::Resources : Genode::Noncopyable
|
|||||||
|
|
||||||
Platform::Device_capability _gpu_cap { };
|
Platform::Device_capability _gpu_cap { };
|
||||||
Platform::Device_capability _host_bridge_cap { };
|
Platform::Device_capability _host_bridge_cap { };
|
||||||
|
Platform::Device_capability _isa_bridge_cap { };
|
||||||
Genode::Constructible<Platform::Device_client> _gpu_client { };
|
Genode::Constructible<Platform::Device_client> _gpu_client { };
|
||||||
|
|
||||||
/* mmio + gtt */
|
/* mmio + ggtt */
|
||||||
Platform::Device::Resource _gttmmadr { };
|
Platform::Device::Resource _gttmmadr { };
|
||||||
Io_mem_dataspace_capability _gttmmadr_ds { };
|
Io_mem_dataspace_capability _gttmmadr_ds { };
|
||||||
Genode::Constructible<Io_mem_connection> _gttmmadr_io { };
|
Genode::Constructible<Io_mem_connection> _gttmmadr_io { };
|
||||||
|
addr_t _gttmmadr_local { 0 };
|
||||||
|
|
||||||
|
Genode::Constructible<Igd::Mmio> _mmio { };
|
||||||
|
|
||||||
|
/* scratch page for ggtt */
|
||||||
|
Ram_dataspace_capability _scratch_page_ds {
|
||||||
|
_platform.with_upgrade([&] () {
|
||||||
|
return _platform.alloc_dma_buffer(PAGE_SIZE, Genode::UNCACHED); }) };
|
||||||
|
|
||||||
|
addr_t _scratch_page {
|
||||||
|
Genode::Dataspace_client(_scratch_page_ds).phys_addr() };
|
||||||
|
|
||||||
/* aperture */
|
/* aperture */
|
||||||
Platform::Device::Resource _gmadr { };
|
|
||||||
enum {
|
enum {
|
||||||
/* reserved aperture for platform service */
|
/* reserved aperture for platform service */
|
||||||
APERTURE_RESERVED = 64u<<20,
|
APERTURE_RESERVED = 64u<<20,
|
||||||
@ -59,14 +84,12 @@ class Igd::Resources : Genode::Noncopyable
|
|||||||
GTT_RESERVED = (APERTURE_RESERVED/PAGE_SIZE) * 8,
|
GTT_RESERVED = (APERTURE_RESERVED/PAGE_SIZE) * 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Platform::Device::Resource _gmadr { };
|
||||||
|
|
||||||
/* managed dataspace for local platform service */
|
/* managed dataspace for local platform service */
|
||||||
Genode::Rm_connection _rm_connection { _env };
|
Genode::Rm_connection _rm_connection { _env };
|
||||||
Genode::Constructible<Genode::Region_map_client> _gttmmadr_rm { };
|
Genode::Constructible<Genode::Region_map_client> _gttmmadr_rm { };
|
||||||
|
|
||||||
/**********
|
|
||||||
** Mmio **
|
|
||||||
**********/
|
|
||||||
|
|
||||||
void _create_gttmmadr_rm()
|
void _create_gttmmadr_rm()
|
||||||
{
|
{
|
||||||
using off_t = Genode::off_t;
|
using off_t = Genode::off_t;
|
||||||
@ -135,6 +158,12 @@ class Igd::Resources : Genode::Noncopyable
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (device.class_code() == isa_bridge_class()) {
|
||||||
|
_isa_bridge_cap = cap;
|
||||||
|
release = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
release = true;
|
release = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -185,9 +214,10 @@ class Igd::Resources : Genode::Noncopyable
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Resources(Genode::Env &env, Main &obj, void (Main::*ack_irq) ())
|
Resources(Genode::Env &env, Genode::Heap &heap,
|
||||||
|
Main &obj, void (Main::*ack_irq) ())
|
||||||
:
|
:
|
||||||
_env(env), _obj(obj), _ack_irq(ack_irq)
|
_env(env), _heap(heap), _obj(obj), _ack_irq(ack_irq)
|
||||||
{
|
{
|
||||||
/* initial donation for device pd */
|
/* initial donation for device pd */
|
||||||
_platform.upgrade_ram(1024*1024);
|
_platform.upgrade_ram(1024*1024);
|
||||||
@ -207,7 +237,7 @@ class Igd::Resources : Genode::Noncopyable
|
|||||||
|
|
||||||
_enable_pci_bus_master();
|
_enable_pci_bus_master();
|
||||||
|
|
||||||
Genode::log("Reserved beginning ",
|
log("Reserved beginning ",
|
||||||
Genode::Number_of_bytes(APERTURE_RESERVED),
|
Genode::Number_of_bytes(APERTURE_RESERVED),
|
||||||
" of aperture for platform service");
|
" of aperture for platform service");
|
||||||
}
|
}
|
||||||
@ -223,14 +253,16 @@ class Igd::Resources : Genode::Noncopyable
|
|||||||
if (!_gttmmadr_ds.valid())
|
if (!_gttmmadr_ds.valid())
|
||||||
throw Initialization_failed();
|
throw Initialization_failed();
|
||||||
|
|
||||||
addr_t addr = (addr_t)(_env.rm().attach(_gttmmadr_ds, _gttmmadr.size()));
|
if (_gttmmadr_local) return _gttmmadr_local;
|
||||||
|
|
||||||
|
_gttmmadr_local = (addr_t)(_env.rm().attach(_gttmmadr_ds, _gttmmadr.size()));
|
||||||
|
|
||||||
log("Map res:", 0,
|
log("Map res:", 0,
|
||||||
" base:", Genode::Hex(_gttmmadr.base()),
|
" base:", Genode::Hex(_gttmmadr.base()),
|
||||||
" size:", Genode::Hex(_gttmmadr.size()),
|
" size:", Genode::Hex(_gttmmadr.size()),
|
||||||
" vaddr:", Genode::Hex(addr));
|
" vaddr:", Genode::Hex(_gttmmadr_local));
|
||||||
|
|
||||||
return addr;
|
return _gttmmadr_local;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -254,19 +286,24 @@ class Igd::Resources : Genode::Noncopyable
|
|||||||
|
|
||||||
void ack_irq() { (_obj.*_ack_irq)(); }
|
void ack_irq() { (_obj.*_ack_irq)(); }
|
||||||
|
|
||||||
|
Genode::Heap &heap() { return _heap; }
|
||||||
|
Timer::Connection &timer() { return _timer; };
|
||||||
|
addr_t scratch_page() const { return _scratch_page; }
|
||||||
|
|
||||||
Platform::Connection &platform() { return _platform; }
|
Platform::Connection &platform() { return _platform; }
|
||||||
Platform::Device_client &gpu_client() { return *_gpu_client; }
|
Platform::Device_client &gpu_client() { return *_gpu_client; }
|
||||||
Platform::Device_capability host_bridge_cap() { return _host_bridge_cap; }
|
Platform::Device_capability host_bridge_cap() { return _host_bridge_cap; }
|
||||||
|
Platform::Device_capability isa_bridge_cap() { return _isa_bridge_cap; }
|
||||||
|
unsigned isa_bridge_class() const { return 0x601u << 8; }
|
||||||
|
|
||||||
addr_t gmadr_base() const { return _gmadr.base(); }
|
addr_t gmadr_base() const { return _gmadr.base(); }
|
||||||
size_t gmadr_size() const { return _gmadr.size(); }
|
size_t gmadr_size() const { return _gmadr.size(); }
|
||||||
addr_t gttmmadr_base() const { return _gttmmadr.base(); }
|
addr_t gttmmadr_base() const { return _gttmmadr.base(); }
|
||||||
addr_t gttmmadr_size() const { return _gttmmadr.size(); }
|
size_t gttmmadr_size() const { return _gttmmadr.size(); }
|
||||||
|
|
||||||
size_t gmadr_platform_size() const { return APERTURE_RESERVED; }
|
size_t gmadr_platform_size() const { return APERTURE_RESERVED; }
|
||||||
size_t gttmmadr_platform_size() const { return GTT_RESERVED; }
|
size_t gttmmadr_platform_size() const { return GTT_RESERVED; }
|
||||||
|
|
||||||
|
|
||||||
Io_mem_dataspace_capability gttmmadr_platform_ds()
|
Io_mem_dataspace_capability gttmmadr_platform_ds()
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
@ -276,5 +313,19 @@ class Igd::Resources : Genode::Noncopyable
|
|||||||
|
|
||||||
return static_cap_cast<Io_mem_dataspace>(_gttmmadr_rm->dataspace());
|
return static_cap_cast<Io_mem_dataspace>(_gttmmadr_rm->dataspace());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gtt_platform_reset()
|
||||||
|
{
|
||||||
|
addr_t const base = map_gttmmadr() + (gttmmadr_size() / 2);
|
||||||
|
Igd::Ggtt(mmio(), base, gttmmadr_platform_size(), 0, scratch_page(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Igd::Mmio &mmio()
|
||||||
|
{
|
||||||
|
if (!_mmio.constructed())
|
||||||
|
_mmio.construct(_delayer, map_gttmmadr());
|
||||||
|
|
||||||
|
return *_mmio;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user