1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include <linux/types.h>
24
25
26#include <dspbridge/host_os.h>
27#include <linux/fs.h>
28#include <linux/uaccess.h>
29
30
31#include <dspbridge/dbdefs.h>
32
33
34#include <dspbridge/dbc.h>
35
36
37
38#include <dspbridge/dbll.h>
39
40
41#include <dspbridge/cod.h>
42
43
44
45
46struct cod_manager {
47 struct dbll_tar_obj *target;
48 struct dbll_library_obj *base_lib;
49 bool loaded;
50 u32 entry;
51 struct dbll_fxns fxns;
52 struct dbll_attrs attrs;
53 char sz_zl_file[COD_MAXPATHLENGTH];
54};
55
56
57
58
59struct cod_libraryobj {
60 struct dbll_library_obj *dbll_lib;
61 struct cod_manager *cod_mgr;
62};
63
64static u32 refs = 0L;
65
66static struct dbll_fxns ldr_fxns = {
67 (dbll_close_fxn) dbll_close,
68 (dbll_create_fxn) dbll_create,
69 (dbll_delete_fxn) dbll_delete,
70 (dbll_exit_fxn) dbll_exit,
71 (dbll_get_attrs_fxn) dbll_get_attrs,
72 (dbll_get_addr_fxn) dbll_get_addr,
73 (dbll_get_c_addr_fxn) dbll_get_c_addr,
74 (dbll_get_sect_fxn) dbll_get_sect,
75 (dbll_init_fxn) dbll_init,
76 (dbll_load_fxn) dbll_load,
77 (dbll_open_fxn) dbll_open,
78 (dbll_read_sect_fxn) dbll_read_sect,
79 (dbll_unload_fxn) dbll_unload,
80};
81
82static bool no_op(void);
83
84
85
86
87static s32 cod_f_close(struct file *filp)
88{
89
90 if (!filp)
91 return -EFAULT;
92
93 filp_close(filp, NULL);
94
95
96 return 0;
97}
98
99static struct file *cod_f_open(const char *psz_file_name, const char *sz_mode)
100{
101 mm_segment_t fs;
102 struct file *filp;
103
104 fs = get_fs();
105 set_fs(get_ds());
106
107
108 filp = filp_open(psz_file_name, O_RDONLY, 0);
109
110 if (IS_ERR(filp))
111 filp = NULL;
112
113 set_fs(fs);
114
115 return filp;
116}
117
118static s32 cod_f_read(void __user *pbuffer, s32 size, s32 count,
119 struct file *filp)
120{
121
122 if (!filp)
123 return -EFAULT;
124
125 if ((size > 0) && (count > 0) && pbuffer) {
126 u32 dw_bytes_read;
127 mm_segment_t fs;
128
129
130 fs = get_fs();
131 set_fs(get_ds());
132 dw_bytes_read = filp->f_op->read(filp, pbuffer, size * count,
133 &(filp->f_pos));
134 set_fs(fs);
135
136 if (!dw_bytes_read)
137 return -EBADF;
138
139 return dw_bytes_read / size;
140 }
141
142 return -EINVAL;
143}
144
145static s32 cod_f_seek(struct file *filp, s32 offset, s32 origin)
146{
147 loff_t dw_cur_pos;
148
149
150 if (!filp)
151 return -EFAULT;
152
153
154 dw_cur_pos = filp->f_op->llseek(filp, offset, origin);
155
156 if ((s32) dw_cur_pos < 0)
157 return -EPERM;
158
159
160 return 0;
161}
162
163static s32 cod_f_tell(struct file *filp)
164{
165 loff_t dw_cur_pos;
166
167 if (!filp)
168 return -EFAULT;
169
170
171 dw_cur_pos = filp->f_op->llseek(filp, 0, SEEK_CUR);
172
173 if ((s32) dw_cur_pos < 0)
174 return -EPERM;
175
176 return dw_cur_pos;
177}
178
179
180
181
182void cod_close(struct cod_libraryobj *lib)
183{
184 struct cod_manager *hmgr;
185
186 DBC_REQUIRE(refs > 0);
187 DBC_REQUIRE(lib != NULL);
188 DBC_REQUIRE(lib->cod_mgr);
189
190 hmgr = lib->cod_mgr;
191 hmgr->fxns.close_fxn(lib->dbll_lib);
192
193 kfree(lib);
194}
195
196
197
198
199
200
201
202
203
204
205int cod_create(struct cod_manager **mgr, char *str_zl_file)
206{
207 struct cod_manager *mgr_new;
208 struct dbll_attrs zl_attrs;
209 int status = 0;
210
211 DBC_REQUIRE(refs > 0);
212 DBC_REQUIRE(mgr != NULL);
213
214
215 *mgr = NULL;
216
217 mgr_new = kzalloc(sizeof(struct cod_manager), GFP_KERNEL);
218 if (mgr_new == NULL)
219 return -ENOMEM;
220
221
222 mgr_new->fxns = ldr_fxns;
223
224
225 mgr_new->fxns.init_fxn();
226
227 zl_attrs.alloc = (dbll_alloc_fxn) no_op;
228 zl_attrs.free = (dbll_free_fxn) no_op;
229 zl_attrs.fread = (dbll_read_fxn) cod_f_read;
230 zl_attrs.fseek = (dbll_seek_fxn) cod_f_seek;
231 zl_attrs.ftell = (dbll_tell_fxn) cod_f_tell;
232 zl_attrs.fclose = (dbll_f_close_fxn) cod_f_close;
233 zl_attrs.fopen = (dbll_f_open_fxn) cod_f_open;
234 zl_attrs.sym_lookup = NULL;
235 zl_attrs.base_image = true;
236 zl_attrs.log_write = NULL;
237 zl_attrs.log_write_handle = NULL;
238 zl_attrs.write = NULL;
239 zl_attrs.rmm_handle = NULL;
240 zl_attrs.input_params = NULL;
241 zl_attrs.sym_handle = NULL;
242 zl_attrs.sym_arg = NULL;
243
244 mgr_new->attrs = zl_attrs;
245
246 status = mgr_new->fxns.create_fxn(&mgr_new->target, &zl_attrs);
247
248 if (status) {
249 cod_delete(mgr_new);
250 return -ESPIPE;
251 }
252
253
254 *mgr = mgr_new;
255
256 return 0;
257}
258
259
260
261
262
263
264void cod_delete(struct cod_manager *cod_mgr_obj)
265{
266 DBC_REQUIRE(refs > 0);
267 DBC_REQUIRE(cod_mgr_obj);
268
269 if (cod_mgr_obj->base_lib) {
270 if (cod_mgr_obj->loaded)
271 cod_mgr_obj->fxns.unload_fxn(cod_mgr_obj->base_lib,
272 &cod_mgr_obj->attrs);
273
274 cod_mgr_obj->fxns.close_fxn(cod_mgr_obj->base_lib);
275 }
276 if (cod_mgr_obj->target) {
277 cod_mgr_obj->fxns.delete_fxn(cod_mgr_obj->target);
278 cod_mgr_obj->fxns.exit_fxn();
279 }
280 kfree(cod_mgr_obj);
281}
282
283
284
285
286
287
288
289void cod_exit(void)
290{
291 DBC_REQUIRE(refs > 0);
292
293 refs--;
294
295 DBC_ENSURE(refs >= 0);
296}
297
298
299
300
301
302
303int cod_get_base_lib(struct cod_manager *cod_mgr_obj,
304 struct dbll_library_obj **plib)
305{
306 int status = 0;
307
308 DBC_REQUIRE(refs > 0);
309 DBC_REQUIRE(cod_mgr_obj);
310 DBC_REQUIRE(plib != NULL);
311
312 *plib = (struct dbll_library_obj *)cod_mgr_obj->base_lib;
313
314 return status;
315}
316
317
318
319
320int cod_get_base_name(struct cod_manager *cod_mgr_obj, char *sz_name,
321 u32 usize)
322{
323 int status = 0;
324
325 DBC_REQUIRE(refs > 0);
326 DBC_REQUIRE(cod_mgr_obj);
327 DBC_REQUIRE(sz_name != NULL);
328
329 if (usize <= COD_MAXPATHLENGTH)
330 strncpy(sz_name, cod_mgr_obj->sz_zl_file, usize);
331 else
332 status = -EPERM;
333
334 return status;
335}
336
337
338
339
340
341
342
343int cod_get_entry(struct cod_manager *cod_mgr_obj, u32 *entry_pt)
344{
345 DBC_REQUIRE(refs > 0);
346 DBC_REQUIRE(cod_mgr_obj);
347 DBC_REQUIRE(entry_pt != NULL);
348
349 *entry_pt = cod_mgr_obj->entry;
350
351 return 0;
352}
353
354
355
356
357
358
359int cod_get_loader(struct cod_manager *cod_mgr_obj,
360 struct dbll_tar_obj **loader)
361{
362 int status = 0;
363
364 DBC_REQUIRE(refs > 0);
365 DBC_REQUIRE(cod_mgr_obj);
366 DBC_REQUIRE(loader != NULL);
367
368 *loader = (struct dbll_tar_obj *)cod_mgr_obj->target;
369
370 return status;
371}
372
373
374
375
376
377
378
379int cod_get_section(struct cod_libraryobj *lib, char *str_sect,
380 u32 *addr, u32 *len)
381{
382 struct cod_manager *cod_mgr_obj;
383 int status = 0;
384
385 DBC_REQUIRE(refs > 0);
386 DBC_REQUIRE(lib != NULL);
387 DBC_REQUIRE(lib->cod_mgr);
388 DBC_REQUIRE(str_sect != NULL);
389 DBC_REQUIRE(addr != NULL);
390 DBC_REQUIRE(len != NULL);
391
392 *addr = 0;
393 *len = 0;
394 if (lib != NULL) {
395 cod_mgr_obj = lib->cod_mgr;
396 status = cod_mgr_obj->fxns.get_sect_fxn(lib->dbll_lib, str_sect,
397 addr, len);
398 } else {
399 status = -ESPIPE;
400 }
401
402 DBC_ENSURE(!status || ((*addr == 0) && (*len == 0)));
403
404 return status;
405}
406
407
408
409
410
411
412
413
414
415int cod_get_sym_value(struct cod_manager *cod_mgr_obj, char *str_sym,
416 u32 *pul_value)
417{
418 struct dbll_sym_val *dbll_sym;
419
420 DBC_REQUIRE(refs > 0);
421 DBC_REQUIRE(cod_mgr_obj);
422 DBC_REQUIRE(str_sym != NULL);
423 DBC_REQUIRE(pul_value != NULL);
424
425 dev_dbg(bridge, "%s: cod_mgr_obj: %p str_sym: %s pul_value: %p\n",
426 __func__, cod_mgr_obj, str_sym, pul_value);
427 if (cod_mgr_obj->base_lib) {
428 if (!cod_mgr_obj->fxns.
429 get_addr_fxn(cod_mgr_obj->base_lib, str_sym, &dbll_sym)) {
430 if (!cod_mgr_obj->fxns.
431 get_c_addr_fxn(cod_mgr_obj->base_lib, str_sym,
432 &dbll_sym))
433 return -ESPIPE;
434 }
435 } else {
436 return -ESPIPE;
437 }
438
439 *pul_value = dbll_sym->value;
440
441 return 0;
442}
443
444
445
446
447
448
449
450bool cod_init(void)
451{
452 bool ret = true;
453
454 DBC_REQUIRE(refs >= 0);
455
456 if (ret)
457 refs++;
458
459 DBC_ENSURE((ret && refs > 0) || (!ret && refs >= 0));
460 return ret;
461}
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476int cod_load_base(struct cod_manager *cod_mgr_obj, u32 num_argc, char *args[],
477 cod_writefxn pfn_write, void *arb, char *envp[])
478{
479 dbll_flags flags;
480 struct dbll_attrs save_attrs;
481 struct dbll_attrs new_attrs;
482 int status;
483 u32 i;
484
485 DBC_REQUIRE(refs > 0);
486 DBC_REQUIRE(cod_mgr_obj);
487 DBC_REQUIRE(num_argc > 0);
488 DBC_REQUIRE(args != NULL);
489 DBC_REQUIRE(args[0] != NULL);
490 DBC_REQUIRE(pfn_write != NULL);
491 DBC_REQUIRE(cod_mgr_obj->base_lib != NULL);
492
493
494
495
496
497 for (i = 0; i < num_argc; i++) {
498 if (args[i] == NULL) {
499 num_argc = i;
500 break;
501 }
502 }
503
504
505 cod_mgr_obj->fxns.get_attrs_fxn(cod_mgr_obj->target, &save_attrs);
506
507 new_attrs = save_attrs;
508 new_attrs.write = (dbll_write_fxn) pfn_write;
509 new_attrs.input_params = arb;
510 new_attrs.alloc = (dbll_alloc_fxn) no_op;
511 new_attrs.free = (dbll_free_fxn) no_op;
512 new_attrs.log_write = NULL;
513 new_attrs.log_write_handle = NULL;
514
515
516 flags = DBLL_CODE | DBLL_DATA | DBLL_SYMB;
517 status = cod_mgr_obj->fxns.load_fxn(cod_mgr_obj->base_lib, flags,
518 &new_attrs,
519 &cod_mgr_obj->entry);
520 if (status)
521 cod_mgr_obj->fxns.close_fxn(cod_mgr_obj->base_lib);
522
523 if (!status)
524 cod_mgr_obj->loaded = true;
525 else
526 cod_mgr_obj->base_lib = NULL;
527
528 return status;
529}
530
531
532
533
534
535int cod_open(struct cod_manager *hmgr, char *sz_coff_path,
536 u32 flags, struct cod_libraryobj **lib_obj)
537{
538 int status = 0;
539 struct cod_libraryobj *lib = NULL;
540
541 DBC_REQUIRE(refs > 0);
542 DBC_REQUIRE(hmgr);
543 DBC_REQUIRE(sz_coff_path != NULL);
544 DBC_REQUIRE(flags == COD_NOLOAD || flags == COD_SYMB);
545 DBC_REQUIRE(lib_obj != NULL);
546
547 *lib_obj = NULL;
548
549 lib = kzalloc(sizeof(struct cod_libraryobj), GFP_KERNEL);
550 if (lib == NULL)
551 status = -ENOMEM;
552
553 if (!status) {
554 lib->cod_mgr = hmgr;
555 status = hmgr->fxns.open_fxn(hmgr->target, sz_coff_path, flags,
556 &lib->dbll_lib);
557 if (!status)
558 *lib_obj = lib;
559 }
560
561 if (status)
562 pr_err("%s: error status 0x%x, sz_coff_path: %s flags: 0x%x\n",
563 __func__, status, sz_coff_path, flags);
564 return status;
565}
566
567
568
569
570
571
572int cod_open_base(struct cod_manager *hmgr, char *sz_coff_path,
573 dbll_flags flags)
574{
575 int status = 0;
576 struct dbll_library_obj *lib;
577
578 DBC_REQUIRE(refs > 0);
579 DBC_REQUIRE(hmgr);
580 DBC_REQUIRE(sz_coff_path != NULL);
581
582
583 if (hmgr->base_lib) {
584 if (hmgr->loaded) {
585 hmgr->fxns.unload_fxn(hmgr->base_lib, &hmgr->attrs);
586 hmgr->loaded = false;
587 }
588 hmgr->fxns.close_fxn(hmgr->base_lib);
589 hmgr->base_lib = NULL;
590 }
591 status = hmgr->fxns.open_fxn(hmgr->target, sz_coff_path, flags, &lib);
592 if (!status) {
593
594 hmgr->base_lib = lib;
595 strncpy(hmgr->sz_zl_file, sz_coff_path, COD_MAXPATHLENGTH - 1);
596 hmgr->sz_zl_file[COD_MAXPATHLENGTH - 1] = '\0';
597 }
598
599 if (status)
600 pr_err("%s: error status 0x%x sz_coff_path: %s\n", __func__,
601 status, sz_coff_path);
602 return status;
603}
604
605
606
607
608
609
610int cod_read_section(struct cod_libraryobj *lib, char *str_sect,
611 char *str_content, u32 content_size)
612{
613 int status = 0;
614
615 DBC_REQUIRE(refs > 0);
616 DBC_REQUIRE(lib != NULL);
617 DBC_REQUIRE(lib->cod_mgr);
618 DBC_REQUIRE(str_sect != NULL);
619 DBC_REQUIRE(str_content != NULL);
620
621 if (lib != NULL)
622 status =
623 lib->cod_mgr->fxns.read_sect_fxn(lib->dbll_lib, str_sect,
624 str_content, content_size);
625 else
626 status = -ESPIPE;
627
628 return status;
629}
630
631
632
633
634
635
636
637static bool no_op(void)
638{
639 return true;
640}
641