1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include <linux/types.h>
26
27
28#include <dspbridge/host_os.h>
29
30
31#include <dspbridge/dbdefs.h>
32
33
34#include <dspbridge/cod.h>
35
36
37#include <dspbridge/uuidutil.h>
38
39
40#include <dspbridge/dbdcd.h>
41
42
43#define MAX_INT2CHAR_LENGTH 16
44
45
46#define DEPLIBSECT ".dspbridge_deplibs"
47
48
49struct dcd_manager {
50 struct cod_manager *cod_mgr;
51};
52
53
54static struct list_head reg_key_list;
55static DEFINE_SPINLOCK(dbdcd_lock);
56
57
58static u32 refs;
59static u32 enum_refs;
60
61
62static s32 atoi(char *psz_buf);
63static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size,
64 enum dsp_dcdobjtype obj_type,
65 struct dcd_genericobj *gen_obj);
66static void compress_buf(char *psz_buf, u32 ul_buf_size, s32 char_size);
67static char dsp_char2_gpp_char(char *word, s32 dsp_char_size);
68static int get_dep_lib_info(struct dcd_manager *hdcd_mgr,
69 struct dsp_uuid *uuid_obj,
70 u16 *num_libs,
71 u16 *num_pers_libs,
72 struct dsp_uuid *dep_lib_uuids,
73 bool *prstnt_dep_libs,
74 enum nldr_phase phase);
75
76
77
78
79
80
81int dcd_auto_register(struct dcd_manager *hdcd_mgr,
82 char *sz_coff_path)
83{
84 int status = 0;
85
86 if (hdcd_mgr)
87 status = dcd_get_objects(hdcd_mgr, sz_coff_path,
88 (dcd_registerfxn) dcd_register_object,
89 (void *)sz_coff_path);
90 else
91 status = -EFAULT;
92
93 return status;
94}
95
96
97
98
99
100
101int dcd_auto_unregister(struct dcd_manager *hdcd_mgr,
102 char *sz_coff_path)
103{
104 int status = 0;
105
106 if (hdcd_mgr)
107 status = dcd_get_objects(hdcd_mgr, sz_coff_path,
108 (dcd_registerfxn) dcd_register_object,
109 NULL);
110 else
111 status = -EFAULT;
112
113 return status;
114}
115
116
117
118
119
120
121int dcd_create_manager(char *sz_zl_dll_name,
122 struct dcd_manager **dcd_mgr)
123{
124 struct cod_manager *cod_mgr;
125 struct dcd_manager *dcd_mgr_obj = NULL;
126 int status = 0;
127
128 status = cod_create(&cod_mgr, sz_zl_dll_name);
129 if (status)
130 goto func_end;
131
132
133 dcd_mgr_obj = kzalloc(sizeof(struct dcd_manager), GFP_KERNEL);
134 if (dcd_mgr_obj != NULL) {
135
136 dcd_mgr_obj->cod_mgr = cod_mgr;
137
138
139 *dcd_mgr = dcd_mgr_obj;
140 } else {
141 status = -ENOMEM;
142
143
144
145
146
147 cod_delete(cod_mgr);
148 }
149
150func_end:
151 return status;
152}
153
154
155
156
157
158
159int dcd_destroy_manager(struct dcd_manager *hdcd_mgr)
160{
161 struct dcd_manager *dcd_mgr_obj = hdcd_mgr;
162 int status = -EFAULT;
163
164 if (hdcd_mgr) {
165
166 cod_delete(dcd_mgr_obj->cod_mgr);
167
168
169 kfree(dcd_mgr_obj);
170
171 status = 0;
172 }
173
174 return status;
175}
176
177
178
179
180
181
182int dcd_enumerate_object(s32 index, enum dsp_dcdobjtype obj_type,
183 struct dsp_uuid *uuid_obj)
184{
185 int status = 0;
186 char sz_reg_key[DCD_MAXPATHLENGTH];
187 char sz_value[DCD_MAXPATHLENGTH];
188 struct dsp_uuid dsp_uuid_obj;
189 char sz_obj_type[MAX_INT2CHAR_LENGTH];
190 u32 dw_key_len = 0;
191 struct dcd_key_elem *dcd_key;
192 int len;
193
194 if ((index != 0) && (enum_refs == 0)) {
195
196
197
198
199
200 status = -EIDRM;
201 } else {
202
203
204
205
206 dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1;
207
208
209
210 strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
211 if ((strlen(sz_reg_key) + strlen("_\0")) <
212 DCD_MAXPATHLENGTH) {
213 strncat(sz_reg_key, "_\0", 2);
214 } else {
215 status = -EPERM;
216 }
217
218
219
220 status = snprintf(sz_obj_type, MAX_INT2CHAR_LENGTH, "%d",
221 obj_type);
222
223 if (status == -1) {
224 status = -EPERM;
225 } else {
226 status = 0;
227 if ((strlen(sz_reg_key) + strlen(sz_obj_type)) <
228 DCD_MAXPATHLENGTH) {
229 strncat(sz_reg_key, sz_obj_type,
230 strlen(sz_obj_type) + 1);
231 } else {
232 status = -EPERM;
233 }
234 }
235
236 if (!status) {
237 len = strlen(sz_reg_key);
238 spin_lock(&dbdcd_lock);
239 list_for_each_entry(dcd_key, ®_key_list, link) {
240 if (!strncmp(dcd_key->name, sz_reg_key, len)
241 && !index--) {
242 strncpy(sz_value, &dcd_key->name[len],
243 strlen(&dcd_key->name[len]) + 1);
244 break;
245 }
246 }
247 spin_unlock(&dbdcd_lock);
248
249 if (&dcd_key->link == ®_key_list)
250 status = -ENODATA;
251 }
252
253 if (!status) {
254
255
256 uuid_uuid_from_string(sz_value, &dsp_uuid_obj);
257
258 *uuid_obj = dsp_uuid_obj;
259
260
261 enum_refs++;
262
263 status = 0;
264 } else if (status == -ENODATA) {
265
266 enum_refs = 0;
267
268
269
270
271
272 status = ENODATA;
273 } else {
274 status = -EPERM;
275 }
276 }
277
278 return status;
279}
280
281
282
283
284
285
286void dcd_exit(void)
287{
288 struct dcd_key_elem *rv, *rv_tmp;
289
290 refs--;
291 if (refs == 0) {
292 list_for_each_entry_safe(rv, rv_tmp, ®_key_list, link) {
293 list_del(&rv->link);
294 kfree(rv->path);
295 kfree(rv);
296 }
297 }
298
299}
300
301
302
303
304int dcd_get_dep_libs(struct dcd_manager *hdcd_mgr,
305 struct dsp_uuid *uuid_obj,
306 u16 num_libs, struct dsp_uuid *dep_lib_uuids,
307 bool *prstnt_dep_libs,
308 enum nldr_phase phase)
309{
310 int status = 0;
311
312 status =
313 get_dep_lib_info(hdcd_mgr, uuid_obj, &num_libs, NULL, dep_lib_uuids,
314 prstnt_dep_libs, phase);
315
316 return status;
317}
318
319
320
321
322int dcd_get_num_dep_libs(struct dcd_manager *hdcd_mgr,
323 struct dsp_uuid *uuid_obj,
324 u16 *num_libs, u16 *num_pers_libs,
325 enum nldr_phase phase)
326{
327 int status = 0;
328
329 status = get_dep_lib_info(hdcd_mgr, uuid_obj, num_libs, num_pers_libs,
330 NULL, NULL, phase);
331
332 return status;
333}
334
335
336
337
338
339
340
341int dcd_get_object_def(struct dcd_manager *hdcd_mgr,
342 struct dsp_uuid *obj_uuid,
343 enum dsp_dcdobjtype obj_type,
344 struct dcd_genericobj *obj_def)
345{
346 struct dcd_manager *dcd_mgr_obj = hdcd_mgr;
347 struct cod_libraryobj *lib = NULL;
348 int status = 0;
349 int len;
350 u32 ul_addr = 0;
351 u32 ul_len = 0;
352 u32 dw_buf_size;
353 char sz_reg_key[DCD_MAXPATHLENGTH];
354 char *sz_uuid;
355 char *tmp;
356 struct dcd_key_elem *dcd_key = NULL;
357 char sz_sect_name[MAXUUIDLEN + 2];
358 char *psz_coff_buf;
359 u32 dw_key_len;
360 char sz_obj_type[MAX_INT2CHAR_LENGTH];
361
362 sz_uuid = kzalloc(MAXUUIDLEN, GFP_KERNEL);
363 if (!sz_uuid) {
364 status = -ENOMEM;
365 goto func_end;
366 }
367
368 if (!hdcd_mgr) {
369 status = -EFAULT;
370 goto func_end;
371 }
372
373
374
375 dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1;
376
377
378 strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
379
380 if ((strlen(sz_reg_key) + strlen("_\0")) < DCD_MAXPATHLENGTH)
381 strncat(sz_reg_key, "_\0", 2);
382 else
383 status = -EPERM;
384
385 status = snprintf(sz_obj_type, MAX_INT2CHAR_LENGTH, "%d", obj_type);
386 if (status == -1) {
387 status = -EPERM;
388 } else {
389 status = 0;
390
391 if ((strlen(sz_reg_key) + strlen(sz_obj_type)) <
392 DCD_MAXPATHLENGTH) {
393 strncat(sz_reg_key, sz_obj_type,
394 strlen(sz_obj_type) + 1);
395 } else {
396 status = -EPERM;
397 }
398
399
400 snprintf(sz_uuid, MAXUUIDLEN, "%pUL", obj_uuid);
401
402 if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH)
403 strncat(sz_reg_key, sz_uuid, MAXUUIDLEN);
404 else
405 status = -EPERM;
406
407
408 dw_buf_size = DCD_MAXPATHLENGTH;
409 }
410 if (!status) {
411 spin_lock(&dbdcd_lock);
412 list_for_each_entry(dcd_key, ®_key_list, link) {
413 if (!strncmp(dcd_key->name, sz_reg_key,
414 strlen(sz_reg_key) + 1))
415 break;
416 }
417 spin_unlock(&dbdcd_lock);
418 if (&dcd_key->link == ®_key_list) {
419 status = -ENOKEY;
420 goto func_end;
421 }
422 }
423
424
425
426 status = cod_open(dcd_mgr_obj->cod_mgr, dcd_key->path,
427 COD_NOLOAD, &lib);
428 if (status) {
429 status = -EACCES;
430 goto func_end;
431 }
432
433
434 len = strlen(sz_uuid);
435 if (len + 1 > sizeof(sz_sect_name)) {
436 status = -EPERM;
437 goto func_end;
438 }
439
440
441
442
443
444 len -= 4;
445 tmp = sz_uuid;
446
447 strncpy(sz_sect_name, ".", 2);
448 do {
449 char *uuid = strsep(&tmp, "-");
450 if (!uuid)
451 break;
452 len -= strlen(uuid);
453 strncat(sz_sect_name, uuid, strlen(uuid) + 1);
454 } while (len && strncat(sz_sect_name, "_", 2));
455
456
457 status = cod_get_section(lib, sz_sect_name, &ul_addr, &ul_len);
458 if (status) {
459 status = -EACCES;
460 goto func_end;
461 }
462
463
464 psz_coff_buf = kzalloc(ul_len + 4, GFP_KERNEL);
465 if (psz_coff_buf == NULL) {
466 status = -ENOMEM;
467 goto func_end;
468 }
469#ifdef _DB_TIOMAP
470 if (strstr(dcd_key->path, "iva") == NULL) {
471
472 status =
473 cod_read_section(lib, sz_sect_name, psz_coff_buf, ul_len);
474 } else {
475 status =
476 cod_read_section(lib, sz_sect_name, psz_coff_buf, ul_len);
477 dev_dbg(bridge, "%s: Skipped Byte swap for IVA!!\n", __func__);
478 }
479#else
480 status = cod_read_section(lib, sz_sect_name, psz_coff_buf, ul_len);
481#endif
482 if (!status) {
483
484 if (strstr(dcd_key->path, "iva") == NULL) {
485 compress_buf(psz_coff_buf, ul_len, DSPWORDSIZE);
486 } else {
487 compress_buf(psz_coff_buf, ul_len, 1);
488 dev_dbg(bridge, "%s: Compressing IVA COFF buffer by 1 "
489 "for IVA!!\n", __func__);
490 }
491
492
493 status =
494 get_attrs_from_buf(psz_coff_buf, ul_len, obj_type, obj_def);
495 if (status)
496 status = -EACCES;
497 } else {
498 status = -EACCES;
499 }
500
501
502 kfree(psz_coff_buf);
503func_end:
504 if (lib)
505 cod_close(lib);
506
507 kfree(sz_uuid);
508
509 return status;
510}
511
512
513
514
515int dcd_get_objects(struct dcd_manager *hdcd_mgr,
516 char *sz_coff_path, dcd_registerfxn register_fxn,
517 void *handle)
518{
519 struct dcd_manager *dcd_mgr_obj = hdcd_mgr;
520 int status = 0;
521 char *psz_coff_buf;
522 char *psz_cur;
523 struct cod_libraryobj *lib = NULL;
524 u32 ul_addr = 0;
525 u32 ul_len = 0;
526 char seps[] = ":, ";
527 char *token = NULL;
528 struct dsp_uuid dsp_uuid_obj;
529 s32 object_type;
530
531 if (!hdcd_mgr) {
532 status = -EFAULT;
533 goto func_end;
534 }
535
536
537 status = cod_open(dcd_mgr_obj->cod_mgr, sz_coff_path, COD_NOLOAD, &lib);
538 if (status) {
539 status = -EACCES;
540 goto func_cont;
541 }
542
543
544 status = cod_get_section(lib, DCD_REGISTER_SECTION, &ul_addr, &ul_len);
545 if (status || !(ul_len > 0)) {
546 status = -EACCES;
547 goto func_cont;
548 }
549
550
551 psz_coff_buf = kzalloc(ul_len + 4, GFP_KERNEL);
552 if (psz_coff_buf == NULL) {
553 status = -ENOMEM;
554 goto func_cont;
555 }
556#ifdef _DB_TIOMAP
557 if (strstr(sz_coff_path, "iva") == NULL) {
558
559 status = cod_read_section(lib, DCD_REGISTER_SECTION,
560 psz_coff_buf, ul_len);
561 } else {
562 dev_dbg(bridge, "%s: Skipped Byte swap for IVA!!\n", __func__);
563 status = cod_read_section(lib, DCD_REGISTER_SECTION,
564 psz_coff_buf, ul_len);
565 }
566#else
567 status =
568 cod_read_section(lib, DCD_REGISTER_SECTION, psz_coff_buf, ul_len);
569#endif
570 if (!status) {
571
572 if (strstr(sz_coff_path, "iva") == NULL) {
573 compress_buf(psz_coff_buf, ul_len, DSPWORDSIZE);
574 } else {
575 compress_buf(psz_coff_buf, ul_len, 1);
576 dev_dbg(bridge, "%s: Compress COFF buffer with 1 word "
577 "for IVA!!\n", __func__);
578 }
579
580
581 psz_cur = psz_coff_buf;
582 while ((token = strsep(&psz_cur, seps)) && *token != '\0') {
583
584 uuid_uuid_from_string(token, &dsp_uuid_obj);
585
586
587 token = strsep(&psz_cur, seps);
588
589
590 object_type = atoi(token);
591
592
593
594
595
596
597
598
599
600 status =
601 register_fxn(&dsp_uuid_obj, object_type, handle);
602 if (status) {
603
604 break;
605 }
606 }
607 } else {
608 status = -EACCES;
609 }
610
611
612 kfree(psz_coff_buf);
613func_cont:
614 if (lib)
615 cod_close(lib);
616
617func_end:
618 return status;
619}
620
621
622
623
624
625
626
627int dcd_get_library_name(struct dcd_manager *hdcd_mgr,
628 struct dsp_uuid *uuid_obj,
629 char *str_lib_name,
630 u32 *buff_size,
631 enum nldr_phase phase, bool *phase_split)
632{
633 char sz_reg_key[DCD_MAXPATHLENGTH];
634 char sz_uuid[MAXUUIDLEN];
635 u32 dw_key_len;
636 char sz_obj_type[MAX_INT2CHAR_LENGTH];
637 int status = 0;
638 struct dcd_key_elem *dcd_key = NULL;
639
640 dev_dbg(bridge, "%s: hdcd_mgr %p, uuid_obj %p, str_lib_name %p,"
641 " buff_size %p\n", __func__, hdcd_mgr, uuid_obj, str_lib_name,
642 buff_size);
643
644
645
646
647
648 dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1;
649
650
651 strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
652 if ((strlen(sz_reg_key) + strlen("_\0")) < DCD_MAXPATHLENGTH)
653 strncat(sz_reg_key, "_\0", 2);
654 else
655 status = -EPERM;
656
657 switch (phase) {
658 case NLDR_CREATE:
659
660 sprintf(sz_obj_type, "%d", DSP_DCDCREATELIBTYPE);
661 break;
662 case NLDR_EXECUTE:
663
664 sprintf(sz_obj_type, "%d", DSP_DCDEXECUTELIBTYPE);
665 break;
666 case NLDR_DELETE:
667
668 sprintf(sz_obj_type, "%d", DSP_DCDDELETELIBTYPE);
669 break;
670 case NLDR_NOPHASE:
671
672 sprintf(sz_obj_type, "%d", DSP_DCDLIBRARYTYPE);
673 break;
674 default:
675 status = -EINVAL;
676 }
677 if (!status) {
678 if ((strlen(sz_reg_key) + strlen(sz_obj_type)) <
679 DCD_MAXPATHLENGTH) {
680 strncat(sz_reg_key, sz_obj_type,
681 strlen(sz_obj_type) + 1);
682 } else {
683 status = -EPERM;
684 }
685
686 snprintf(sz_uuid, MAXUUIDLEN, "%pUL", uuid_obj);
687 if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH)
688 strncat(sz_reg_key, sz_uuid, MAXUUIDLEN);
689 else
690 status = -EPERM;
691 }
692 if (!status) {
693 spin_lock(&dbdcd_lock);
694 list_for_each_entry(dcd_key, ®_key_list, link) {
695
696 if (!strncmp(dcd_key->name, sz_reg_key,
697 strlen(sz_reg_key) + 1))
698 break;
699 }
700 spin_unlock(&dbdcd_lock);
701 }
702
703 if (&dcd_key->link == ®_key_list)
704 status = -ENOKEY;
705
706
707 if (status && phase != NLDR_NOPHASE) {
708 if (phase_split)
709 *phase_split = false;
710
711 strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
712 if ((strlen(sz_reg_key) + strlen("_\0")) <
713 DCD_MAXPATHLENGTH) {
714 strncat(sz_reg_key, "_\0", 2);
715 } else {
716 status = -EPERM;
717 }
718 sprintf(sz_obj_type, "%d", DSP_DCDLIBRARYTYPE);
719 if ((strlen(sz_reg_key) + strlen(sz_obj_type))
720 < DCD_MAXPATHLENGTH) {
721 strncat(sz_reg_key, sz_obj_type,
722 strlen(sz_obj_type) + 1);
723 } else {
724 status = -EPERM;
725 }
726 snprintf(sz_uuid, MAXUUIDLEN, "%pUL", uuid_obj);
727 if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH)
728 strncat(sz_reg_key, sz_uuid, MAXUUIDLEN);
729 else
730 status = -EPERM;
731
732 spin_lock(&dbdcd_lock);
733 list_for_each_entry(dcd_key, ®_key_list, link) {
734
735 if (!strncmp(dcd_key->name, sz_reg_key,
736 strlen(sz_reg_key) + 1))
737 break;
738 }
739 spin_unlock(&dbdcd_lock);
740
741 status = (&dcd_key->link != ®_key_list) ?
742 0 : -ENOKEY;
743 }
744
745 if (!status)
746 memcpy(str_lib_name, dcd_key->path, strlen(dcd_key->path) + 1);
747 return status;
748}
749
750
751
752
753
754
755bool dcd_init(void)
756{
757 bool ret = true;
758
759 if (refs == 0)
760 INIT_LIST_HEAD(®_key_list);
761
762 if (ret)
763 refs++;
764
765 return ret;
766}
767
768
769
770
771
772
773
774int dcd_register_object(struct dsp_uuid *uuid_obj,
775 enum dsp_dcdobjtype obj_type,
776 char *psz_path_name)
777{
778 int status = 0;
779 char sz_reg_key[DCD_MAXPATHLENGTH];
780 char sz_uuid[MAXUUIDLEN + 1];
781 u32 dw_path_size = 0;
782 u32 dw_key_len;
783 char sz_obj_type[MAX_INT2CHAR_LENGTH];
784 struct dcd_key_elem *dcd_key = NULL;
785
786 dev_dbg(bridge, "%s: object UUID %p, obj_type %d, szPathName %s\n",
787 __func__, uuid_obj, obj_type, psz_path_name);
788
789
790
791
792
793 dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1;
794
795
796 strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
797 if ((strlen(sz_reg_key) + strlen("_\0")) < DCD_MAXPATHLENGTH)
798 strncat(sz_reg_key, "_\0", 2);
799 else {
800 status = -EPERM;
801 goto func_end;
802 }
803
804 status = snprintf(sz_obj_type, MAX_INT2CHAR_LENGTH, "%d", obj_type);
805 if (status == -1) {
806 status = -EPERM;
807 } else {
808 status = 0;
809 if ((strlen(sz_reg_key) + strlen(sz_obj_type)) <
810 DCD_MAXPATHLENGTH) {
811 strncat(sz_reg_key, sz_obj_type,
812 strlen(sz_obj_type) + 1);
813 } else
814 status = -EPERM;
815
816
817 snprintf(sz_uuid, MAXUUIDLEN, "%pUL", uuid_obj);
818 if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH)
819 strncat(sz_reg_key, sz_uuid, MAXUUIDLEN);
820 else
821 status = -EPERM;
822 }
823
824 if (status)
825 goto func_end;
826
827
828
829
830
831
832 if (psz_path_name) {
833 dw_path_size = strlen(psz_path_name) + 1;
834 spin_lock(&dbdcd_lock);
835 list_for_each_entry(dcd_key, ®_key_list, link) {
836
837 if (!strncmp(dcd_key->name, sz_reg_key,
838 strlen(sz_reg_key) + 1))
839 break;
840 }
841 spin_unlock(&dbdcd_lock);
842 if (&dcd_key->link == ®_key_list) {
843
844
845
846
847
848 dcd_key = kmalloc(sizeof(struct dcd_key_elem),
849 GFP_KERNEL);
850 if (!dcd_key) {
851 status = -ENOMEM;
852 goto func_end;
853 }
854
855 dcd_key->path = kmalloc(dw_path_size, GFP_KERNEL);
856
857 if (!dcd_key->path) {
858 kfree(dcd_key);
859 status = -ENOMEM;
860 goto func_end;
861 }
862
863 strncpy(dcd_key->name, sz_reg_key,
864 strlen(sz_reg_key) + 1);
865 strncpy(dcd_key->path, psz_path_name ,
866 dw_path_size);
867 spin_lock(&dbdcd_lock);
868 list_add_tail(&dcd_key->link, ®_key_list);
869 spin_unlock(&dbdcd_lock);
870 } else {
871
872 if (strncmp(dcd_key->path, psz_path_name,
873 dw_path_size)) {
874
875 kfree(dcd_key->path);
876 dcd_key->path = kmalloc(dw_path_size,
877 GFP_KERNEL);
878 if (dcd_key->path == NULL) {
879 status = -ENOMEM;
880 goto func_end;
881 }
882 }
883
884
885 memcpy(dcd_key->path, psz_path_name, dw_path_size);
886 }
887 dev_dbg(bridge, "%s: psz_path_name=%s, dw_path_size=%d\n",
888 __func__, psz_path_name, dw_path_size);
889 } else {
890
891 spin_lock(&dbdcd_lock);
892 list_for_each_entry(dcd_key, ®_key_list, link) {
893 if (!strncmp(dcd_key->name, sz_reg_key,
894 strlen(sz_reg_key) + 1)) {
895 list_del(&dcd_key->link);
896 kfree(dcd_key->path);
897 kfree(dcd_key);
898 break;
899 }
900 }
901 spin_unlock(&dbdcd_lock);
902 if (&dcd_key->link == ®_key_list)
903 status = -EPERM;
904 }
905
906 if (!status) {
907
908
909
910
911
912
913
914 enum_refs = 0;
915 }
916func_end:
917 return status;
918}
919
920
921
922
923
924
925int dcd_unregister_object(struct dsp_uuid *uuid_obj,
926 enum dsp_dcdobjtype obj_type)
927{
928 int status = 0;
929
930
931
932
933
934 status = dcd_register_object(uuid_obj, obj_type, NULL);
935
936 return status;
937}
938
939
940
941
942
943
944
945
946
947
948
949
950static s32 atoi(char *psz_buf)
951{
952 char *pch = psz_buf;
953 s32 base = 0;
954
955 while (isspace(*pch))
956 pch++;
957
958 if (*pch == '-' || *pch == '+') {
959 base = 10;
960 pch++;
961 } else if (*pch && tolower(pch[strlen(pch) - 1]) == 'h') {
962 base = 16;
963 }
964
965 return simple_strtoul(pch, NULL, base);
966}
967
968
969
970
971
972
973
974
975static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size,
976 enum dsp_dcdobjtype obj_type,
977 struct dcd_genericobj *gen_obj)
978{
979 int status = 0;
980 char seps[] = ", ";
981 char *psz_cur;
982 char *token;
983 s32 token_len = 0;
984 u32 i = 0;
985#ifdef _DB_TIOMAP
986 s32 entry_id;
987#endif
988
989 switch (obj_type) {
990 case DSP_DCDNODETYPE:
991
992
993
994
995 psz_cur = psz_buf;
996 token = strsep(&psz_cur, seps);
997
998
999 gen_obj->obj_data.node_obj.ndb_props.cb_struct =
1000 (u32) atoi(token);
1001 token = strsep(&psz_cur, seps);
1002
1003
1004 uuid_uuid_from_string(token,
1005 &gen_obj->obj_data.node_obj.ndb_props.
1006 ui_node_id);
1007 token = strsep(&psz_cur, seps);
1008
1009
1010 token_len = strlen(token);
1011 if (token_len > DSP_MAXNAMELEN - 1)
1012 token_len = DSP_MAXNAMELEN - 1;
1013
1014 strncpy(gen_obj->obj_data.node_obj.ndb_props.ac_name,
1015 token, token_len);
1016 gen_obj->obj_data.node_obj.ndb_props.ac_name[token_len] = '\0';
1017 token = strsep(&psz_cur, seps);
1018
1019 gen_obj->obj_data.node_obj.ndb_props.ntype = atoi(token);
1020 token = strsep(&psz_cur, seps);
1021
1022 gen_obj->obj_data.node_obj.ndb_props.cache_on_gpp = atoi(token);
1023 token = strsep(&psz_cur, seps);
1024
1025 gen_obj->obj_data.node_obj.ndb_props.dsp_resource_reqmts.
1026 cb_struct = (u32) atoi(token);
1027 token = strsep(&psz_cur, seps);
1028
1029 gen_obj->obj_data.node_obj.ndb_props.
1030 dsp_resource_reqmts.static_data_size = atoi(token);
1031 token = strsep(&psz_cur, seps);
1032 gen_obj->obj_data.node_obj.ndb_props.
1033 dsp_resource_reqmts.global_data_size = atoi(token);
1034 token = strsep(&psz_cur, seps);
1035 gen_obj->obj_data.node_obj.ndb_props.
1036 dsp_resource_reqmts.program_mem_size = atoi(token);
1037 token = strsep(&psz_cur, seps);
1038 gen_obj->obj_data.node_obj.ndb_props.
1039 dsp_resource_reqmts.wc_execution_time = atoi(token);
1040 token = strsep(&psz_cur, seps);
1041 gen_obj->obj_data.node_obj.ndb_props.
1042 dsp_resource_reqmts.wc_period = atoi(token);
1043 token = strsep(&psz_cur, seps);
1044
1045 gen_obj->obj_data.node_obj.ndb_props.
1046 dsp_resource_reqmts.wc_deadline = atoi(token);
1047 token = strsep(&psz_cur, seps);
1048
1049 gen_obj->obj_data.node_obj.ndb_props.
1050 dsp_resource_reqmts.avg_exection_time = atoi(token);
1051 token = strsep(&psz_cur, seps);
1052
1053 gen_obj->obj_data.node_obj.ndb_props.
1054 dsp_resource_reqmts.minimum_period = atoi(token);
1055 token = strsep(&psz_cur, seps);
1056
1057
1058 gen_obj->obj_data.node_obj.ndb_props.prio = atoi(token);
1059 token = strsep(&psz_cur, seps);
1060
1061
1062 gen_obj->obj_data.node_obj.ndb_props.stack_size = atoi(token);
1063 token = strsep(&psz_cur, seps);
1064
1065
1066 gen_obj->obj_data.node_obj.ndb_props.sys_stack_size =
1067 atoi(token);
1068 token = strsep(&psz_cur, seps);
1069
1070
1071 gen_obj->obj_data.node_obj.ndb_props.stack_seg = atoi(token);
1072 token = strsep(&psz_cur, seps);
1073
1074
1075 gen_obj->obj_data.node_obj.ndb_props.message_depth =
1076 atoi(token);
1077 token = strsep(&psz_cur, seps);
1078
1079
1080 gen_obj->obj_data.node_obj.ndb_props.num_input_streams =
1081 atoi(token);
1082 token = strsep(&psz_cur, seps);
1083
1084
1085 gen_obj->obj_data.node_obj.ndb_props.num_output_streams =
1086 atoi(token);
1087 token = strsep(&psz_cur, seps);
1088
1089
1090 gen_obj->obj_data.node_obj.ndb_props.timeout = atoi(token);
1091 token = strsep(&psz_cur, seps);
1092
1093
1094 token_len = strlen(token);
1095 gen_obj->obj_data.node_obj.str_create_phase_fxn =
1096 kzalloc(token_len + 1, GFP_KERNEL);
1097 strncpy(gen_obj->obj_data.node_obj.str_create_phase_fxn,
1098 token, token_len);
1099 gen_obj->obj_data.node_obj.str_create_phase_fxn[token_len] =
1100 '\0';
1101 token = strsep(&psz_cur, seps);
1102
1103
1104 token_len = strlen(token);
1105 gen_obj->obj_data.node_obj.str_execute_phase_fxn =
1106 kzalloc(token_len + 1, GFP_KERNEL);
1107 strncpy(gen_obj->obj_data.node_obj.str_execute_phase_fxn,
1108 token, token_len);
1109 gen_obj->obj_data.node_obj.str_execute_phase_fxn[token_len] =
1110 '\0';
1111 token = strsep(&psz_cur, seps);
1112
1113
1114 token_len = strlen(token);
1115 gen_obj->obj_data.node_obj.str_delete_phase_fxn =
1116 kzalloc(token_len + 1, GFP_KERNEL);
1117 strncpy(gen_obj->obj_data.node_obj.str_delete_phase_fxn,
1118 token, token_len);
1119 gen_obj->obj_data.node_obj.str_delete_phase_fxn[token_len] =
1120 '\0';
1121 token = strsep(&psz_cur, seps);
1122
1123
1124 gen_obj->obj_data.node_obj.msg_segid = atoi(token);
1125 token = strsep(&psz_cur, seps);
1126
1127
1128 gen_obj->obj_data.node_obj.msg_notify_type = atoi(token);
1129 token = strsep(&psz_cur, seps);
1130
1131
1132 if (token) {
1133 token_len = strlen(token);
1134 gen_obj->obj_data.node_obj.str_i_alg_name =
1135 kzalloc(token_len + 1, GFP_KERNEL);
1136 strncpy(gen_obj->obj_data.node_obj.str_i_alg_name,
1137 token, token_len);
1138 gen_obj->obj_data.node_obj.str_i_alg_name[token_len] =
1139 '\0';
1140 token = strsep(&psz_cur, seps);
1141 }
1142
1143
1144 if (token) {
1145 gen_obj->obj_data.node_obj.load_type = atoi(token);
1146 token = strsep(&psz_cur, seps);
1147 }
1148
1149
1150 if (token) {
1151 gen_obj->obj_data.node_obj.data_mem_seg_mask =
1152 atoi(token);
1153 token = strsep(&psz_cur, seps);
1154 }
1155
1156
1157 if (token) {
1158 gen_obj->obj_data.node_obj.code_mem_seg_mask =
1159 atoi(token);
1160 token = strsep(&psz_cur, seps);
1161 }
1162
1163
1164 if (token) {
1165
1166 gen_obj->obj_data.node_obj.ndb_props.count_profiles =
1167 atoi(token);
1168 for (i = 0;
1169 i <
1170 gen_obj->obj_data.node_obj.
1171 ndb_props.count_profiles; i++) {
1172 token = strsep(&psz_cur, seps);
1173 if (token) {
1174
1175 gen_obj->obj_data.node_obj.
1176 ndb_props.node_profiles[i].
1177 heap_size = atoi(token);
1178 }
1179 }
1180 }
1181 token = strsep(&psz_cur, seps);
1182 if (token) {
1183 gen_obj->obj_data.node_obj.ndb_props.stack_seg_name =
1184 (u32) (token);
1185 }
1186
1187 break;
1188
1189 case DSP_DCDPROCESSORTYPE:
1190
1191
1192
1193
1194 psz_cur = psz_buf;
1195 token = strsep(&psz_cur, seps);
1196
1197 gen_obj->obj_data.proc_info.cb_struct = atoi(token);
1198 token = strsep(&psz_cur, seps);
1199
1200 gen_obj->obj_data.proc_info.processor_family = atoi(token);
1201 token = strsep(&psz_cur, seps);
1202
1203 gen_obj->obj_data.proc_info.processor_type = atoi(token);
1204 token = strsep(&psz_cur, seps);
1205
1206 gen_obj->obj_data.proc_info.clock_rate = atoi(token);
1207 token = strsep(&psz_cur, seps);
1208
1209 gen_obj->obj_data.proc_info.internal_mem_size = atoi(token);
1210 token = strsep(&psz_cur, seps);
1211
1212 gen_obj->obj_data.proc_info.external_mem_size = atoi(token);
1213 token = strsep(&psz_cur, seps);
1214
1215 gen_obj->obj_data.proc_info.processor_id = atoi(token);
1216 token = strsep(&psz_cur, seps);
1217
1218 gen_obj->obj_data.proc_info.ty_running_rtos = atoi(token);
1219 token = strsep(&psz_cur, seps);
1220
1221 gen_obj->obj_data.proc_info.node_min_priority = atoi(token);
1222 token = strsep(&psz_cur, seps);
1223
1224 gen_obj->obj_data.proc_info.node_max_priority = atoi(token);
1225
1226#ifdef _DB_TIOMAP
1227
1228
1229 for (entry_id = 0; entry_id < 7; entry_id++) {
1230 token = strsep(&psz_cur, seps);
1231 gen_obj->obj_data.ext_proc_obj.ty_tlb[entry_id].
1232 gpp_phys = atoi(token);
1233
1234 token = strsep(&psz_cur, seps);
1235 gen_obj->obj_data.ext_proc_obj.ty_tlb[entry_id].
1236 dsp_virt = atoi(token);
1237 }
1238#endif
1239
1240 break;
1241
1242 default:
1243 status = -EPERM;
1244 break;
1245 }
1246
1247 return status;
1248}
1249
1250
1251
1252
1253
1254
1255static void compress_buf(char *psz_buf, u32 ul_buf_size, s32 char_size)
1256{
1257 char *p;
1258 char ch;
1259 char *q;
1260
1261 p = psz_buf;
1262 if (p == NULL)
1263 return;
1264
1265 for (q = psz_buf; q < (psz_buf + ul_buf_size);) {
1266 ch = dsp_char2_gpp_char(q, char_size);
1267 if (ch == '\\') {
1268 q += char_size;
1269 ch = dsp_char2_gpp_char(q, char_size);
1270 switch (ch) {
1271 case 't':
1272 *p = '\t';
1273 break;
1274
1275 case 'n':
1276 *p = '\n';
1277 break;
1278
1279 case 'r':
1280 *p = '\r';
1281 break;
1282
1283 case '0':
1284 *p = '\0';
1285 break;
1286
1287 default:
1288 *p = ch;
1289 break;
1290 }
1291 } else {
1292 *p = ch;
1293 }
1294 p++;
1295 q += char_size;
1296 }
1297
1298
1299 while (p < q)
1300 *p++ = '\0';
1301}
1302
1303
1304
1305
1306
1307
1308static char dsp_char2_gpp_char(char *word, s32 dsp_char_size)
1309{
1310 char ch = '\0';
1311 char *ch_src;
1312 s32 i;
1313
1314 for (ch_src = word, i = dsp_char_size; i > 0; i--)
1315 ch |= *ch_src++;
1316
1317 return ch;
1318}
1319
1320
1321
1322
1323static int get_dep_lib_info(struct dcd_manager *hdcd_mgr,
1324 struct dsp_uuid *uuid_obj,
1325 u16 *num_libs,
1326 u16 *num_pers_libs,
1327 struct dsp_uuid *dep_lib_uuids,
1328 bool *prstnt_dep_libs,
1329 enum nldr_phase phase)
1330{
1331 struct dcd_manager *dcd_mgr_obj = hdcd_mgr;
1332 char *psz_coff_buf = NULL;
1333 char *psz_cur;
1334 char *psz_file_name = NULL;
1335 struct cod_libraryobj *lib = NULL;
1336 u32 ul_addr = 0;
1337 u32 ul_len = 0;
1338 u32 dw_data_size = COD_MAXPATHLENGTH;
1339 char seps[] = ", ";
1340 char *token = NULL;
1341 bool get_uuids = (dep_lib_uuids != NULL);
1342 u16 dep_libs = 0;
1343 int status = 0;
1344
1345
1346
1347 if (!get_uuids) {
1348 *num_libs = 0;
1349 *num_pers_libs = 0;
1350 }
1351
1352
1353 psz_file_name = kzalloc(dw_data_size, GFP_KERNEL);
1354 if (psz_file_name == NULL) {
1355 status = -ENOMEM;
1356 } else {
1357
1358 status = dcd_get_library_name(hdcd_mgr, uuid_obj, psz_file_name,
1359 &dw_data_size, phase, NULL);
1360 }
1361
1362
1363 if (!status) {
1364 status = cod_open(dcd_mgr_obj->cod_mgr, psz_file_name,
1365 COD_NOLOAD, &lib);
1366 }
1367 if (!status) {
1368
1369 status = cod_get_section(lib, DEPLIBSECT, &ul_addr, &ul_len);
1370
1371 if (status) {
1372
1373 ul_len = 0;
1374 status = 0;
1375 }
1376 }
1377
1378 if (status || !(ul_len > 0))
1379 goto func_cont;
1380
1381
1382 psz_coff_buf = kzalloc(ul_len + 4, GFP_KERNEL);
1383 if (psz_coff_buf == NULL)
1384 status = -ENOMEM;
1385
1386
1387 status = cod_read_section(lib, DEPLIBSECT, psz_coff_buf, ul_len);
1388 if (status)
1389 goto func_cont;
1390
1391
1392 compress_buf(psz_coff_buf, ul_len, DSPWORDSIZE);
1393
1394
1395 psz_cur = psz_coff_buf;
1396 while ((token = strsep(&psz_cur, seps)) && *token != '\0') {
1397 if (get_uuids) {
1398 if (dep_libs >= *num_libs) {
1399
1400 break;
1401 } else {
1402
1403 uuid_uuid_from_string(token,
1404 &(dep_lib_uuids
1405 [dep_libs]));
1406
1407 token = strsep(&psz_cur, seps);
1408 prstnt_dep_libs[dep_libs] = atoi(token);
1409 dep_libs++;
1410 }
1411 } else {
1412
1413 token = strsep(&psz_cur, seps);
1414 if (atoi(token))
1415 (*num_pers_libs)++;
1416
1417
1418 (*num_libs)++;
1419 }
1420 }
1421func_cont:
1422 if (lib)
1423 cod_close(lib);
1424
1425
1426 kfree(psz_file_name);
1427
1428 kfree(psz_coff_buf);
1429
1430 return status;
1431}
1432