gpu/intel: report slice, subslice, eu via gpu info

used by libdrm & mesa-21 clients

issue #4254
This commit is contained in:
Alexander Boettcher 2021-08-05 11:06:31 +02:00 committed by Christian Helmuth
parent b287c4888a
commit cc2363d421
3 changed files with 120 additions and 9 deletions

View File

@ -46,13 +46,25 @@ struct Gpu::Info
Genode::uint64_t id;
} last_completed;
struct Revision { Genode::uint8_t value; } revision;
struct Slice_mask { unsigned value; } slice_mask;
struct Subslice_mask { unsigned value; } subslice_mask;
struct Eu_total { unsigned value; } eus;
struct Subslices { unsigned value; } subslices;
Info(Chip_id chip_id, Features features, size_t aperture_size,
Context_id ctx_id, Execution_buffer_sequence last)
Context_id ctx_id, Execution_buffer_sequence last,
Revision rev, Slice_mask s_mask, Subslice_mask ss_mask,
Eu_total eu, Subslices subslice)
:
chip_id(chip_id), features(features),
aperture_size(aperture_size), ctx_id(ctx_id),
last_completed(last)
last_completed(last),
revision(rev),
slice_mask(s_mask),
subslice_mask(ss_mask),
eus(eu),
subslices(subslice)
{ }
};

View File

@ -127,8 +127,12 @@ struct Igd::Device
} _pci_backend_alloc { _resources.platform() };
Device_info _info { };
uint8_t _revision { };
Device_info _info { };
Gpu::Info::Revision _revision { };
Gpu::Info::Slice_mask _slice_mask { };
Gpu::Info::Subslice_mask _subslice_mask { };
Gpu::Info::Eu_total _eus { };
Gpu::Info::Subslices _subslices { };
void _pci_info(char const *descr)
{
@ -141,7 +145,7 @@ struct Igd::Device
_device.bus_address(&bus, &dev, &fun);
log("Found: '", descr, "' gen=", _info.generation,
" rev=", _revision, " ",
" rev=", _revision.value, " ",
"[", Hex(vendor_id), ":", Hex(device_id), "] (",
Hex(bus, Hex::OMIT_PREFIX), ":",
Hex(dev, Hex::OMIT_PREFIX), ".",
@ -170,7 +174,7 @@ struct Igd::Device
for (size_t i = 0; i < ELEM_NUMBER(_supported_devices); i++) {
if (_supported_devices[i].id == id) {
_info = _supported_devices[i];
_revision = _resources.config_read<uint8_t>(8);
_revision.value = _resources.config_read<uint8_t>(8);
_pci_info(_supported_devices[i].descr);
return true;
}
@ -960,7 +964,76 @@ struct Igd::Device
_mmio.dump();
_mmio.context_status_pointer_dump();
_resources.timer().sigh(_watchdog_timeout_sigh);
_mmio->dump();
_mmio->context_status_pointer_dump();
/* read out slice, subslice, EUs information depending on platform */
if (_info.platform == Device_info::Platform::BROADWELL) {
enum { SUBSLICE_MAX = 3 };
_subslice_mask.value = (1u << SUBSLICE_MAX) - 1;
_subslice_mask.value &= ~_mmio->read<Igd::Mmio::FUSE2::Gt_subslice_disable_fuse_gen8>();
for (unsigned i=0; i < SUBSLICE_MAX; i++)
if (_subslice_mask.value & (1u << i))
_subslices.value ++;
_init_eu_total(3, SUBSLICE_MAX, 8);
} else
if (_info.generation == 9) {
enum { SUBSLICE_MAX = 4 };
_subslice_mask.value = (1u << SUBSLICE_MAX) - 1;
_subslice_mask.value &= ~_mmio->read<Igd::Mmio::FUSE2::Gt_subslice_disable_fuse_gen9>();
for (unsigned i=0; i < SUBSLICE_MAX; i++)
if (_subslice_mask.value & (1u << i))
_subslices.value ++;
_init_eu_total(3, SUBSLICE_MAX, 8);
} else
Genode::error("unsupported platform ", (int)_info.platform);
_timer.sigh(_watchdog_timeout_sigh);
}
void _init_eu_total(uint8_t const max_slices,
uint8_t const max_subslices,
uint8_t const max_eus_per_subslice)
{
if (max_eus_per_subslice != 8) {
Genode::error("wrong eu_total calculation");
}
_slice_mask.value = _mmio->read<Igd::Mmio::FUSE2::Gt_slice_enable_fuse>();
unsigned eu_total = 0;
/* determine total amount of available EUs */
for (unsigned disable_byte = 0; disable_byte < 12; disable_byte++) {
unsigned const fuse_bits = disable_byte * 8;
unsigned const slice = fuse_bits / (max_subslices * max_eus_per_subslice);
unsigned const subslice = fuse_bits / max_eus_per_subslice;
if (fuse_bits >= max_slices * max_subslices * max_eus_per_subslice)
break;
if (!(_subslice_mask.value & (1u << subslice)))
continue;
if (!(_slice_mask.value & (1u << slice)))
continue;
auto const disabled = _mmio->read<Igd::Mmio::EU_DISABLE>(disable_byte);
for (unsigned b = 0; b < 8; b++) {
if (disabled & (1u << b))
continue;
eu_total ++;
}
}
_eus = Gpu::Info::Eu_total { eu_total };
}
/*********************
@ -1003,7 +1076,7 @@ struct Igd::Device
Device_info::Stepping stepping = Device_info::Stepping::A0;
switch (_revision) {
switch (_revision.value) {
case 0: stepping = Device_info::Stepping::A0; break;
case 1: stepping = Device_info::Stepping::B0; break;
case 2: stepping = Device_info::Stepping::C0; break;
@ -1346,7 +1419,12 @@ class Gpu::Session_component : public Genode::Session_object<Gpu::Session>
{
Genode::size_t const aperture_size = Igd::Device::Vgpu::APERTURE_SIZE;
return Info(_device.id(), _device.features(), aperture_size,
_vgpu.id(), { .id = _vgpu.completed_seqno() });
_vgpu.id(), { .id = _vgpu.completed_seqno() },
_device._revision,
_device._slice_mask,
_device._subslice_mask,
_device._eus,
_device._subslices);
}
Gpu::Info::Execution_buffer_sequence exec_buffer(Genode::Dataspace_capability cap,

View File

@ -751,6 +751,27 @@ class Igd::Mmio : public Genode::Mmio
struct Graphics_full_soft_reset_ctl : Bitfield<0, 1> { };
};
/*
* IHD-OS-BDW-Vol 2c-11.15 p. 1062 ff.
* IHD-OS-SKL-Vol 2c-05.16 part 2 p. 516 ff.
* IHD-OS-KBL-Vol 2c-1.17 part 2 p. 402 ff.
*/
struct FUSE2 : Register<0x09120, 32>
{
struct Gt_subslice_disable_fuse_gen8: Bitfield<21, 3> { };
struct Gt_subslice_disable_fuse_gen9: Bitfield<20, 4> { };
struct Gt_slice_enable_fuse: Bitfield<25, 3> { };
};
/*
* IHD-OS-BDW-Vol 2c-11.15 p. 1057 ff.
* IHD-OS-SKL-Vol 2c-05.16 part 2 p. 398 ff.
* IHD-OS-KBL-Vol 2c-1.17 part2 p. 397 ff.
*
* 0x9134, 0x9138, 0x913c
*/
struct EU_DISABLE : Register_array<0x9134, 32, 12, 8> { };
/*
* IHD-OS-BDW-Vol 2c-11.15 p. 611 ff.
*/