-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathQDMAController.hpp
More file actions
130 lines (96 loc) · 3 KB
/
QDMAController.hpp
File metadata and controls
130 lines (96 loc) · 3 KB
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
#ifndef _QDMACONTROLLER_HPP_
#define _QDMACONTROLLER_HPP_
#include <map>
#include <array>
#include <mutex>
#include <functional>
#include <cstdint>
#include <immintrin.h>
class FPGACtl
{
protected:
FPGACtl(uint8_t pci_bus, size_t bridge_bar_size, uint8_t write_combine = 0);
public:
~FPGACtl();
static void explictInit(uint8_t pci_bus, size_t bridge_bar_size, uint8_t write_combine = 0);
static FPGACtl *getInstance(uint8_t pci_bus);
static void enableDebug();
static void disableDebug();
public:
void writeConfig(uint32_t index, uint32_t value);
uint32_t readConfig(uint32_t index);
void writeReg(uint32_t index, uint32_t value);
uint32_t readReg(uint32_t index);
void writeBridge(uint32_t index, const std::array<uint64_t, 8> &value);
std::array<uint64_t, 8> readBridge(uint32_t index);
void writeBridge(uint32_t index, uint64_t *value);
void readBridge(uint32_t index, uint64_t *value);
void writeBridgeAligned(uint32_t index, uint64_t *value);
void readBridgeAligned(uint32_t index, uint64_t *value);
void *getBridgeAddr();
void *getLiteAddr();
void enableWriteCombine();
void disableWriteCombine();
private:
uint8_t pci_bus, write_combine;
size_t bridge_bar_size;
private:
volatile uint32_t *config_bar{};
volatile uint32_t *lite_bar{};
volatile __m512i *bridge_bar{};
volatile __m512i *wc_bridge_bar{};
};
class MemCtl
{
public:
virtual ~MemCtl() = default;
[[nodiscard]] size_t getPoolSize() const
{
return pool_size;
}
void *alloc(size_t size);
void free(void *ptr);
protected:
MemCtl() = default;
size_t pool_size{};
std::mutex allocMutex;
/*<首地址, 块大小>*/
std::map<uint64_t, uint64_t> free_chunk, used_chunk;
/* n_pages, virt_addr_base, phy_addr_array */
std::tuple<uint32_t, uint64_t, uint64_t *> page_table;
};
class CPUMemCtl : public MemCtl
{
public:
~CPUMemCtl() override;
static CPUMemCtl *getInstance(size_t pool_size);
protected:
explicit CPUMemCtl(uint64_t size);
public:
/*
* void(uint32_t, uint32_t, uint64_t, uint64_t) => (page_index, page_size, virt_addr, phy_addr)
*/
void writeTLB(const std::function<void(uint32_t, uint32_t, uint64_t, uint64_t)> &func);
void legacyWriteTLB(FPGACtl *fpga_ctl);
// For performance reason, mapV2P does not check the ptr's range
uint64_t mapV2P(void *ptr);
};
class GPUMemCtl : public MemCtl
{
public:
~GPUMemCtl() override;
static GPUMemCtl *getInstance(int32_t dev_id, size_t pool_size);
[[maybe_unused]] static void cleanCtx();
protected:
explicit GPUMemCtl(uint64_t size);
public:
/*
* void(uint32_t, uint32_t, uint64_t, uint64_t) => (page_index, page_size, virt_addr, phy_addr)
*/
void writeTLB(const std::function<void(uint32_t, uint32_t, uint64_t, uint64_t)> &func, bool aggr_flag);
uint64_t mapV2P(void *ptr);
void *getDevPtr() const;
void *getMapDevPtr() const;
bool chechPhyContiguous() const;
};
#endif