20
int pcilib_add_registers(pcilib_t *ctx, size_t n, pcilib_register_description_t *registers) {
21
pcilib_register_description_t *regs;
22
size_t size, n_present, n_new;
25
for (n = 0; registers[n].bits; n++);
29
if (ctx->model_info.registers == pcilib_model[ctx->model].registers) {
30
for (n_present = 0; ctx->model_info.registers[n_present].bits; n_present++);
31
for (size = 1024; size < 2 * (n + n_present + 1); size<<=1);
32
regs = (pcilib_register_description_t*)malloc(size * sizeof(pcilib_register_description_t));
33
if (!regs) return PCILIB_ERROR_MEMORY;
35
ctx->model_info.registers = regs;
36
ctx->num_reg = n + n_present;
37
ctx->alloc_reg = size;
39
memcpy(ctx->model_info.registers, pcilib_model[ctx->model].registers, (n_present + 1) * sizeof(pcilib_register_description_t));
41
n_present = ctx->num_reg;
42
if ((n_present + n + 1) > ctx->alloc_reg) {
43
for (size = ctx->alloc_reg; size < 2 * (n + n_present + 1); size<<=1);
45
regs = (pcilib_register_description_t*)realloc(ctx->model_info.registers, size * sizeof(pcilib_register_description_t));
46
if (!regs) return PCILIB_ERROR_MEMORY;
48
ctx->model_info.registers = regs;
49
ctx->alloc_reg = size;
54
memcpy(ctx->model_info.registers + ctx->num_reg, ctx->model_info.registers + n_present, sizeof(pcilib_register_description_t));
55
memcpy(ctx->model_info.registers + n_present, registers, n * sizeof(pcilib_register_description_t));
20
60
pcilib_register_bank_t pcilib_find_bank_by_addr(pcilib_t *ctx, pcilib_register_bank_addr_t bank) {
21
61
pcilib_register_bank_t i;
22
pcilib_model_t model = pcilib_get_model(ctx);
23
pcilib_register_bank_description_t *banks = pcilib_model[model].banks;
62
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
63
pcilib_register_bank_description_t *banks = model_info->banks;
25
65
for (i = 0; banks[i].access; i++)
26
66
if (banks[i].addr == bank) return i;
31
71
pcilib_register_bank_t pcilib_find_bank_by_name(pcilib_t *ctx, const char *bankname) {
32
72
pcilib_register_bank_t i;
33
pcilib_register_bank_description_t *banks = pcilib_model[ctx->model].banks;
73
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
74
pcilib_register_bank_description_t *banks = model_info->banks;
35
76
for (i = 0; banks[i].access; i++)
36
77
if (!strcasecmp(banks[i].name, bankname)) return i;
43
84
unsigned long addr;
46
pcilib_model_t model = pcilib_get_model(ctx);
47
pcilib_register_bank_description_t *banks = pcilib_model[model].banks;
87
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
88
pcilib_register_bank_description_t *banks = model_info->banks;
48
89
if ((banks)&&(banks[0].access)) return (pcilib_register_bank_t)0;
62
103
pcilib_register_t i;
63
104
pcilib_register_bank_t bank_id;
64
105
pcilib_register_bank_addr_t bank_addr;
66
pcilib_model_t model = pcilib_get_model(ctx);
68
pcilib_register_description_t *registers = pcilib_model[model].registers;
107
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
108
pcilib_register_description_t *registers = model_info->registers;
71
111
bank_id = pcilib_find_bank(ctx, bank);
77
bank_addr = pcilib_model[model].banks[bank_id].addr;
117
bank_addr = model_info->banks[bank_id].addr;
80
120
for (i = 0; registers[i].bits; i++) {
81
121
if ((!strcasecmp(registers[i].name, reg))&&((!bank)||(registers[i].bank == bank_addr))) return i;
124
if ((ctx->model_info.dma_api)&&(!ctx->dma_ctx)&&(pcilib_get_dma_info(ctx))) {
125
registers = model_info->registers;
127
for (; registers[i].bits; i++) {
128
if ((!strcasecmp(registers[i].name, reg))&&((!bank)||(registers[i].bank == bank_addr))) return i;
84
132
return (pcilib_register_t)-1;
87
static int pcilib_read_register_space_internal(pcilib_t *ctx, pcilib_register_bank_t bank, pcilib_register_addr_t addr, size_t n, uint8_t bits, pcilib_register_value_t *buf) {
135
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) {
92
pcilib_model_t model = pcilib_get_model(ctx);
93
pcilib_register_bank_description_t *b = pcilib_model[model].banks + bank;
140
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
141
pcilib_register_bank_description_t *b = model_info->banks + bank;
95
143
assert(bits < 8 * sizeof(pcilib_register_value_t));
97
145
if (((addr + n) > b->size)||(((addr + n) == b->size)&&(bits))) {
98
pcilib_error("Accessing sregister (%u regs at addr %u) out of register space (%u registers total)", bits?(n+1):n, addr, b->size);
146
pcilib_error("Accessing register (%u regs at addr %u) out of register space (%u registers total)", bits?(n+1):n, addr, b->size);
99
147
return PCILIB_ERROR_OUTOFRANGE;
109
157
//bits %= b->access;
111
159
for (i = 0; i < n; i++) {
112
err = pcilib_protocol[b->protocol].read(ctx, b, addr + i, b->access, buf + i);
160
err = pcilib_protocol[b->protocol].read(ctx, b, addr + i, buf + i);
116
if ((bits > 0)&&(!err)) err = pcilib_protocol[b->protocol].read(ctx, b, addr + n, bits, buf + n);
164
if ((bits > 0)&&(!err)) {
165
pcilib_register_value_t val = 0;
166
err = pcilib_protocol[b->protocol].read(ctx, b, addr + n, &val);
168
val = (val >> offset)&BIT_MASK(bits);
169
memcpy(buf + n, &val, sizeof(pcilib_register_value_t));
126
180
return PCILIB_ERROR_INVALID_BANK;
129
return pcilib_read_register_space_internal(ctx, bank_id, addr, n, 0, buf);
183
return pcilib_read_register_space_internal(ctx, bank_id, addr, n, 0, 0, buf);
132
186
int pcilib_read_register_by_id(pcilib_t *ctx, pcilib_register_t reg, pcilib_register_value_t *value) {
189
pcilib_register_size_t bits;
135
190
pcilib_register_value_t res;
191
pcilib_register_bank_t bank;
136
192
pcilib_register_description_t *r;
137
193
pcilib_register_bank_description_t *b;
138
pcilib_model_t model = pcilib_get_model(ctx);
194
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
140
r = pcilib_model[model].registers + reg;
141
b = pcilib_model[model].banks + r->bank;
196
r = model_info->registers + reg;
198
bank = pcilib_find_bank_by_addr(ctx, r->bank);
199
if (bank == PCILIB_REGISTER_BANK_INVALID) return PCILIB_ERROR_INVALID_BANK;
201
b = model_info->banks + bank;
143
203
n = r->bits / b->access;
144
204
bits = r->bits % b->access;
146
206
pcilib_register_value_t buf[n + 1];
147
err = pcilib_read_register_space_internal(ctx, r->bank, r->addr, n, bits, buf);
207
err = pcilib_read_register_space_internal(ctx, bank, r->addr, n, r->offset, bits, buf);
149
209
if ((b->endianess == PCILIB_BIG_ENDIAN)||((b->endianess == PCILIB_HOST_ENDIAN)&&(ntohs(1) == 1))) {
150
210
pcilib_error("Big-endian byte order support is not implemented");
176
236
return pcilib_read_register_by_id(ctx, reg, value);
178
// registers[reg].bank
179
// printf("%li %li", sizeof(pcilib_model[model].banks), sizeof(pcilib_register_bank_description_t));
183
static int pcilib_write_register_space_internal(pcilib_t *ctx, pcilib_register_bank_t bank, pcilib_register_addr_t addr, size_t n, uint8_t bits, pcilib_register_value_t *buf) {
240
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) {
188
pcilib_model_t model = pcilib_get_model(ctx);
189
pcilib_register_bank_description_t *b = pcilib_model[model].banks + bank;
245
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
246
pcilib_register_bank_description_t *b = model_info->banks + bank;
191
248
assert(bits < 8 * sizeof(pcilib_register_value_t));
193
250
if (((addr + n) > b->size)||(((addr + n) == b->size)&&(bits))) {
194
pcilib_error("Accessing sregister (%u regs at addr %u) out of register space (%u registers total)", bits?(n+1):n, addr, b->size);
251
pcilib_error("Accessing register (%u regs at addr %u) out of register space (%u registers total)", bits?(n+1):n, addr, b->size);
195
252
return PCILIB_ERROR_OUTOFRANGE;
205
262
//bits %= b->access;
207
264
for (i = 0; i < n; i++) {
208
err = pcilib_protocol[b->protocol].write(ctx, b, addr + i, b->access, buf[i]);
265
err = pcilib_protocol[b->protocol].write(ctx, b, addr + i, buf[i]);
212
if ((bits > 0)&&(!err)) err = pcilib_protocol[b->protocol].write(ctx, b, addr + n, bits, buf[n]);
269
if ((bits > 0)&&(!err)) {
270
pcilib_register_value_t val = (buf[n]&BIT_MASK(bits))<<offset;
271
pcilib_register_value_t mask = BIT_MASK(bits)<<offset;
274
pcilib_register_value_t rval;
276
err = pcilib_protocol[b->protocol].read(ctx, b, addr + n, &rval);
279
val |= (rval & rwmask & ~mask);
282
err = pcilib_protocol[b->protocol].write(ctx, b, addr + n, val);
222
293
return PCILIB_ERROR_INVALID_BANK;
225
return pcilib_write_register_space_internal(ctx, bank_id, addr, n, 0, buf);
296
return pcilib_write_register_space_internal(ctx, bank_id, addr, n, 0, 0, 0, buf);
229
300
int pcilib_write_register_by_id(pcilib_t *ctx, pcilib_register_t reg, pcilib_register_value_t value) {
303
pcilib_register_size_t bits;
304
pcilib_register_bank_t bank;
232
305
pcilib_register_value_t res;
233
306
pcilib_register_description_t *r;
234
307
pcilib_register_bank_description_t *b;
235
pcilib_model_t model = pcilib_get_model(ctx);
237
r = pcilib_model[model].registers + reg;
238
b = pcilib_model[model].banks + r->bank;
308
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
310
r = model_info->registers + reg;
312
bank = pcilib_find_bank_by_addr(ctx, r->bank);
313
if (bank == PCILIB_REGISTER_BANK_INVALID) return PCILIB_ERROR_INVALID_BANK;
315
b = model_info->banks + bank;
240
317
n = r->bits / b->access;
241
318
bits = r->bits % b->access;
265
err = pcilib_write_register_space_internal(ctx, r->bank, r->addr, n, bits, buf);
342
err = pcilib_write_register_space_internal(ctx, bank, r->addr, n, r->offset, bits, r->rwmask, buf);