// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" #include "core/hle/service/nvdrv/devices/nvdevice.h" namespace Service::Nvidia { class EventInterface; } namespace Service::Nvidia::Devices { class nvhost_ctrl_gpu final : public nvdevice { public: explicit nvhost_ctrl_gpu(Core::System& system_, EventInterface& events_interface_); ~nvhost_ctrl_gpu() override; NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span input, std::span output) override; NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span input, std::span inline_input, std::span output) override; NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span input, std::span output, std::span inline_output) override; void OnOpen(DeviceFD fd) override; void OnClose(DeviceFD fd) override; Kernel::KEvent* QueryEvent(u32 event_id) override; private: struct IoctlGpuCharacteristics { u32_le arch; // 0x120 (NVGPU_GPU_ARCH_GM200) u32_le impl; // 0xB (NVGPU_GPU_IMPL_GM20B) u32_le rev; // 0xA1 (Revision A1) u32_le num_gpc; // 0x1 u64_le l2_cache_size; // 0x40000 u64_le on_board_video_memory_size; // 0x0 (not used) u32_le num_tpc_per_gpc; // 0x2 u32_le bus_type; // 0x20 (NVGPU_GPU_BUS_TYPE_AXI) u32_le big_page_size; // 0x20000 u32_le compression_page_size; // 0x20000 u32_le pde_coverage_bit_count; // 0x1B u32_le available_big_page_sizes; // 0x30000 u32_le gpc_mask; // 0x1 u32_le sm_arch_sm_version; // 0x503 (Maxwell Generation 5.0.3?) u32_le sm_arch_spa_version; // 0x503 (Maxwell Generation 5.0.3?) u32_le sm_arch_warp_count; // 0x80 u32_le gpu_va_bit_count; // 0x28 u32_le reserved; // NULL u64_le flags; // 0x55 u32_le twod_class; // 0x902D (FERMI_TWOD_A) u32_le threed_class; // 0xB197 (MAXWELL_B) u32_le compute_class; // 0xB1C0 (MAXWELL_COMPUTE_B) u32_le gpfifo_class; // 0xB06F (MAXWELL_CHANNEL_GPFIFO_A) u32_le inline_to_memory_class; // 0xA140 (KEPLER_INLINE_TO_MEMORY_B) u32_le dma_copy_class; // 0xB0B5 (MAXWELL_DMA_COPY_A) u32_le max_fbps_count; // 0x1 u32_le fbp_en_mask; // 0x0 (disabled) u32_le max_ltc_per_fbp; // 0x2 u32_le max_lts_per_ltc; // 0x1 u32_le max_tex_per_tpc; // 0x0 (not supported) u32_le max_gpc_count; // 0x1 u32_le rop_l2_en_mask_0; // 0x21D70 (fuse_status_opt_rop_l2_fbp_r) u32_le rop_l2_en_mask_1; // 0x0 u64_le chipname; // 0x6230326D67 ("gm20b") u64_le gr_compbit_store_base_hw; // 0x0 (not supported) }; static_assert(sizeof(IoctlGpuCharacteristics) == 160, "IoctlGpuCharacteristics is incorrect size"); struct IoctlCharacteristics { u64_le gpu_characteristics_buf_size; // must not be NULL, but gets overwritten with // 0xA0=max_size u64_le gpu_characteristics_buf_addr; // ignored, but must not be NULL IoctlGpuCharacteristics gc; }; static_assert(sizeof(IoctlCharacteristics) == 16 + sizeof(IoctlGpuCharacteristics), "IoctlCharacteristics is incorrect size"); struct IoctlGpuGetTpcMasksArgs { u32_le mask_buffer_size{}; INSERT_PADDING_WORDS(1); u64_le mask_buffer_address{}; u32_le tcp_mask{}; INSERT_PADDING_WORDS(1); }; static_assert(sizeof(IoctlGpuGetTpcMasksArgs) == 24, "IoctlGpuGetTpcMasksArgs is incorrect size"); struct IoctlActiveSlotMask { u32_le slot; // always 0x07 u32_le mask; }; static_assert(sizeof(IoctlActiveSlotMask) == 8, "IoctlActiveSlotMask is incorrect size"); struct IoctlZcullGetCtxSize { u32_le size; }; static_assert(sizeof(IoctlZcullGetCtxSize) == 4, "IoctlZcullGetCtxSize is incorrect size"); struct IoctlNvgpuGpuZcullGetInfoArgs { u32_le width_align_pixels; u32_le height_align_pixels; u32_le pixel_squares_by_aliquots; u32_le aliquot_total; u32_le region_byte_multiplier; u32_le region_header_size; u32_le subregion_header_size; u32_le subregion_width_align_pixels; u32_le subregion_height_align_pixels; u32_le subregion_count; }; static_assert(sizeof(IoctlNvgpuGpuZcullGetInfoArgs) == 40, "IoctlNvgpuGpuZcullGetInfoArgs is incorrect size"); struct IoctlZbcSetTable { u32_le color_ds[4]; u32_le color_l2[4]; u32_le depth; u32_le format; u32_le type; }; static_assert(sizeof(IoctlZbcSetTable) == 44, "IoctlZbcSetTable is incorrect size"); struct IoctlZbcQueryTable { u32_le color_ds[4]; u32_le color_l2[4]; u32_le depth; u32_le ref_cnt; u32_le format; u32_le type; u32_le index_size; }; static_assert(sizeof(IoctlZbcQueryTable) == 52, "IoctlZbcQueryTable is incorrect size"); struct IoctlFlushL2 { u32_le flush; // l2_flush | l2_invalidate << 1 | fb_flush << 2 u32_le reserved; }; static_assert(sizeof(IoctlFlushL2) == 8, "IoctlFlushL2 is incorrect size"); struct IoctlGetGpuTime { u64_le gpu_time{}; INSERT_PADDING_WORDS(2); }; static_assert(sizeof(IoctlGetGpuTime) == 0x10, "IoctlGetGpuTime is incorrect size"); NvResult GetCharacteristics(std::span input, std::span output); NvResult GetCharacteristics(std::span input, std::span output, std::span inline_output); NvResult GetTPCMasks(std::span input, std::span output); NvResult GetTPCMasks(std::span input, std::span output, std::span inline_output); NvResult GetActiveSlotMask(std::span input, std::span output); NvResult ZCullGetCtxSize(std::span input, std::span output); NvResult ZCullGetInfo(std::span input, std::span output); NvResult ZBCSetTable(std::span input, std::span output); NvResult ZBCQueryTable(std::span input, std::span output); NvResult FlushL2(std::span input, std::span output); NvResult GetGpuTime(std::span input, std::span output); EventInterface& events_interface; // Events Kernel::KEvent* error_notifier_event; Kernel::KEvent* unknown_event; }; } // namespace Service::Nvidia::Devices