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

  • Committer: Suren A. Chilingaryan
  • Date: 2015-10-19 13:58:46 UTC
  • Revision ID: csa@suren.me-20151019135846-nz3f6iobifx06xvq
Support computed (property-based) registers

Show diffs side-by-side

added added

removed removed

Lines of Context:
74
74
            bank_addr = registers[i].bank;
75
75
            bank = pcilib_find_register_bank_by_addr(ctx, bank_addr);
76
76
            if (bank == PCILIB_REGISTER_BANK_INVALID) {
77
 
                pcilib_error("Invalid bank address (0x%lx) is specified for register %s", bank_addr, registers[i].name);
78
 
                return PCILIB_ERROR_INVALID_BANK;
 
77
                    // We need to add a bank first in this case
 
78
                if (registers[i].type == PCILIB_REGISTER_PROPERTY) {
 
79
                    err = pcilib_add_register_banks(ctx, 0, 1, &pcilib_property_register_bank, &bank);
 
80
                } else {
 
81
                    err = PCILIB_ERROR_INVALID_BANK;
 
82
                }
 
83
 
 
84
                if (err) {
 
85
                    pcilib_error("Invalid bank address (0x%lx) is specified for register %s", bank_addr, registers[i].name);
 
86
                    return err;
 
87
                }
79
88
            }
80
89
        }
81
90
 
91
100
        banks[i] = bank;
92
101
    }
93
102
 
94
 
    err = pcilib_add_register_properties(ctx, n, banks, registers);
 
103
    err = pcilib_add_properties_from_registers(ctx, n, banks, registers);
95
104
    if (err) return err;
96
105
 
97
106
    for (i = 0; i < n; i++) {
148
157
 
149
158
static int pcilib_read_register_space_internal(pcilib_t *ctx, pcilib_register_bank_t bank, pcilib_register_addr_t addr, size_t n, pcilib_register_size_t offset, pcilib_register_size_t bits, pcilib_register_value_t *buf) {
150
159
    int err;
 
160
 
151
161
    size_t i;
 
162
    size_t space_size;
152
163
 
153
164
    pcilib_register_bank_context_t *bctx = ctx->bank_ctx[bank];
154
165
    const pcilib_register_protocol_api_description_t *bapi = bctx->api;
163
174
        return PCILIB_ERROR_NOTSUPPORTED;
164
175
    }
165
176
 
166
 
    if (((addr + n) > b->size)||(((addr + n) == b->size)&&(bits))) {
 
177
    if (b->protocol == PCILIB_REGISTER_PROTOCOL_PROPERTY) space_size = ctx->num_views;
 
178
    else space_size = b->size;
 
179
 
 
180
    if (((addr + n) > space_size)||(((addr + n) == space_size)&&(bits))) {
167
181
        if ((b->format)&&(strchr(b->format, 'x')))
168
 
            pcilib_error("Accessing register (%u regs at addr 0x%x) out of register space (%u registers total)", bits?(n+1):n, addr, b->size);
 
182
            pcilib_error("Accessing register (%u regs at addr 0x%x) out of register space (%u registers total)", bits?(n+1):n, addr, space_size);
169
183
        else 
170
 
            pcilib_error("Accessing register (%u regs at addr %u) out of register space (%u registers total)", bits?(n+1):n, addr, b->size);
 
184
            pcilib_error("Accessing register (%u regs at addr %u) out of register space (%u registers total)", bits?(n+1):n, addr, space_size);
171
185
        return PCILIB_ERROR_OUTOFRANGE;
172
186
    }
173
187
 
 
188
    if (b->protocol == PCILIB_REGISTER_PROTOCOL_PROPERTY) {
 
189
        for (i = 0; i < (bits?(n+1):n); i++) {
 
190
            if ((ctx->views[i]->flags&PCILIB_VIEW_FLAG_REGISTER) == 0) {
 
191
                pcilib_error("Accessing invalid register %u (associated view does not provide register functionality)", addr + i);
 
192
                return PCILIB_ERROR_INVALID_REQUEST;
 
193
            }
 
194
 
 
195
            if ((ctx->views[i]->mode&PCILIB_ACCESS_R) == 0) {
 
196
                pcilib_error("Read access is not allowed to register %u", addr + i);
 
197
                return PCILIB_ERROR_NOTPERMITED;
 
198
            }
 
199
        }
 
200
    } 
 
201
 
174
202
    //err = pcilib_init_register_banks(ctx);
175
203
    //if (err) return err;
176
204
    
259
287
 
260
288
static int pcilib_write_register_space_internal(pcilib_t *ctx, pcilib_register_bank_t bank, pcilib_register_addr_t addr, size_t n, pcilib_register_size_t offset, pcilib_register_size_t bits, pcilib_register_value_t rwmask, pcilib_register_value_t *buf) {
261
289
    int err;
 
290
 
262
291
    size_t i;
 
292
    size_t space_size;
263
293
 
264
294
    pcilib_register_bank_context_t *bctx = ctx->bank_ctx[bank];
265
295
    const pcilib_register_protocol_api_description_t *bapi = bctx->api;
274
304
        return PCILIB_ERROR_NOTSUPPORTED;
275
305
    }
276
306
 
277
 
    if (((addr + n) > b->size)||(((addr + n) == b->size)&&(bits))) {
 
307
    if (b->protocol == PCILIB_REGISTER_PROTOCOL_PROPERTY) space_size = ctx->num_views;
 
308
    else space_size = b->size;
 
309
 
 
310
    if (((addr + n) > space_size)||(((addr + n) == space_size)&&(bits))) {
278
311
        if ((b->format)&&(strchr(b->format, 'x')))
279
 
            pcilib_error("Accessing register (%u regs at addr 0x%x) out of register space (%u registers total)", bits?(n+1):n, addr, b->size);
 
312
            pcilib_error("Accessing register (%u regs at addr 0x%x) out of register space (%u registers total)", bits?(n+1):n, addr, space_size);
280
313
        else 
281
 
            pcilib_error("Accessing register (%u regs at addr %u) out of register space (%u registers total)", bits?(n+1):n, addr, b->size);
 
314
            pcilib_error("Accessing register (%u regs at addr %u) out of register space (%u registers total)", bits?(n+1):n, addr, space_size);
282
315
        return PCILIB_ERROR_OUTOFRANGE;
283
316
    }
284
317
 
 
318
    if (b->protocol == PCILIB_REGISTER_PROTOCOL_PROPERTY) {
 
319
        for (i = 0; i < (bits?(n+1):n); i++) {
 
320
            if ((ctx->views[i]->flags&PCILIB_VIEW_FLAG_REGISTER) == 0) {
 
321
                pcilib_error("Accessing invalid register %u (associated view does not provide register functionality)", addr + i);
 
322
                return PCILIB_ERROR_INVALID_REQUEST;
 
323
            }
 
324
 
 
325
            if ((ctx->views[i]->mode&PCILIB_ACCESS_W) == 0) {
 
326
                pcilib_error("Write access is not allowed to register %u", addr + i);
 
327
                return PCILIB_ERROR_NOTPERMITED;
 
328
            }
 
329
        }
 
330
    } 
 
331
 
285
332
    //err = pcilib_init_register_banks(ctx);
286
333
    //if (err) return err;
287
334