-
Notifications
You must be signed in to change notification settings - Fork 8
/
fpga_pci.h
264 lines (236 loc) · 8.85 KB
/
fpga_pci.h
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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
/*
* Copyright 2015-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may
* not use this file except in compliance with the License. A copy of the
* License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
#pragma once
#include <stdint.h>
#include <pthread.h>
#include "hal/fpga_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* FPGA_PCI_BARS_MAX:
* -compile time tunable via mkall_fpga_mgmt_tools.sh, with the below default.
* -set this to the max number of FPGA BARs that the application plans
* to attach at any one time.
* -the upper limit is FPGA_SLOT_MAX * FPGA_BARS_MAX.
* -FPGA_SLOT_MAX is driven by the EC2 FPGA system design and instance type.
* -FPGA_BARS_MAX is driven by the FPGA Shell release.
*/
#if ! defined(FPGA_PCI_BARS_MAX)
#define FPGA_PCI_BARS_MAX (FPGA_SLOT_MAX * FPGA_PF_MAX * FPGA_BAR_PER_PF_MAX)
#endif
/*
* Notes on platform vs application locking:
*
* Platform Locking:
* -attach/detach are protected via a pthread mutex to allow for use cases
* of multi-threaded attach/detach sequences vs calling attach/detach during
* one time process init/destroy.
*
* Application Locking:
* -a single process may access all of the FPGAs via the dev_index(es) without
* locking.
* -a single thread may access a single FPGA via the dev_index without locking.
* -multi-threaded access to the same FPGA must be done with locking within
* the application.
*/
/**
* Type definition for a descriptor/handle used to specify a BAR. Initialize
* with PCI_BAR_HANDLE_INIT.
*/
typedef int pci_bar_handle_t;
#define PCI_BAR_HANDLE_INIT (-1)
/**
* Initialize the pci library.
* @returns 0 on success, non-zero on error
*/
int fpga_pci_init(void);
/**
* Attach to an FPGA memory space.
*
* @param[in] slot_id logical slot index
* @param[in] pf_id physical function id, e.g. FPGA_APP_PF
* @param[in] bar_id base address register, e.g. APP_PF_BAR4
* @param[in] flags set various options (flags defined below)
* @param[out] handle used to identify fpga attachment for future library
* calls
*
* @returns 0 on success, non-zero on error
*/
int fpga_pci_attach(int slot_id, int pf_id, int bar_id, uint32_t flags,
pci_bar_handle_t *handle);
/**
* Flags used to specify options for fpga_pci_attach.
*/
enum {
BURST_CAPABLE = 0x1,
FPGA_ATTACH_RESERVED = 0xfffffffe,
};
/**
* Detach from an FPGA memory space.
*
* @param[in] handle the value provided by fpga_pci_attach corresponding to
* the memory space to detach
* @returns 0 on success, non-zero on error
*/
int fpga_pci_detach(pci_bar_handle_t handle);
/**
* Write a value to a register.
*
* @param[in] handle handle provided by fpga_pci_attach
* @param[in] offset memory location offset for register to write
* @param[in] value value to write to the register
* @returns 0 on success, non-zero on error
*/
int fpga_pci_poke(pci_bar_handle_t handle, uint64_t offset, uint32_t value);
/**
* Write a one byte value to a register.
*
* @param[in] handle handle provided by fpga_pci_attach
* @param[in] offset memory location offset for register to write
* @param[in] value 8-bit value to write to the register
* @returns 0 on success, non-zero on error
*/
int fpga_pci_poke8(pci_bar_handle_t handle, uint64_t offset, uint8_t value);
/**
* Write a value to a register.
*
* @param[in] handle handle provided by fpga_pci_attach
* @param[in] offset memory location offset for register to write
* @param[in] value 64-bit value to write to the register
* @returns 0 on success, non-zero on error
*/
int fpga_pci_poke64(pci_bar_handle_t handle, uint64_t offset, uint64_t value);
/**
* Write a burst to a burst capable memory bar.
*
* @param[in] handle handle provided by fpga_pci_attach
* @param[in] offset memory location offset for to write
* @param[in] datap pointer to the data to be written
* @param[in] dword_len the length of data to write in burst, in 4-byte DWORDs
*
* @returns 0 on success, non-zero on error
*/
int fpga_pci_write_burst(pci_bar_handle_t handle, uint64_t offset,
uint32_t* datap, uint64_t dword_len);
/**
* Read a value from a register.
*
* @param[in] handle handle provided by fpga_pci_attach
* @param[in] offset memory location offset for register to read
* @param[out] value value read from the register (32-bit)
* @returns 0 on success, non-zero on error
*/
int fpga_pci_peek(pci_bar_handle_t handle, uint64_t offset, uint32_t *value);
/**
* Read a one byte value from a register.
*
* @param[in] handle handle provided by fpga_pci_attach
* @param[in] offset memory location offset for register to read
* @param[out] value 8-bit value read from the register
* @returns 0 on success, non-zero on error
*/
int fpga_pci_peek8(pci_bar_handle_t handle, uint64_t offset, uint8_t *value);
/**
* Read a value from a register.
*
* @param[in] handle handle provided by fpga_pci_attach
* @param[in] offset memory location offset for register to read
* @param[out] value 64-bit value read from the register
* @returns 0 on success, non-zero on error
*/
int fpga_pci_peek64(pci_bar_handle_t handle, uint64_t offset, uint64_t *value);
/**
* Use a logical slot id to populate a slot spec
*
* @param[in] slot_id The logical slot id of the FPGA of interest
* @param[in] pf_id physical function id (e.g. FPGA_APP_PF)
* @param[in] bar_id base address register id (e.g. APP_PF_BAR0)
* @param[out] spec Pointer to fpga_slot spec to populate
* @returns 0 on success, non-zero on error
*/
int fpga_pci_get_slot_spec(int slot_id, struct fpga_slot_spec *spec);
/**
* Populate slot specs for all FPGAs on the system. It is recommended to use
* FPGA_SLOT_MAX as the size of the spec_array;
*
* @param[out] spec_array array to populate
* @param[in] size allocated size of the provided array
*/
int fpga_pci_get_all_slot_specs(struct fpga_slot_spec spec_array[], int size);
/**
* Get resource map information for a single slot and physical function. This
* information is provided in the slot_spec, but occasionally only the resource
* map is needed.
*
* @param[in] slot_id The logical slot id of the FPGA of interest
* @param[in] pf_id physical function id (e.g. FPGA_APP_PF)
* @param[out] map resource map to populate
* @returns 0 on success, non-zero on error
*/
int fpga_pci_get_resource_map(int slot_id, int pf_id,
struct fpga_pci_resource_map *map);
/**
* Rescan the slot application physical functions.
* -performs both a pci device remove and a PCI rescan to refresh the device
* vendor and device IDs within the OS.
*
* @param[in] slot_id The logical slot id of the FPGA of interest
*
* @returns 0 on success, non-zero on error
*/
int fpga_pci_rescan_slot_app_pfs(int slot_id);
/**
* Get a bounds checked pointer to memory in the mapped region for this handle.
*
* @param[in] handle handle provided by fpga_pci_attach
* @param[in] offset offset into the mmap'ed region
* @param[in] dword_len the length of data to write in burst, in 4-byte DWORDs
* (used for bounds checking)
* @param[out] ptr pointer to memory
*
* @return 0 on success, non-zero on error (bounds errors in particular)
*/
int fpga_pci_get_address(pci_bar_handle_t handle, uint64_t offset,
uint64_t dword_len, void **ptr);
/**
* Initialze a segment of memory to an initial value. This has the best
* performance when the BAR is attached with write combining enabled.
*
* @param[in] handle handle provided by fpga_pci_attach
* @param[in] offset memory location offset to write
* @param[in] value value to write into memory
* @param[in] dword_len the length of data to write in burst, in 4-byte DWORDs
*
* @returns 0 on success, non-zero on error
*/
int fpga_pci_memset(pci_bar_handle_t handle, uint64_t offset, uint32_t value,
uint64_t dword_len);
/**
* Glibc 2.19 and lower support readdir_r, a reentrant version of readdir.
* Newer versions of glibc deprecate readdir_r and therefore require external
* synchronization on readdir.
*
* The mutex is used internally in fpga_pci_get_all_slot_specs to provide
* synchronization for calls to readdir. The calls to lock/unlock this mutex is exported
* so that if software which links with this library also uses readdir in a threaded
* environment, it can use this lock to protect calls to readdir.
*/
__attribute__((visibility("hidden"))) extern pthread_mutex_t fpga_pci_readdir_mutex;
int fpga_acquire_readdir_lock(void);
int fpga_release_readdir_lock(void);
#ifdef __cplusplus
}
#endif