/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 pci.c

  • Committer: Suren A. Chilingaryan
  • Date: 2015-04-20 20:01:04 UTC
  • Revision ID: csa@suren.me-20150420200104-b5xny65io8lvoz3w
Big redign of model structures

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#define _PCILIB_PCI_C
2
1
//#define PCILIB_FILE_IO
3
 
#define _POSIX_C_SOURCE 199309L
 
2
#define _BSD_SOURCE
 
3
#define _POSIX_C_SOURCE 200809L
4
4
 
5
5
#include <stdio.h>
6
6
#include <string.h>
17
17
 
18
18
#include "pcilib.h"
19
19
#include "pci.h"
20
 
#include "kernel.h"
21
20
#include "tools.h"
22
21
#include "error.h"
23
 
 
24
 
#include "ipecamera/model.h"
25
 
#include "kapture/model.h"
26
 
 
27
 
 
28
 
pcilib_t *pcilib_open(const char *device, pcilib_model_t model) {
 
22
#include "model.h"
 
23
 
 
24
static int pcilib_detect_model(pcilib_t *ctx, const char *model) {
 
25
    int i, j;
 
26
 
 
27
        // Registers & Banks must be copied!
 
28
 
 
29
    if (model) {
 
30
            // Check for DMA models
 
31
        for (i = 0; pcilib_dma[i].name; i++) {
 
32
            if (!strcasecmp(model, pcilib_dma[i].name))
 
33
                break;
 
34
        }
 
35
 
 
36
        if (pcilib_dma[i].api) {
 
37
            memcpy(&ctx->dma, &pcilib_dma[i], sizeof(pcilib_dma_description_t));
 
38
            ctx->model_info.dma = &ctx->dma;
 
39
 
 
40
            if (pcilib_dma[i].banks)
 
41
                pcilib_add_register_banks(ctx, 0, pcilib_dma[i].banks);
 
42
            
 
43
            if (pcilib_dma[i].registers)
 
44
                pcilib_add_registers(ctx, 0, pcilib_dma[i].registers);
 
45
 
 
46
            if (pcilib_dma[i].engines) {
 
47
                for (j = 0; pcilib_dma[i].engines[j].addr_bits; j++)
 
48
                memcpy(ctx->engines, pcilib_dma[i].engines, j * sizeof(pcilib_dma_engine_description_t));
 
49
                ctx->num_engines = j;
 
50
            } else
 
51
                ctx->dma.engines = ctx->engines;
 
52
 
 
53
            return 0;
 
54
        }
 
55
 
 
56
        // Check for XML models (DMA + XML registers)
 
57
 
 
58
        // Check for specified model
 
59
        
 
60
        // Iterate other all other models
 
61
    }
 
62
 
 
63
    // Check for all installed models
 
64
    // memcpy(&ctx->model_info, model, sizeof(pcilib_model_description_t));
 
65
    // how we reconcile the banks from event model and dma description? The banks specified in the DMA description should override corresponding banks of events...
 
66
 
 
67
 
 
68
    if (model)
 
69
        return PCILIB_ERROR_NOTFOUND;
 
70
 
 
71
        // Otherwise, simple pci access (all model members are set to NULL)
 
72
 
 
73
    return 0;
 
74
}
 
75
 
 
76
 
 
77
 
 
78
pcilib_t *pcilib_open(const char *device, const char *model) {
 
79
    int err;
 
80
    size_t i;
29
81
    pcilib_t *ctx = malloc(sizeof(pcilib_t));
30
82
 
31
83
    if (ctx) {
32
 
        memset(ctx, 0, sizeof(pcilib_t));       
33
 
    
 
84
        memset(ctx, 0, sizeof(pcilib_t));
 
85
        
34
86
        ctx->handle = open(device, O_RDWR);
35
87
        if (ctx->handle < 0) {
36
88
            pcilib_error("Error opening device (%s)", device);
39
91
        }
40
92
        
41
93
        ctx->page_mask = (uintptr_t)-1;
42
 
        ctx->model = model;
43
 
 
44
 
        if (!model) model = pcilib_get_model(ctx);
45
 
        
46
 
        memcpy(&ctx->model_info, pcilib_model + model, sizeof(pcilib_model_description_t));
47
 
 
48
 
        pcilib_init_event_engine(ctx);
 
94
        ctx->model = model?strdup(model):NULL;
 
95
 
 
96
        ctx->alloc_reg = PCILIB_DEFAULT_REGISTER_SPACE;
 
97
        ctx->registers = (pcilib_register_description_t *)malloc(PCILIB_DEFAULT_REGISTER_SPACE * sizeof(pcilib_register_description_t));
 
98
/*      ctx->banks = (pcilib_register_bank_context_t *)malloc(PCILIB_MAX_BANKS * sizeof(pcilib_register_bank_context_t));
 
99
        ctx->ranges = (pcilib_register_range_t *)malloc(PCILIB_MAX_RANGES * sizeof(pcilib_register_range_t));
 
100
        ctx->protocols
 
101
        ctx->engines*/
 
102
        
 
103
        if ((!ctx->registers)/*||(!ctx->banks)||(!ctx->ranges)*/) {
 
104
            pcilib_error("Error allocating memory for register model");
 
105
            pcilib_close(ctx);
 
106
            free(ctx);
 
107
            return NULL;
 
108
        }
 
109
        
 
110
        memset(ctx->registers, 0, sizeof(pcilib_register_description_t));
 
111
        memset(ctx->banks, 0, sizeof(pcilib_register_bank_description_t));
 
112
        memset(ctx->ranges, 0, sizeof(pcilib_register_range_t));
 
113
        
 
114
        for (i = 0; pcilib_protocols[i].api; i++);
 
115
        memcpy(ctx->protocols, pcilib_protocols, i * sizeof(pcilib_register_protocol_description_t));
 
116
 
 
117
        ctx->model_info.registers = ctx->registers;
 
118
        ctx->model_info.banks = ctx->banks;
 
119
        ctx->model_info.protocols = ctx->protocols;
 
120
        ctx->model_info.ranges = ctx->ranges;
 
121
 
 
122
        err = pcilib_detect_model(ctx, model);
 
123
        if (err) {
 
124
            const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
 
125
            if (board_info)
 
126
                pcilib_error("Error (%i) configuring model %s (%x:%x)", err, (model?model:""), board_info->vendor_id, board_info->device_id);
 
127
            else
 
128
                pcilib_error("Error (%i) configuring model %s", err, (model?model:""));
 
129
            pcilib_close(ctx);
 
130
            free(ctx);
 
131
            return NULL;
 
132
        }
 
133
 
 
134
        err = pcilib_init_register_banks(ctx);
 
135
        if (err) {
 
136
            pcilib_error("Error (%i) initializing regiser banks\n", err);
 
137
            pcilib_close(ctx);
 
138
            free(ctx);
 
139
            return NULL;
 
140
        }
 
141
        
 
142
        err = pcilib_init_event_engine(ctx);
 
143
        if (err) {
 
144
            pcilib_error("Error (%i) initializing event engine\n", err);
 
145
            pcilib_close(ctx);
 
146
            free(ctx);
 
147
            return NULL;
 
148
        }
49
149
    }
50
150
 
51
151
    return ctx;
52
152
}
53
153
 
54
 
pcilib_model_description_t *pcilib_get_model_description(pcilib_t *ctx) {
55
 
    return &ctx->model_info;
56
 
}
57
154
 
58
155
const pcilib_board_info_t *pcilib_get_board_info(pcilib_t *ctx) {
59
156
    int ret;
72
169
}
73
170
 
74
171
 
75
 
 
76
172
pcilib_context_t *pcilib_get_implementation_context(pcilib_t *ctx) {
77
173
    return ctx->event_ctx;
78
174
}
79
175
 
80
 
pcilib_model_t pcilib_get_model(pcilib_t *ctx) {
81
 
    if (ctx->model == PCILIB_MODEL_DETECT) {
82
 
//      unsigned short vendor_id;
83
 
//      unsigned short device_id;
84
 
 
85
 
        //return PCILIB_MODEL_PCI;
86
 
        
87
 
        const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
88
 
        if (!board_info) return PCILIB_MODEL_PCI;
89
 
 
90
 
        if ((board_info->vendor_id == PCIE_XILINX_VENDOR_ID)&&(board_info->device_id == PCIE_IPECAMERA_DEVICE_ID))
91
 
            ctx->model = PCILIB_MODEL_IPECAMERA;
92
 
        else if ((board_info->vendor_id == PCIE_XILINX_VENDOR_ID)&&(board_info->device_id == PCIE_KAPTURE_DEVICE_ID))
93
 
            ctx->model = PCILIB_MODEL_KAPTURE;
94
 
        else
95
 
            ctx->model = PCILIB_MODEL_PCI;
96
 
    }
97
 
    
98
 
    return ctx->model;
99
 
}
100
176
 
101
177
static pcilib_bar_t pcilib_detect_bar(pcilib_t *ctx, uintptr_t addr, size_t size) {
102
178
    int n = 0;
105
181
    const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
106
182
    if (!board_info) return PCILIB_BAR_INVALID;
107
183
                
108
 
    for (i = 0; i < PCILIB_MAX_BANKS; i++) {
 
184
    for (i = 0; i < PCILIB_MAX_BARS; i++) {
109
185
        if (board_info->bar_length[i] > 0) {
110
186
            if ((addr >= board_info->bar_start[i])&&((board_info->bar_start[i] + board_info->bar_length[i]) >= (addr + size))) return i;
111
187
 
201
277
    pcilib_register_bank_t i;
202
278
    
203
279
    if (!ctx->reg_bar_mapped)  {
204
 
        pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
205
 
        pcilib_register_bank_description_t *banks = model_info->banks;
 
280
        const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
 
281
        const pcilib_register_bank_description_t *banks = model_info->banks;
206
282
    
207
283
        for (i = 0; ((banks)&&(banks[i].access)); i++) {
208
284
//          uint32_t buf[2];
235
311
//              pcilib_memcpy(&buf, reg_space, 8);
236
312
                
237
313
            }
 
314
            
238
315
            if (!i) ctx->reg_bar = bar;
239
316
        }
240
317
        
 
318
        
241
319
        ctx->reg_bar_mapped = 1;
242
320
    }
243
321
    
260
338
        
261
339
        int data_bar = -1;      
262
340
        
263
 
        for (i = 0; i < PCILIB_MAX_BANKS; i++) {
 
341
        for (i = 0; i < PCILIB_MAX_BARS; i++) {
264
342
            if ((ctx->bar_space[i])||(!board_info->bar_length[i])) continue;
265
343
            
266
344
            if (addr) {
302
380
    return 0;
303
381
}
304
382
        
305
 
/*
306
 
static void pcilib_unmap_register_space(pcilib_t *ctx) {
307
 
    if (ctx->reg_space) {
308
 
        pcilib_unmap_bar(ctx, ctx->reg_bar, ctx->reg_space);
309
 
        ctx->reg_space = NULL;
310
 
    }
311
 
}
312
 
 
313
 
static void pcilib_unmap_data_space(pcilib_t *ctx) {
314
 
    if (ctx->data_space) {
315
 
        pcilib_unmap_bar(ctx, ctx->data_bar, ctx->data_space);
316
 
        ctx->data_space = NULL;
317
 
    }
318
 
}
319
 
*/
320
 
 
321
383
char  *pcilib_resolve_register_address(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr) {
322
384
    if (bar == PCILIB_BAR_DETECT) {
323
385
            // First checking the default register bar
378
440
 
379
441
void pcilib_close(pcilib_t *ctx) {
380
442
    pcilib_bar_t i;
381
 
    
 
443
 
382
444
    if (ctx) {
383
 
        pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
384
 
        pcilib_event_api_description_t *eapi = model_info->event_api;
385
 
        pcilib_dma_api_description_t *dapi = model_info->dma_api;
386
 
    
 
445
        const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
 
446
        const pcilib_event_api_description_t *eapi = model_info->api;
 
447
        const pcilib_dma_api_description_t *dapi = NULL;
 
448
        
 
449
        if (model_info->dma) dapi = model_info->dma->api;
 
450
 
387
451
        if ((eapi)&&(eapi->free)) eapi->free(ctx->event_ctx);
388
452
        if ((dapi)&&(dapi->free)) dapi->free(ctx->dma_ctx);
389
 
        
390
 
        if (ctx->model_info.registers != model_info->registers) {
391
 
            free(ctx->model_info.registers);
392
 
            ctx->model_info.registers = pcilib_model[ctx->model].registers;
393
 
        }
 
453
 
 
454
        pcilib_free_register_banks(ctx);
394
455
        
395
456
        if (ctx->kmem_list) {
396
457
            pcilib_warning("Not all kernel buffers are properly cleaned");
399
460
                pcilib_free_kernel_memory(ctx, ctx->kmem_list, 0);
400
461
            }
401
462
        }
402
 
 
403
 
        for (i = 0; i < PCILIB_MAX_BANKS; i++) {
 
463
        
 
464
        for (i = 0; i < PCILIB_MAX_BARS; i++) {
404
465
            if (ctx->bar_space[i]) {
405
466
                char *ptr = ctx->bar_space[i];
406
467
                ctx->bar_space[i] = NULL;
407
468
                pcilib_unmap_bar(ctx, i, ptr);
408
469
            }
409
470
        }
410
 
        close(ctx->handle);
 
471
 
 
472
        if (ctx->registers)
 
473
            free(ctx->registers);
 
474
        
 
475
        if (ctx->model)
 
476
            free(ctx->model);
 
477
        
 
478
        if (ctx->handle >= 0)
 
479
            close(ctx->handle);
411
480
        
412
481
        free(ctx);
413
482
    }