Move nvhost-ctrl-gpu to new device API

This commit is contained in:
Billy Laws 2021-07-17 17:48:37 +01:00
parent 6c6abd9a51
commit abaca6d40e
4 changed files with 180 additions and 191 deletions

View File

@ -0,0 +1,68 @@
// SPDX-License-Identifier: MIT OR MPL-2.0
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include <services/nvdrv/devices/deserialisation/deserialisation.h>
#include "ctrl_gpu.h"
namespace skyline::service::nvdrv::device::nvhost {
CtrlGpu::CtrlGpu(const DeviceState &state, Core &core, const SessionContext &ctx) :
NvDevice(state, core, ctx),
errorNotifierEvent(std::make_shared<type::KEvent>(state, false)),
unknownEvent(std::make_shared<type::KEvent>(state, false)) {}
PosixResult CtrlGpu::ZCullGetCtxSize(Out<u32> size) {
size = 0x1;
return PosixResult::Success;
}
PosixResult CtrlGpu::ZCullGetInfo(Out<ZCullInfo> info) {
info = {};
return PosixResult::Success;
}
PosixResult CtrlGpu::GetCharacteristics(InOut<u64> size, In<u64> userAddress, Out<GpuCharacteristics> characteristics) {
characteristics = {};
size = sizeof(GpuCharacteristics);
return PosixResult::Success;
}
PosixResult CtrlGpu::GetTpcMasks(In<u32> bufSize, Out<u64> maskBuf) {
// TODO
maskBuf = 0x3;
return PosixResult::Success;
}
PosixResult CtrlGpu::GetActiveSlotMask(Out<u32> slot, Out<u32> mask) {
slot = 0x7;
mask = 0x1;
return PosixResult::Success;
}
std::shared_ptr<type::KEvent> CtrlGpu::QueryEvent(u32 eventId) {
switch (eventId) {
case 1:
return errorNotifierEvent;
case 2:
return unknownEvent;
default:
return nullptr;
}
}
#include <services/nvdrv/devices/deserialisation/macro_def.h>
static constexpr u32 CtrlGpuMagic{0x47};
IOCTL_HANDLER_FUNC(CtrlGpu, ({
IOCTL_CASE_ARGS(OUT, SIZE(0x4), MAGIC(CtrlGpuMagic), FUNC(0x1),
ZCullGetCtxSize, ARGS(Out<u32>))
IOCTL_CASE_ARGS(INOUT, SIZE(0x28), MAGIC(CtrlGpuMagic), FUNC(0x2),
ZCullGetInfo, ARGS(Out<ZCullInfo>))
IOCTL_CASE_ARGS(INOUT, SIZE(0xB0), MAGIC(CtrlGpuMagic), FUNC(0x5),
GetCharacteristics, ARGS(InOut<u64>, In<u64>, Out<GpuCharacteristics>))
IOCTL_CASE_ARGS(INOUT, SIZE(0x18), MAGIC(CtrlGpuMagic), FUNC(0x6),
GetTpcMasks, ARGS(In<u32>, Pad<u32, 3>, Out<u64>))
IOCTL_CASE_ARGS(OUT, SIZE(0x8), MAGIC(CtrlGpuMagic), FUNC(0x14),
GetActiveSlotMask, ARGS(Out<u32>, Out<u32>))
}))
#include <services/nvdrv/devices/deserialisation/macro_undef.h>
}

View File

