/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool

« back to all changes in this revision

Viewing changes to pcilib/pci.c

  • Committer: Suren A. Chilingaryan
  • Date: 2015-05-05 13:27:22 UTC
  • Revision ID: csa@suren.me-20150505132722-rz47ppxkx39x2koj
Split bar manipulation and fifo operations in stand-alone source and publish kmem and bar headers

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
#include "error.h"
22
22
#include "model.h"
23
23
#include "plugin.h"
 
24
#include "bar.h"
24
25
 
25
26
static int pcilib_detect_model(pcilib_t *ctx, const char *model) {
26
27
    int i, j;
86
87
    // how we reconcile the banks from event model and dma description? The banks specified in the DMA description should override corresponding banks of events...
87
88
 
88
89
 
89
 
    if ((model)&&(!model_info)/*&&(no xml)*/)
90
 
        return PCILIB_ERROR_NOTFOUND;
 
90
    if (!model_info) {
 
91
        if ((model)&&(strcasecmp(model, "pci"))/*&&(no xml)*/)
 
92
            return PCILIB_ERROR_NOTFOUND;
 
93
        
 
94
        ctx->model = strdup("pci");
 
95
    }
91
96
 
92
97
    return 0;
93
98
}
192
197
    return ctx->event_ctx;
193
198
}
194
199
 
195
 
 
196
 
static pcilib_bar_t pcilib_detect_bar(pcilib_t *ctx, uintptr_t addr, size_t size) {
197
 
    int n = 0;
198
 
    pcilib_bar_t i;
199
 
        
200
 
    const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
201
 
    if (!board_info) return PCILIB_BAR_INVALID;
202
 
                
203
 
    for (i = 0; i < PCILIB_MAX_BARS; i++) {
204
 
        if (board_info->bar_length[i] > 0) {
205
 
            if ((addr >= board_info->bar_start[i])&&((board_info->bar_start[i] + board_info->bar_length[i]) >= (addr + size))) return i;
206
 
 
207
 
            if (n) n = -1;
208
 
            else n = i + 1;
209
 
        }
210
 
    }
211
 
 
212
 
    if (n > 0) return n - 1;
213
 
 
214
 
    return PCILIB_BAR_INVALID;
215
 
}
216
 
 
217
 
int pcilib_detect_address(pcilib_t *ctx, pcilib_bar_t *bar, uintptr_t *addr, size_t size) {
218
 
    const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
219
 
    if (!board_info) return PCILIB_ERROR_NOTFOUND;
220
 
    
221
 
    if (*bar == PCILIB_BAR_DETECT) {
222
 
        *bar = pcilib_detect_bar(ctx, *addr, size);
223
 
        if (*bar == PCILIB_BAR_INVALID) {
224
 
            pcilib_error("The requested data block at address 0x%x with size %zu does not belongs to any available memory bank", *addr, size);
225
 
            return PCILIB_ERROR_NOTFOUND;
226
 
        }
227
 
        if (*addr < board_info->bar_start[*bar]) 
228
 
            *addr += board_info->bar_start[*bar];
229
 
    } else {
230
 
        if ((*addr < board_info->bar_start[*bar])||((board_info->bar_start[*bar] + board_info->bar_length[*bar]) < (((uintptr_t)*addr) + size))) {
231
 
            if ((board_info->bar_length[*bar]) >= (((uintptr_t)*addr) + size)) {
232
 
                *addr += board_info->bar_start[*bar];
233
 
            } else {
234
 
                pcilib_error("The requested data block at address 0x%x with size %zu does not belong the specified memory bank (Bar %i: starting at 0x%x with size 0x%x)", *addr, size, *bar, board_info->bar_start[*bar], board_info->bar_length[*bar]);
235
 
                return PCILIB_ERROR_NOTFOUND;
236
 
            }
237
 
        }
238
 
    }
239
 
 
240
 
    *addr -= board_info->bar_start[*bar];
241
 
    *addr += board_info->bar_start[*bar] & ctx->page_mask;
242
 
 
243
 
    return 0;
244
 
}
245
 
 
246
 
void *pcilib_map_bar(pcilib_t *ctx, pcilib_bar_t bar) {
247
 
    void *res;
248
 
    int ret; 
249
 
 
250
 
    const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
251
 
    if (!board_info) return NULL;
252
 
    
253
 
    if (ctx->bar_space[bar]) return ctx->bar_space[bar];
254
 
    
255
 
    ret = ioctl( ctx->handle, PCIDRIVER_IOC_MMAP_MODE, PCIDRIVER_MMAP_PCI );
256
 
    if (ret) {
257
 
        pcilib_error("PCIDRIVER_IOC_MMAP_MODE ioctl have failed", bar);
258
 
        return NULL;
259
 
    }
260
 
 
261
 
    ret = ioctl( ctx->handle, PCIDRIVER_IOC_MMAP_AREA, PCIDRIVER_BAR0 + bar );
262
 
    if (ret) {
263
 
        pcilib_error("PCIDRIVER_IOC_MMAP_AREA ioctl have failed for bank %i", bar);
264
 
        return NULL;
265
 
    }
266
 
 
267
 
#ifdef PCILIB_FILE_IO
268
 
    file_io_handle = open("/root/data", O_RDWR);
269
 
    res = mmap( 0, board_info->bar_length[bar], PROT_WRITE | PROT_READ, MAP_SHARED, ctx->file_io_handle, 0 );
270
 
#else
271
 
    res = mmap( 0, board_info->bar_length[bar], PROT_WRITE | PROT_READ, MAP_SHARED, ctx->handle, 0 );
272
 
#endif
273
 
    if ((!res)||(res == MAP_FAILED)) {
274
 
        pcilib_error("Failed to mmap data bank %i", bar);
275
 
        return NULL;
276
 
    }
277
 
 
278
 
    
279
 
    return res;
280
 
}
281
 
 
282
 
