mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-06 01:11:46 +00:00
gpu/intel: handle CSB correctly
As it turns out reading both dwords as qword results in mirrored values, DDTT. Issue #4148 #4233
This commit is contained in:
parent
5d6ea5ef22
commit
7dc997c8e6
@ -662,6 +662,12 @@ struct Igd::Device
|
|||||||
/* save old tail */
|
/* save old tail */
|
||||||
Ring_buffer::Index const tail = el.ring_tail();
|
Ring_buffer::Index const tail = el.ring_tail();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IHD-OS-BDW-Vol 7-11.15 p. 18 ff.
|
||||||
|
*
|
||||||
|
* Pipeline synchronization
|
||||||
|
*/
|
||||||
|
|
||||||
/* prolog */
|
/* prolog */
|
||||||
if (1)
|
if (1)
|
||||||
{
|
{
|
||||||
@ -768,7 +774,8 @@ struct Igd::Device
|
|||||||
/* w/a */
|
/* w/a */
|
||||||
if (1)
|
if (1)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < 2; i++) {
|
enum { CMD_NUM = 2, };
|
||||||
|
for (size_t i = 0; i < CMD_NUM; i++) {
|
||||||
advance += el.ring_append(0);
|
advance += el.ring_append(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -918,17 +925,14 @@ struct Igd::Device
|
|||||||
(void)ctx_switch;
|
(void)ctx_switch;
|
||||||
bool const user_complete = Mmio::GT_0_INTERRUPT_IIR::Cs_mi_user_interrupt::get(v);
|
bool const user_complete = Mmio::GT_0_INTERRUPT_IIR::Cs_mi_user_interrupt::get(v);
|
||||||
|
|
||||||
|
if (v) { _clear_rcs_iir(v); }
|
||||||
|
|
||||||
Vgpu *notify_gpu = nullptr;
|
Vgpu *notify_gpu = nullptr;
|
||||||
if (user_complete) { notify_gpu = _current_vgpu(); }
|
if (user_complete) { notify_gpu = _current_vgpu(); }
|
||||||
|
|
||||||
if (v) { _clear_rcs_iir(v); }
|
|
||||||
|
|
||||||
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"); }
|
||||||
|
|
||||||
bool const csb = _mmio->csb_unread();
|
|
||||||
(void)csb;
|
|
||||||
|
|
||||||
_mmio->update_context_status_pointer();
|
_mmio->update_context_status_pointer();
|
||||||
|
|
||||||
if (user_complete) {
|
if (user_complete) {
|
||||||
@ -1089,6 +1093,7 @@ struct Igd::Device
|
|||||||
_irq->ack_irq();
|
_irq->ack_irq();
|
||||||
|
|
||||||
_mmio->dump();
|
_mmio->dump();
|
||||||
|
_mmio->context_status_pointer_dump();
|
||||||
|
|
||||||
_timer.sigh(_watchdog_timeout_sigh);
|
_timer.sigh(_watchdog_timeout_sigh);
|
||||||
}
|
}
|
||||||
@ -1535,7 +1540,8 @@ class Gpu::Session_component : public Genode::Session_object<Gpu::Session>
|
|||||||
{
|
{
|
||||||
if (!cap.valid()) { return false; }
|
if (!cap.valid()) { return false; }
|
||||||
|
|
||||||
bool result = false;
|
enum { ALLOC_FAILED, MAP_FAILED, OK } result = ALLOC_FAILED;
|
||||||
|
|
||||||
auto lookup_and_map = [&] (Buffer &buffer) {
|
auto lookup_and_map = [&] (Buffer &buffer) {
|
||||||
if (!(buffer.cap == cap)) { return; }
|
if (!(buffer.cap == cap)) { return; }
|
||||||
|
|
||||||
@ -1552,10 +1558,11 @@ class Gpu::Session_component : public Genode::Session_object<Gpu::Session>
|
|||||||
_vgpu.rcs_map_ppgtt(va, phys_addr, actual_size);
|
_vgpu.rcs_map_ppgtt(va, phys_addr, actual_size);
|
||||||
buffer.ppgtt_va = va;
|
buffer.ppgtt_va = va;
|
||||||
buffer.ppgtt_va_valid = true;
|
buffer.ppgtt_va_valid = true;
|
||||||
result = true;
|
result = OK;
|
||||||
} catch (Igd::Device::Could_not_map_buffer) {
|
} catch (Igd::Device::Could_not_map_buffer) {
|
||||||
/* FIXME do not result in Out_of_ram */
|
/* FIXME do not result in Out_of_ram */
|
||||||
Genode::error("could not map buffer object into PPGTT");
|
Genode::error("could not map buffer object into PPGTT");
|
||||||
|
result = MAP_FAILED;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* will throw below */
|
/* will throw below */
|
||||||
@ -1563,9 +1570,14 @@ class Gpu::Session_component : public Genode::Session_object<Gpu::Session>
|
|||||||
};
|
};
|
||||||
_buffer_registry.for_each(lookup_and_map);
|
_buffer_registry.for_each(lookup_and_map);
|
||||||
|
|
||||||
if (!result) { throw Gpu::Session::Out_of_ram(); }
|
switch (result) {
|
||||||
|
case ALLOC_FAILED:
|
||||||
return result;
|
throw Gpu::Session::Out_of_ram();
|
||||||
|
case OK:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void unmap_buffer_ppgtt(Genode::Dataspace_capability cap,
|
void unmap_buffer_ppgtt(Genode::Dataspace_capability cap,
|
||||||
|
@ -795,21 +795,11 @@ class Igd::Mmio : public Genode::Mmio
|
|||||||
* IHD-OS-BDW-Vol 6-11.15 p. 19 ff.
|
* IHD-OS-BDW-Vol 6-11.15 p. 19 ff.
|
||||||
*/
|
*/
|
||||||
enum {
|
enum {
|
||||||
CTXT_ST_BUF_QW_NUM = 8,
|
|
||||||
CTXT_ST_BUF_NUM = 6,
|
CTXT_ST_BUF_NUM = 6,
|
||||||
|
CTXT_ST_BUF_DWORDS = 12,
|
||||||
};
|
};
|
||||||
template <long int BASE>
|
template <long int BASE>
|
||||||
struct CTXT_ST_BUF_BASE : Register_array<BASE + 0x370, 64, CTXT_ST_BUF_NUM, 64>
|
struct CTXT_ST_BUF_BASE : Register_array<BASE + 0x370, 32, CTXT_ST_BUF_DWORDS, 32> { };
|
||||||
{
|
|
||||||
using B = Register_array<BASE + 0x370, 64, CTXT_ST_BUF_NUM, 64>;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Judging by the documentation it seems that one context status
|
|
||||||
* buffer in fact contains the same DWORD twice.
|
|
||||||
*/
|
|
||||||
struct Context_status_udw : B::template Bitfield<32, 32> { };
|
|
||||||
struct Context_status_ldw : B::template Bitfield< 0, 32> { };
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CTXT_ST_BUF_RCSUNIT : CTXT_ST_BUF_BASE<0x2000> { };
|
struct CTXT_ST_BUF_RCSUNIT : CTXT_ST_BUF_BASE<0x2000> { };
|
||||||
|
|
||||||
@ -1233,15 +1223,6 @@ class Igd::Mmio : public Genode::Mmio
|
|||||||
write<RCS_RING_CONTEXT_STATUS_PTR>(v);
|
write<RCS_RING_CONTEXT_STATUS_PTR>(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool csb_unread()
|
|
||||||
{
|
|
||||||
RCS_RING_CONTEXT_STATUS_PTR::access_t const r = read<RCS_RING_CONTEXT_STATUS_PTR::Read_pointer>();
|
|
||||||
RCS_RING_CONTEXT_STATUS_PTR::access_t const w = read<RCS_RING_CONTEXT_STATUS_PTR::Write_pointer>();
|
|
||||||
|
|
||||||
return (r != w) && (r + 1) % CTXT_ST_BUF_NUM <= w; /* XXX */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t find_free_fence()
|
uint32_t find_free_fence()
|
||||||
{
|
{
|
||||||
uint32_t id = 0xff;
|
uint32_t id = 0xff;
|
||||||
|
@ -305,16 +305,20 @@ void Igd::Mmio::context_status_pointer_dump()
|
|||||||
|
|
||||||
uint32_t r = rp;
|
uint32_t r = rp;
|
||||||
uint32_t w = wp;
|
uint32_t w = wp;
|
||||||
if (r > w) { w += CTXT_ST_BUF_NUM; }
|
|
||||||
while (r < w) {
|
|
||||||
uint32_t const i = ++r % CTXT_ST_BUF_NUM;
|
|
||||||
|
|
||||||
uint64_t const cs = read<CTXT_ST_BUF_RCSUNIT>(i);
|
while (r != w) {
|
||||||
uint32_t const csu = read<CTXT_ST_BUF_RCSUNIT::Context_status_udw>(i);
|
|
||||||
uint32_t const csl = read<CTXT_ST_BUF_RCSUNIT::Context_status_ldw>(i);
|
if (++r == CTXT_ST_BUF_NUM) { r = 0; }
|
||||||
|
|
||||||
|
uint32_t const i = r;
|
||||||
|
|
||||||
|
uint32_t const csu = read<CTXT_ST_BUF_RCSUNIT>(i*2+1);
|
||||||
|
uint32_t const csl = read<CTXT_ST_BUF_RCSUNIT>(i*2);
|
||||||
|
uint64_t const cs = ((uint64_t)csu << 32) | csl;
|
||||||
|
|
||||||
log(i, " Context_status: ", Hex(cs));
|
log(i, " Context_status: ", Hex(cs));
|
||||||
|
|
||||||
Igd::Context_status_qword::access_t const v = csl;
|
Igd::Context_status_qword::access_t const v = cs;
|
||||||
log(i, " Context_complete: ", Igd::Context_status_qword::Context_complete::get(v));
|
log(i, " Context_complete: ", Igd::Context_status_qword::Context_complete::get(v));
|
||||||
log(i, " Active_to_idle: ", Igd::Context_status_qword::Active_to_idle::get(v));
|
log(i, " Active_to_idle: ", Igd::Context_status_qword::Active_to_idle::get(v));
|
||||||
log(i, " Element_switch: ", Igd::Context_status_qword::Element_switch::get(v));
|
log(i, " Element_switch: ", Igd::Context_status_qword::Element_switch::get(v));
|
||||||
|
@ -35,7 +35,7 @@ namespace Utils {
|
|||||||
|
|
||||||
template <unsigned int ELEMENTS> class Address_map;
|
template <unsigned int ELEMENTS> class Address_map;
|
||||||
|
|
||||||
void clflush(volatile void *addr)
|
inline void clflush(volatile void *addr)
|
||||||
{
|
{
|
||||||
asm volatile("clflush %0" : "+m" (*(volatile char *)addr));
|
asm volatile("clflush %0" : "+m" (*(volatile char *)addr));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user