@ -0,0 +1,112 @@
// SPDX-License-Identifier: MIT OR MPL-2.0
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
#pragma once
#include "services/nvdrv/devices/nvdevice.h"
namespace skyline::service::nvdrv::device::nvhost {
/**
* @brief nvhost::CtrlGpu (/dev/nvhost-ctrl-gpu) is used for context independent operations on the underlying GPU
* @url https://switchbrew.org/wiki/NV_services#.2Fdev.2Fnvhost-ctrl-gpu
*/
class CtrlGpu : public NvDevice {
private:
std::shared_ptr<type::KEvent> errorNotifierEvent;
std::shared_ptr<type::KEvent> unknownEvent;
public:
/**
* @brief Holds hardware characteristics about a GPU, initialised to the GM20B values
*/
struct GpuCharacteristics {
u32 arch{0x120}; // NVGPU_GPU_ARCH_GM200
u32 impl{0xB}; // 0xB (NVGPU_GPU_IMPL_GM20B) or 0xE (NVGPU_GPU_IMPL_GM20B_B)
u32 rev{0xA1};
u32 numGpc{0x1};
u64 l2CacheSize{0x40000};
u64 onBoardVideoMemorySize{}; // UMA
u32 numTpcPerGpc{0x2};
u32 busType{0x20}; // NVGPU_GPU_BUS_TYPE_AXI
u32 bigPageSize{0x20000};
u32 compressionPageSize{0x20000};
u32 pdeCoverageBitCount{0x1B};
u32 availableBigPageSizes{0x30000};
u32 gpcMask{0x1};
u32 smArchSmVersion{0x503}; // Maxwell Generation 5.0.3
u32 smArchSpaVersion{0x503}; // Maxwell Generation 5.0.3
u32 smArchWarpCount{0x80};
u32 gpuVaBitCount{0x28};
u32 _res_{};
u64 flags{0x55}; // HAS_SYNCPOINTS | SUPPORT_SPARSE_ALLOCS | SUPPORT_CYCLE_STATS | SUPPORT_CYCLE_STATS_SNAPSHOT
u32 twodClass{0x902D}; // FERMI_TWOD_A
u32 threedClass{0xB197}; // MAXWELL_B
u32 computeClass{0xB1C0}; // MAXWELL_COMPUTE_B
u32 gpfifoClass{0xB06F}; // MAXWELL_CHANNEL_GPFIFO_A
u32 inlineToMemoryClass{0xA140}; // KEPLER_INLINE_TO_MEMORY_B
u32 dmaCopyClass{0xA140}; // MAXWELL_DMA_COPY_A
u32 maxFbpsCount{0x1}; // 0x1
u32 fbpEnMask{}; // Disabled
u32 maxLtcPerFbp{0x2};
u32 maxLtsPerLtc{0x1};
u32 maxTexPerTpc{}; // Not Supported
u32 maxGpcCount{0x1};
u32 ropL2EnMask0{0x21D70}; // fuse_status_opt_rop_l2_fbp_r
u32 ropL2EnMask1{};
u64 chipName{util::MakeMagic<u64>("gm20b")};
u64 grCompbitStoreBaseHw{}; // Not Supported
};
/**
* @brief Contains the Maxwell ZCULL capabilities and configuration
*/
struct ZCullInfo {
u32 widthAlignPixels{0x20};
u32 heightAlignPixels{0x20};
u32 pixelSquaresByAliquots{0x400};
u32 aliquotTotal{0x800};
u32 regionByteMultiplier{0x20};
u32 regionHeaderSize{0x20};
u32 subregionHeaderSize{0xC0};
u32 subregionWidthAlignPixels{0x20};
u32 subregionHeightAlignPixels{0x40};
u32 subregionCount{0x10};
};
CtrlGpu(const DeviceState &state, Core &core, const SessionContext &ctx);
/**
* @brief Returns the zcull context size
* @url https://switchbrew.org/wiki/NV_services#NVGPU_GPU_IOCTL_ZCULL_GET_CTX_SIZE
*/
PosixResult ZCullGetCtxSize(Out<u32> size);
/**
* @brief Returns information about the GPU ZCULL parameters
* @url https://switchbrew.org/wiki/NV_services#NVGPU_GPU_IOCTL_ZCULL_GET_INFO
*/
PosixResult ZCullGetInfo(Out<ZCullInfo> info);
/**
* @brief Returns a struct with certain GPU characteristics
* @url https://switchbrew.org/wiki/NV_services#NVGPU_GPU_IOCTL_GET_CHARACTERISTICS
*/
PosixResult GetCharacteristics(InOut<u64> size, In<u64> userAddress, Out<GpuCharacteristics> characteristics);
/**
* @brief Returns the TPC mask value for each GPC
* @url https://switchbrew.org/wiki/NV_services#NVGPU_GPU_IOCTL_GET_TPC_MASKS
*/
PosixResult GetTpcMasks(In<u32> bufSize, Out<u64> maskBuf);
/**
* @brief Returns the mask value for a ZBC slot
* @url https://switchbrew.org/wiki/NV_services#NVGPU_GPU_IOCTL_ZBC_GET_ACTIVE_SLOT_MASK
*/
PosixResult GetActiveSlotMask(Out<u32> slot, Out<u32> mask);
std::shared_ptr<type::KEvent> QueryEvent(u32 eventId) override;
PosixResult Ioctl(IoctlDescriptor cmd, span<u8> buffer) override;
};
}

