/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-18 01:47:47 UTC
  • Revision ID: csa@suren.me-20151018014747-9ji2ygdhz1l9wnt5
Support properties of arbitrary type

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
#include <arpa/inet.h>
12
12
#include <errno.h>
13
13
#include <assert.h>
 
14
#include <alloca.h>
14
15
 
15
16
#include "pci.h"
16
17
#include "bank.h"
17
18
 
18
19
#include "tools.h"
19
20
#include "error.h"
20
 
 
 
21
#include "property.h"
21
22
 
22
23
int pcilib_add_registers(pcilib_t *ctx, pcilib_model_modification_flags_t flags, size_t n, const pcilib_register_description_t *registers, pcilib_register_t *ids) {
23
24
        // DS: Overrride existing registers 
24
25
        // Registers identified by addr + offset + size + type or name
25
 
        
 
26
    int err;
 
27
    size_t size;
26
28
    pcilib_register_t i;
 
29
 
27
30
    pcilib_register_description_t *regs;
28
31
    pcilib_register_context_t *reg_ctx;
29
 
    size_t size;
 
32
 
 
33
    pcilib_register_bank_t bank = PCILIB_REGISTER_BANK_INVALID;
 
34
    pcilib_register_bank_addr_t bank_addr = (pcilib_register_bank_addr_t)-1;
 
35
    pcilib_register_bank_t *banks;
30
36
 
31
37
    if (!n) {
32
38
        for (n = 0; registers[n].bits; n++);
59
65
        ctx->alloc_reg = size;
60
66
    }
61
67
 
 
68
    banks = (pcilib_register_bank_t*)alloca(n * sizeof(pcilib_register_bank_t));
 
69
    if (!banks) return PCILIB_ERROR_MEMORY;
 
70
 
 
71
    for (i = 0; i < n; i++) {
 
72
        if (registers[i].bank != bank_addr) {
 
73
            bank_addr = registers[i].bank;
 
74
            bank = pcilib_find_register_bank_by_addr(ctx, bank_addr);
 
75
            if (bank == PCILIB_REGISTER_BANK_INVALID) {
 
76
                pcilib_error("Invalid bank address (0x%lx) is specified for register %s", bank_addr, registers[i].name);
 
77
                return PCILIB_ERROR_INVALID_BANK;
 
78
            }
 
79
        }
 
80
 
 
81
/*
 
82
            // No hash so far, will iterate.
 
83
        pcilib_register_t reg = pcilib_find_register(ctx, ctx->banks[bank].name, registers[i].name);
 
84
        if (reg != PCILIB_REGISTER_INVALID) {
 
85
            pcilib_error("Register %s is already defined in the model", registers[i].name);
 
86
            return PCILIB_ERROR_EXIST;
 
87
        }
 
88
*/
 
89
 
 
90
        banks[i] = bank;
 
91
    }
 
92
 
 
93
    err = pcilib_add_register_properties(ctx, n, banks, registers);
 
94
    if (err) return err;
 
95
 
62
96
    for (i = 0; i < n; i++) {
63
97
        pcilib_register_context_t *cur = &ctx->register_ctx[ctx->num_reg + i];
 
98
 
64
99
        cur->reg = ctx->num_reg + i;
65
100
        cur->name = registers[i].name;
 
101
        cur->bank = banks[i];
66
102
        HASH_ADD_KEYPTR(hh, ctx->reg_hash, cur->name, strlen(cur->name), cur);
67
103
    }
68
 
    
 
104
 
69
105
    memcpy(ctx->registers + ctx->num_reg, registers, n * sizeof(pcilib_register_description_t));
70
106
    memset(ctx->registers + ctx->num_reg + n, 0, sizeof(pcilib_register_description_t));
71
107
 
78
114
 
79
115
    ctx->num_reg += n;
80
116
 
81
 
 
82
117
    return 0;
83
118
}
84
119
 
85
 
void pcilib_clean_registers(pcilib_t *ctx) {
 
120
void pcilib_clean_registers(pcilib_t *ctx, pcilib_register_t start) {
86
121
    pcilib_register_t reg;
87
 
 
88
 
    HASH_CLEAR(hh, ctx->reg_hash);
89
 
    for (reg = 0; reg < ctx->num_reg; reg++) {
 
122
    pcilib_register_context_t *reg_ctx, *tmp;
 
123
 
 
124
    if (start) {
 
125
        HASH_ITER(hh, ctx->reg_hash, reg_ctx, tmp) {
 
126
            if (reg_ctx->reg >= start) {
 
127
                HASH_DEL(ctx->reg_hash, reg_ctx);
 
128
            }
 
129
        }
 
130
    } else {
 
131
        HASH_CLEAR(hh, ctx->reg_hash);
 
132
    }
 
133
 
 
134
    for (reg = start; reg < ctx->num_reg; reg++) {
90
135
        if (ctx->register_ctx[reg].views)
91
136
            free(ctx->register_ctx[reg].views);
92
137
    }
93
138
 
94
139
    if (ctx->registers)
95
 
        memset(ctx->registers, 0, sizeof(pcilib_register_description_t));
 
140
        memset(&ctx->registers[start], 0, sizeof(pcilib_register_description_t));
96
141
 
97
142
    if (ctx->register_ctx)
98
 
        memset(ctx->register_ctx, 0, ctx->alloc_reg * sizeof(pcilib_register_context_t));
 
143
        memset(&ctx->register_ctx[start], 0, (ctx->alloc_reg - start) * sizeof(pcilib_register_context_t));
99
144
 
100
 
    ctx->num_reg = 0;
 
145
    ctx->num_reg = start;
101
146
}
102
147
 
103
148
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) {