summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/nvdrv/devices/nvmap.h
blob: d5360d6e5875c84b9f7d91d9abd0f90b0dc739b4 (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
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include <memory>
#include <unordered_map>
#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::Devices {

class nvmap final : public nvdevice {
public:
    explicit nvmap(Core::System& system_);
    ~nvmap() override;

    NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
                    std::vector<u8>& output) override;
    NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
                    const std::vector<u8>& inline_input, std::vector<u8>& output) override;
    NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
                    std::vector<u8>& output, std::vector<u8>& inline_output) override;

    void OnOpen(DeviceFD fd) override;
    void OnClose(DeviceFD fd) override;

    /// Returns the allocated address of an nvmap object given its handle.
    VAddr GetObjectAddress(u32 handle) const;

    /// Represents an nvmap object.
    struct Object {
        enum class Status { Created, Allocated };
        u32 id;
        u32 size;
        u32 flags;
        u32 align;
        u8 kind;
        VAddr addr;
        Status status;
        u32 refcount;
        u32 dma_map_addr;
    };

    std::shared_ptr<Object> GetObject(u32 handle) const {
        auto itr = handles.find(handle);
        if (itr != handles.end()) {
            return itr->second;
        }
        return {};
    }

private:
    /// Id to use for the next handle that is created.
    u32 next_handle = 0;

    /// Id to use for the next object that is created.
    u32 next_id = 0;

    /// Mapping of currently allocated handles to the objects they represent.
    std::unordered_map<u32, std::shared_ptr<Object>> handles;

    struct IocCreateParams {
        // Input
        u32_le size{};
        // Output
        u32_le handle{};
    };
    static_assert(sizeof(IocCreateParams) == 8, "IocCreateParams has wrong size");

    struct IocFromIdParams {
        // Input
        u32_le id{};
        // Output
        u32_le handle{};
    };
    static_assert(sizeof(IocFromIdParams) == 8, "IocFromIdParams has wrong size");

    struct IocAllocParams {
        // Input
        u32_le handle{};
        u32_le heap_mask{};
        u32_le flags{};
        u32_le align{};
        u8 kind{};
        INSERT_PADDING_BYTES(7);
        u64_le addr{};
    };
    static_assert(sizeof(IocAllocParams) == 32, "IocAllocParams has wrong size");

    struct IocFreeParams {
        u32_le handle{};
        INSERT_PADDING_BYTES(4);
        u64_le address{};
        u32_le size{};
        u32_le flags{};
    };
    static_assert(sizeof(IocFreeParams) == 24, "IocFreeParams has wrong size");

    struct IocParamParams {
        // Input
        u32_le handle{};
        u32_le param{};
        // Output
        u32_le result{};
    };
    static_assert(sizeof(IocParamParams) == 12, "IocParamParams has wrong size");

    struct IocGetIdParams {
        // Output
        u32_le id{};
        // Input
        u32_le handle{};
    };
    static_assert(sizeof(IocGetIdParams) == 8, "IocGetIdParams has wrong size");

    u32 CreateObject(u32 size);

    NvResult IocCreate(const std::vector<u8>& input, std::vector<u8>& output);
    NvResult IocAlloc(const std::vector<u8>& input, std::vector<u8>& output);
    NvResult IocGetId(const std::vector<u8>& input, std::vector<u8>& output);
    NvResult IocFromId(const std::vector<u8>& input, std::vector<u8>& output);
    NvResult IocParam(const std::vector<u8>& input, std::vector<u8>& output);
    NvResult IocFree(const std::vector<u8>& input, std::vector<u8>& output);
};

} // namespace Service::Nvidia::Devices