2
#define _POSIX_C_SOURCE 200809L
11
#include <sys/ioctl.h>
13
#include <arpa/inet.h>
24
pcilib_bar_t pcilib_detect_bar(pcilib_t *ctx, uintptr_t addr, size_t size) {
28
const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
29
if (!board_info) return PCILIB_BAR_INVALID;
31
for (i = 0; i < PCILIB_MAX_BARS; i++) {
32
if (board_info->bar_length[i] > 0) {
33
if ((addr >= board_info->bar_start[i])&&((board_info->bar_start[i] + board_info->bar_length[i]) >= (addr + size))) return i;
40
if (n > 0) return n - 1;
42
return PCILIB_BAR_INVALID;
45
int pcilib_detect_address(pcilib_t *ctx, pcilib_bar_t *bar, uintptr_t *addr, size_t size) {
46
const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
47
if (!board_info) return PCILIB_ERROR_NOTFOUND;
49
if (*bar == PCILIB_BAR_DETECT) {
50
*bar = pcilib_detect_bar(ctx, *addr, size);
51
if (*bar == PCILIB_BAR_INVALID) {
52
pcilib_error("The requested data block at address 0x%x with size %zu does not belongs to any available memory bar", *addr, size);
53
return PCILIB_ERROR_NOTFOUND;
55
if (*addr < board_info->bar_start[*bar])
56
*addr += board_info->bar_start[*bar];
58
if ((*addr < board_info->bar_start[*bar])||((board_info->bar_start[*bar] + board_info->bar_length[*bar]) < (((uintptr_t)*addr) + size))) {
59
if ((board_info->bar_length[*bar]) >= (((uintptr_t)*addr) + size)) {
60
*addr += board_info->bar_start[*bar];
62
pcilib_error("The requested data block at address 0x%x with size %zu does not belong the specified memory bar (Bar %i: starting at 0x%x with size 0x%x)", *addr, size, *bar, board_info->bar_start[*bar], board_info->bar_length[*bar]);
63
return PCILIB_ERROR_NOTFOUND;
68
*addr -= board_info->bar_start[*bar];
69
*addr += board_info->bar_start[*bar] & ctx->page_mask;
74
void *pcilib_map_bar(pcilib_t *ctx, pcilib_bar_t bar) {
78
const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
79
if (!board_info) return NULL;
81
if (ctx->bar_space[bar]) return ctx->bar_space[bar];
83
ret = ioctl( ctx->handle, PCIDRIVER_IOC_MMAP_MODE, PCIDRIVER_MMAP_PCI );
85
pcilib_error("PCIDRIVER_IOC_MMAP_MODE ioctl have failed", bar);
89
ret = ioctl( ctx->handle, PCIDRIVER_IOC_MMAP_AREA, PCIDRIVER_BAR0 + bar );
91
pcilib_error("PCIDRIVER_IOC_MMAP_AREA ioctl have failed for bank %i", bar);
96
file_io_handle = open("/root/data", O_RDWR);
97
res = mmap( 0, board_info->bar_length[bar], PROT_WRITE | PROT_READ, MAP_SHARED, ctx->file_io_handle, 0 );
99
res = mmap( 0, board_info->bar_length[bar], PROT_WRITE | PROT_READ, MAP_SHARED, ctx->handle, 0 );
101
if ((!res)||(res == MAP_FAILED)) {
102
pcilib_error("Failed to mmap data bank %i", bar);
110
void pcilib_unmap_bar(pcilib_t *ctx, pcilib_bar_t bar, void *data) {
111
const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
112
if (!board_info) return;
114
if (ctx->bar_space[bar]) return;
116
munmap(data, board_info->bar_length[bar]);
117
#ifdef PCILIB_FILE_IO
118
close(ctx->file_io_handle);
122
int pcilib_map_register_space(pcilib_t *ctx) {
124
pcilib_register_bank_t i;
126
if (!ctx->reg_bar_mapped) {
127
const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
128
const pcilib_register_bank_description_t *banks = model_info->banks;
130
for (i = 0; ((banks)&&(banks[i].access)); i++) {
133
pcilib_bar_t bar = banks[i].bar;
135
if (bar == PCILIB_BAR_DETECT) {
136
uintptr_t addr = banks[0].read_addr;
138
err = pcilib_detect_address(ctx, &bar, &addr, 1);
141
if (!ctx->bar_space[bar]) {
142
reg_space = pcilib_map_bar(ctx, bar);
143
// pcilib_memcpy(&buf, reg_space, 8);
146
ctx->bar_space[bar] = reg_space;
148
return PCILIB_ERROR_FAILED;
151
} else if (!ctx->bar_space[bar]) {
152
reg_space = pcilib_map_bar(ctx, bar);
154
ctx->bar_space[bar] = reg_space;
156
return PCILIB_ERROR_FAILED;
158
// pcilib_memcpy(&buf, reg_space, 8);
162
if (!i) ctx->reg_bar = bar;
166
ctx->reg_bar_mapped = 1;
172
int pcilib_read(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf) {
175
pcilib_detect_address(ctx, &bar, &addr, size);
176
data = pcilib_map_bar(ctx, bar);
178
pcilib_memcpy(buf, data + addr, size);
180
pcilib_unmap_bar(ctx, bar, data);
185
int pcilib_write(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf) {
188
pcilib_detect_address(ctx, &bar, &addr, size);
189
data = pcilib_map_bar(ctx, bar);
191
pcilib_memcpy(data + addr, buf, size);
193
pcilib_unmap_bar(ctx, bar, data);