summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
blob: 97995551ccd315607e4e7f42bb7f574aba9f73b4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include <vector>

#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<const u8> input,
                    std::span<u8> output) override;
    NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
                    std::span<const u8> inline_input, std::span<u8> output) override;
    NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
                    std::span<u8> 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<const u8> input, std::span<u8> output);
    NvResult GetCharacteristics(std::span<const u8> input, std::span<u8> output,
                                std::span<u8> inline_output);

    NvResult GetTPCMasks(std::span<const u8> input, std::span<u8> output);
    NvResult GetTPCMasks(std::span<const u8> input, std::span<u8> output,
                         std::span<u8> inline_output);

    NvResult GetActiveSlotMask(std::span<const u8> input, std::span<u8> output);
    NvResult ZCullGetCtxSize(std::span<const u8> input, std::span<u8> output);
    NvResult ZCullGetInfo(std::span<const u8> input, std::span<u8> output);
    NvResult ZBCSetTable(std::span<const u8> input, std::span<u8> output);
    NvResult ZBCQueryTable(std::span<const u8> input, std::span<u8> output);
    NvResult FlushL2(std::span<const u8> input, std::span<u8> output);
    NvResult GetGpuTime(std::span<const u8> input, std::span<u8> output);

    EventInterface& events_interface;

    // Events
    Kernel::KEvent* error_notifier_event;
    Kernel::KEvent* unknown_event;
};

} // namespace Service::Nvidia::Devices