View File

@ -1,130 +0,0 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include "nvhost_ctrl_gpu.h"
namespace skyline::service::nvdrv::device {
NvHostCtrlGpu::NvHostCtrlGpu(const DeviceState &state) : errorNotifierEvent(std::make_shared<type::KEvent>(state, false)), unknownEvent(std::make_shared<type::KEvent>(state, false)), NvDevice(state) {}
NvStatus NvHostCtrlGpu::ZCullGetCtxSize(IoctlType type, span<u8> buffer, span<u8> inlineBuffer) {
buffer.as<u32>() = 0x1;
return NvStatus::Success;
}
NvStatus NvHostCtrlGpu::ZCullGetInfo(IoctlType type, span<u8> buffer, span<u8> inlineBuffer) {
struct ZCullInfo {
u32 widthAlignPixels{0x20};
u32 heightAlignPixels{0x20};
u32 pixelSquaresByAliquots{0x400};
u32 aliquotTotal{0x800};
u32 regionByteMultiplier{0x20};
u32 regionHeaderSize{0x20};
u32 subregionHeaderSize{0xC0};
u32 subregionWidthAlignPixels{0x20};
u32 subregionHeightAlignPixels{0x40};
u32 subregionCount{0x10};
} zCullInfo;
buffer.as<ZCullInfo>() = zCullInfo;
return NvStatus::Success;
}
NvStatus NvHostCtrlGpu::GetCharacteristics(IoctlType type, span<u8> buffer, span<u8> inlineBuffer) {
struct GpuCharacteristics {
u32 arch{0x120}; // NVGPU_GPU_ARCH_GM200
u32 impl{0xB}; // 0xB (NVGPU_GPU_IMPL_GM20B) or 0xE (NVGPU_GPU_IMPL_GM20B_B)
u32 rev{0xA1};
u32 numGpc{0x1};
u64 l2CacheSize{0x40000};
u64 onBoardVideoMemorySize{}; // UMA
u32 numTpcPerGpc{0x2};
u32 busType{0x20}; // NVGPU_GPU_BUS_TYPE_AXI
u32 bigPageSize{0x20000};
u32 compressionPageSize{0x20000};
u32 pdeCoverageBitCount{0x1B};
u32 availableBigPageSizes{0x30000};
u32 gpcMask{0x1};
u32 smArchSmVersion{0x503}; // Maxwell Generation 5.0.3
u32 smArchSpaVersion{0x503}; // Maxwell Generation 5.0.3
u32 smArchWarpCount{0x80};
u32 gpuVaBitCount{0x28};
u32 _res_{};
u64 flags{0x55}; // HAS_SYNCPOINTS | SUPPORT_SPARSE_ALLOCS | SUPPORT_CYCLE_STATS | SUPPORT_CYCLE_STATS_SNAPSHOT
u32 twodClass{0x902D}; // FERMI_TWOD_A
u32 threedClass{0xB197}; // MAXWELL_B
u32 computeClass{0xB1C0}; // MAXWELL_COMPUTE_B
u32 gpfifoClass{0xB06F}; // MAXWELL_CHANNEL_GPFIFO_A
u32 inlineToMemoryClass{0xA140}; // KEPLER_INLINE_TO_MEMORY_B
u32 dmaCopyClass{0xA140}; // MAXWELL_DMA_COPY_A
u32 maxFbpsCount{0x1}; // 0x1
u32 fbpEnMask{}; // Disabled
u32 maxLtcPerFbp{0x2};
u32 maxLtsPerLtc{0x1};
u32 maxTexPerTpc{}; // Not Supported
u32 maxGpcCount{0x1};
u32 ropL2EnMask0{0x21D70}; // fuse_status_opt_rop_l2_fbp_r
u32 ropL2EnMask1{};
u64 chipName{util::MakeMagic<u64>("gm20b")};
u64 grCompbitStoreBaseHw{}; // Not Supported
};
struct Data {
u64 gpuCharacteristicsBufSize; // InOut
u64 gpuCharacteristicsBufAddr; // In
GpuCharacteristics gpuCharacteristics; // Out
} &data = buffer.as<Data>();
if (data.gpuCharacteristicsBufSize < sizeof(GpuCharacteristics))
return NvStatus::InvalidSize;
// The IOCTL3 version of GetCharacteristics additionally outputs to the inline output buffer
if (type == IoctlType::Ioctl3) {
auto &inlineCharacteristics{inlineBuffer.as<GpuCharacteristics>()};
data.gpuCharacteristics = inlineCharacteristics = GpuCharacteristics{};
} else {
data.gpuCharacteristics = GpuCharacteristics{};
}
data.gpuCharacteristicsBufSize = sizeof(GpuCharacteristics);
return NvStatus::Success;
}
NvStatus NvHostCtrlGpu::GetTpcMasks(IoctlType type, span<u8> buffer, span<u8> inlineBuffer) {
struct Data {
u32 maskBufSize; // In
u32 _res_[3]; // In
u64 maskBuf; // Out
} &data = buffer.as<Data>();
if (data.maskBufSize) {
if (type == IoctlType::Ioctl3) {
auto &inlineMask{inlineBuffer.as<u32>()};
data.maskBuf = inlineMask = 0x3;
} else {
data.maskBuf = 0x3;
}
}
return NvStatus::Success;
}
NvStatus NvHostCtrlGpu::GetActiveSlotMask(IoctlType type, span<u8> buffer, span<u8> inlineBuffer) {
struct Data {
u32 slot{0x07}; // Out
u32 mask{0x01}; // Out
} data;
buffer.as<Data>() = data;
return NvStatus::Success;
}
std::shared_ptr<type::KEvent> NvHostCtrlGpu::QueryEvent(u32 eventId) {
switch (eventId) {
case 1:
return errorNotifierEvent;
case 2:
return unknownEvent;
default:
return nullptr;
}
}
}