void pcilib_unmap_bar(pcilib_t *ctx, pcilib_bar_t bar, void *data) {
283
 
    const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
284
 
    if (!board_info) return;
285
 
 
286
 
    if (ctx->bar_space[bar]) return;
287
 
    
288
 
    munmap(data, board_info->bar_length[bar]);
289
 
#ifdef PCILIB_FILE_IO
290
 
    close(ctx->file_io_handle);
291
 
#endif
292
 
}
293
 
 
294
 
int pcilib_map_register_space(pcilib_t *ctx) {
295
 
    int err;
296
 
    pcilib_register_bank_t i;
297
 
    
298
 
    if (!ctx->reg_bar_mapped)  {
299
 
        const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
300
 
        const pcilib_register_bank_description_t *banks = model_info->banks;
301
 
    
302
 
        for (i = 0; ((banks)&&(banks[i].access)); i++) {
303
 
//          uint32_t buf[2];
304
 
            void *reg_space;
305
 
            pcilib_bar_t bar = banks[i].bar;
306
 
 
307
 
            if (bar == PCILIB_BAR_DETECT) {
308
 
                uintptr_t addr = banks[0].read_addr;
309
 
            
310
 
                err = pcilib_detect_address(ctx, &bar, &addr, 1);
311
 
                if (err) return err;
312
 
                
313
 
                if (!ctx->bar_space[bar]) {
314
 
                    reg_space = pcilib_map_bar(ctx, bar);
315
 
//                  pcilib_memcpy(&buf, reg_space, 8);
316
 
            
317
 
                    if (reg_space) {
318
 
                        ctx->bar_space[bar] = reg_space;
319
 
                    } else {
320
 
                        return PCILIB_ERROR_FAILED;
321
 
                    }
322
 
                }
323
 
            } else if (!ctx->bar_space[bar]) {
324
 
                reg_space = pcilib_map_bar(ctx, bar);
325
 
                if (reg_space) {
326
 
                    ctx->bar_space[bar] = reg_space;
327
 
                } else {
328
 
                    return PCILIB_ERROR_FAILED;
329
 
                }
330
 
//              pcilib_memcpy(&buf, reg_space, 8);
331
 
                
332
 
            }
333
 
            
334
 
            if (!i) ctx->reg_bar = bar;
335
 
        }
336
 
        
337
 
        
338
 
        ctx->reg_bar_mapped = 1;
339
 
    }
340
 
    
341
 
    return 0;
342
 
}
343
 
 
344
200
int pcilib_map_data_space(pcilib_t *ctx, uintptr_t addr) {
345
201
    int err;
346
202
    pcilib_bar_t i;
505
361
    }
506
362
}
507
363
 
508
 
int pcilib_read(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf) {
509
 
    void *data;
510
 
 
511
 
    pcilib_detect_address(ctx, &bar, &addr, size);
512
 
    data = pcilib_map_bar(ctx, bar);
513
 
 
514
 
    pcilib_memcpy(buf, data + addr, size);
515
 
 
516
 
    pcilib_unmap_bar(ctx, bar, data);
517
 
 
518
 
    return 0;
519
 
}
520
 
 
521
 
int pcilib_write(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf) {
522
 
    void *data;
523
 
 
524
 
    pcilib_detect_address(ctx, &bar, &addr, size);
525
 
    data = pcilib_map_bar(ctx, bar);
526
 
 
527
 
    pcilib_memcpy(data + addr, buf, size);
528
 
 
529
 
    pcilib_unmap_bar(ctx, bar, data);
530
 
 
531
 
    return 0;
532
 
}
533
 
 
534
 
 
535
 
int pcilib_read_fifo(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t fifo_size, size_t n, void *buf) {
536
 
    int i;
537
 
    void *data;
538
 
 
539
 
    pcilib_detect_address(ctx, &bar, &addr, fifo_size);
540
 
    data = pcilib_map_bar(ctx, bar);
541
 
 
542
 
    for (i = 0; i < n; i++) {
543
 
        pcilib_memcpy(buf + i * fifo_size, data + addr, fifo_size);
544
 
    }
545
 
 
546
 
    pcilib_unmap_bar(ctx, bar, data);
547
 
 
548
 
    return 0;
549
 
}
550
 
 
551
 
int pcilib_write_fifo(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t fifo_size, size_t n, void *buf) {
552
 
    int i;
553
 
    void *data;
554
 
 
555
 
    pcilib_detect_address(ctx, &bar, &addr, fifo_size);
556
 
    data = pcilib_map_bar(ctx, bar);
557
 
 
558
 
    for (i = 0; i < n; i++) {
559
 
        pcilib_memcpy(data + addr, buf + i * fifo_size, fifo_size);
560
 
    }
561
 
 
562
 
    pcilib_unmap_bar(ctx, bar, data);
563
 
 
564
 
    return 0;
565
 
}