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