From cc2363d421be9c1a3032fe918a38917e5ee4952f Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Thu, 5 Aug 2021 11:06:31 +0200 Subject: [PATCH] gpu/intel: report slice, subslice, eu via gpu info used by libdrm & mesa-21 clients issue #4254 --- repos/os/include/gpu_session/gpu_session.h | 16 +++- repos/os/src/drivers/gpu/intel/main.cc | 92 ++++++++++++++++++++-- repos/os/src/drivers/gpu/intel/mmio.h | 21 +++++ 3 files changed, 120 insertions(+), 9 deletions(-) diff --git a/repos/os/include/gpu_session/gpu_session.h b/repos/os/include/gpu_session/gpu_session.h index bd2fc9490b..0a14889b7b 100644 --- a/repos/os/include/gpu_session/gpu_session.h +++ b/repos/os/include/gpu_session/gpu_session.h @@ -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) { } }; diff --git a/repos/os/src/drivers/gpu/intel/main.cc b/repos/os/src/drivers/gpu/intel/main.cc index 968d4d799c..7c1bfaffbc 100644 --- a/repos/os/src/drivers/gpu/intel/main.cc +++ b/repos/os/src/drivers/gpu/intel/main.cc @@ -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(8); + _revision.value = _resources.config_read(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(); + + 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(); + + 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(); + + 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(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 { 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, diff --git a/repos/os/src/drivers/gpu/intel/mmio.h b/repos/os/src/drivers/gpu/intel/mmio.h index 90f8d3c671..8329da3a24 100644 --- a/repos/os/src/drivers/gpu/intel/mmio.h +++ b/repos/os/src/drivers/gpu/intel/mmio.h @@ -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. */