summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/nvdrv/nvdrv.h
blob: fd59c1dba733bc849d29c25c9728502b50d5de3e (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
// Copyright 2018 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.

#pragma once

#include <memory>
#include <unordered_map>
#include <vector>
#include "common/common_types.h"
#include "core/hle/service/service.h"

namespace Service {
namespace NVDRV {

class nvdevice {
public:
    virtual ~nvdevice() = default;

    virtual u32 ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) = 0;
};

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

    u32 ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) override;
private:
    // 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 next_handle = 1;
    u32 next_id = 1;
    std::unordered_map<u32, std::shared_ptr<Object>> handles;

    enum IoctlCommands {
        IocCreateCommand = 0xC0080101,
        IocFromIdCommand = 0xC0080103,
        IocAllocCommand = 0xC0200104,
        IocParamCommand = 0xC00C0109,
        IocGetIdCommand = 0xC008010E
    };

    struct IocCreateParams {
        // Input
        u32_le size;
        // Output
        u32_le handle;
    };

    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;
    };

    struct IocGetIdParams {
        // Output
        u32_le id;
        // Input
        u32_le handle;
    };

    struct IocFromIdParams {
        // Input
        u32_le id;
        // Output
        u32_le handle;
    };

    struct IocParamParams {
        // Input
        u32_le handle;
        u32_le type;
        // Output
        u32_le value;
    };

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

class nvdisp_disp0 : public nvdevice {
public:
    nvdisp_disp0(std::shared_ptr<nvmap> nvmap_dev) : nvdevice(), nvmap_dev(std::move(nvmap_dev)) {}
    ~nvdisp_disp0() = default;

    u32 ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) override;

    /// Performs a screen flip, drawing the buffer pointed to by the handle.
    void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride);

private:
    std::shared_ptr<nvmap> nvmap_dev;
};

/// Registers all NVDRV services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager);

} // namespace NVDRV
} // namespace Service