View File

@ -1,61 +0,0 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#pragma once
#include "nvdevice.h"
namespace skyline::service::nvdrv::device {
/**
* @brief NvHostCtrlGpu (/dev/nvhost-ctrl-gpu) is used for context independent operations on the underlying GPU
* @url https://switchbrew.org/wiki/NV_services#.2Fdev.2Fnvhost-ctrl-gpu
*/
class NvHostCtrlGpu : public NvDevice {
private:
std::shared_ptr<type::KEvent> errorNotifierEvent;
std::shared_ptr<type::KEvent> unknownEvent;
public:
NvHostCtrlGpu(const DeviceState &state);
/**
* @brief Returns a u32 GPU ZCULL Context Size
* @url https://switchbrew.org/wiki/NV_services#NVGPU_GPU_IOCTL_ZCULL_GET_CTX_SIZE
*/
NvStatus ZCullGetCtxSize(IoctlType type, span<u8> buffer, span<u8> inlineBuffer);
/**
* @brief Returns a the GPU ZCULL Information
* @url https://switchbrew.org/wiki/NV_services#NVGPU_GPU_IOCTL_ZCULL_GET_INFO
*/
NvStatus ZCullGetInfo(IoctlType type, span<u8> buffer, span<u8> inlineBuffer);
/**
* @brief Returns a struct with certain GPU characteristics
* @url https://switchbrew.org/wiki/NV_services#NVGPU_GPU_IOCTL_GET_CHARACTERISTICS
*/
NvStatus GetCharacteristics(IoctlType type, span<u8> buffer, span<u8> inlineBuffer);
/**
* @brief Returns the TPC mask value for each GPC
* @url https://switchbrew.org/wiki/NV_services#NVGPU_GPU_IOCTL_GET_TPC_MASKS
*/
NvStatus GetTpcMasks(IoctlType type, span<u8> buffer, span<u8> inlineBuffer);
/**
* @brief Returns the mask value for a ZBC slot
* @url https://switchbrew.org/wiki/NV_services#NVGPU_GPU_IOCTL_ZBC_GET_ACTIVE_SLOT_MASK
*/
NvStatus GetActiveSlotMask(IoctlType type, span<u8> buffer, span<u8> inlineBuffer);
std::shared_ptr<type::KEvent> QueryEvent(u32 eventId) override;
NVDEVICE_DECL(
NVFUNC(0x4701, NvHostCtrlGpu, ZCullGetCtxSize),
NVFUNC(0x4702, NvHostCtrlGpu, ZCullGetInfo),
NVFUNC(0x4706, NvHostCtrlGpu, GetTpcMasks),
NVFUNC(0x4705, NvHostCtrlGpu, GetCharacteristics),
NVFUNC(0x4714, NvHostCtrlGpu, GetActiveSlotMask)
)
};
}