blob: 0323a47b56e65204790e3da9c1c5b2ce410d1f0e [file] [log] [blame]
yu.dongc33b3072024-08-21 23:14:49 -07001#!/usr/bin/perl -w
2
3#-------------------------------------------------------------------
4#Tool version
5
6$tool_version = '20161012';
7
8#-------------------------------------------------------------------
9#Parameters Configuration
10
11$imm_file = $ARGV[0];
12$itcm_file = $ARGV[1];
13$dtcm_file = $ARGV[2];
14$log_file = $ARGV[3];
15
16#-------------------------------------------------------------------
17# Replace '\' with '/'
18
19$imm_file =~ s/\\/\//g;
20$itcm_file =~ s/\\/\//g;
21$dtcm_file =~ s/\\/\//g;
22$log_file =~ s/\\/\//g;
23
24#-------------------------------------------------------------------
25
26$DEBUG_MODE = 0; # 0 or 1
27$error_prefix = 'AutoTCM Error:';
28$warning_prefix = 'AutoTCM Miss:';
29$nolist_keyword = 'NO_LIST';
30
31
32#-------------------------------------------------------------------
33# Open log file
34open (FILE_LOG, ">>$log_file" ) or die (print "$error_prefix Can't open Auto-TCM-Attribute log file $log_file!\n");
35print FILE_LOG "Auto TCM Attribute Tool $tool_version\n";
36
37#-------------------------------------------------------------------
38#Construct C file name
39$c_file = $imm_file;
40$c_file =~ s/.*\///; # remove path part
41print FILE_LOG "Source C File : $c_file\n";
42print FILE_LOG "Immediated File : $imm_file\n";
43print FILE_LOG "Func List File : $itcm_file\n";
44print FILE_LOG "Var List File : $dtcm_file\n";
45
46#-------------------------------------------------------------------
47# Intialize some list as empty
48%ITCM_LIST = ();
49%DTCM_LIST = ();
50
51%ITCM_LIST_SECTION = ();
52%DTCM_LIST_SECTION_IDX = ();
53
54%ADDED_ATTRIBUTE = ();
55%REPLACED_CODE = ();
56
57$ADDED_ADT_CODE = '';
58$ADDITIONAL_ADT_TAG = '';
59%ITCM_LIST_ADDITIONAL_ADT_TAG = ();
60%ADDITIONAL_ITCM_LIST = ();
61
62%ADDITIONAL_ITCM_LIST_SECTION = ();
63
64#-------------------------------------------------------------------
65#Extract ITCM list
66
67my $itcm_list_num = &Extract_ITCM_List($itcm_file, $c_file);
68
69if( $itcm_list_num > 0 )
70{
71 &Find_ITCM_List($imm_file);
72}
73
74#-------------------------------------------------------------------
75#Extract DTCM list
76
77my $dtcm_list_num = &Extract_DTCM_List(($dtcm_file, $c_file));
78
79if( $dtcm_list_num > 0 )
80{
81 &Find_DTCM_List($imm_file);
82}
83
84#-------------------------------------------------------------------
85#Add __attribute__ and ADT jump code in source code
86my $bak_file = $imm_file;
87$bak_file =~ s/\.c$/\.i/;
88unlink( $bak_file ) or &print_error_info_die("$error_prefix Can't delete $bak_file\n") if( -e $bak_file );
89
90if( scalar(keys %ADDED_ATTRIBUTE) > 0 || scalar(keys %REPLACED_CODE) > 0 || ($ADDED_ADT_CODE ne '') )
91{
92 rename $imm_file, $bak_file or &print_error_info_die("$error_prefix Can't rename $imm_file to $bak_file\n");
93 print FILE_LOG "Backup Imm File : $bak_file\n";
94
95 &Add_Attribute_Code( $bak_file, $imm_file );
96
97}
98else
99{
100 if( $itcm_list_num == 0 && $dtcm_list_num==0 )
101 {
102 print FILE_LOG "\t$c_file is not in TCM symbol lists.\n";
103
104 }else
105 {
106 print FILE_LOG "\t$warning_prefix No TCM symbol is detected in $c_file, but there are $itcm_list_num function and $dtcm_list_num variable in TCM symbol list.\n";
107 }
108}
109
110#-------------------------------------------------------------------
111#Close log file handle
112
113print FILE_LOG "Done!\n";
114print FILE_LOG "-----------------------------------------------------------\n";
115close FILE_LOG;
116
117#-------------------------------------------------------------------
118
119#Parsing Done.
120
121exit 0; #return 0 if it is successful
122
123#-------------------------------------------------------------------
124
125sub Extract_ITCM_List
126{
127 my $list = $_[0];
128
129 return 0 if( $list eq $nolist_keyword );
130
131 my $search_file_1 = $_[1];
132 my $search_file_2 = $search_file_1;
133 $search_file_2 =~ s/\.c$/\.obj/;
134
135 my $is_adt = 0;
136 my $section = '__attribute__ ((section("INTSRAM_ROCODE")))';
137 my @section_adt =();
138
139 # Open TCM fucntions list file
140 open (FILE_ITCM, "<$list" ) or &print_error_info_die("$error_prefix Can't open TCM function list file $list!\n");
141
142 while (<FILE_ITCM>)
143 {
144 s/#.*//;
145 s/^\s*//;
146 s/\s*$//;
147 next if( $_ eq '' );
148
149 if( /^__attribute__/)
150 {
151 #__attribute__ ((section("INTSRAM_ROCODE")))
152 $section = $_;
153 @section_adt = ();
154 $ADDITIONAL_ADT_TAG = '';
155
156 }elsif( /^\[ADT\]\[JMP_FP]\s*(__attribute__.*)/)
157 {
158 #[ADT][JMP_FP] __attribute__ ((section("INTSRAM_RW")))
159 $section_adt[0] = $1;
160 $ADDITIONAL_ADT_TAG = ''; #additional ADT tag section must be put after normal ADT section, or it will be replaced as ''.
161
162 }elsif( /^\[ADT\]\[JMP_FN]\s*(__attribute__.*)/)
163 {
164 #[ADT][JMP_FN] __attribute__ ((section("INTSRAM_ROCODE"))) __attribute__ ((always_inline))
165 $section_adt[1] = $1;
166 $ADDITIONAL_ADT_TAG = '';
167
168 }elsif( /^\[ADT\]\[TCM_FN]\s*(__attribute__.*)/)
169 {
170 #[ADT][TCM_FN] __attribute__ ((section("INTSRAM_ROCODE"))) __attribute__ ((noinline))
171 $section_adt[2] = $1;
172 $ADDITIONAL_ADT_TAG = '';
173
174 }elsif( /^\[ADT\]\[(.+)\]\[JMP_FP\]\s*(__attribute__.*)/)
175 {
176 #[ADT][XXX][JMP_FP] __attribute__ ((section("INTSRAM_RW"))) #XXX is additional ADT tag, only support one additional ADT tag. One function is mapping to one section, so additional ADT tag section must be the same as normal ADT section.
177 $ADDITIONAL_ADT_TAG = $1;
178 $section_adt[0] = $2;
179
180 }elsif( /^\[ADT\]\[(.+)\]\[JMP_FN\]\s*(__attribute__.*)/)
181 {
182 #[ADT][XXX][JMP_FN] __attribute__ ((section("INTSRAM_ROCODE"))) __attribute__ ((always_inline))
183 $ADDITIONAL_ADT_TAG = $1;
184 $section_adt[1] = $2;
185
186 }elsif( /^\[ADT\]\[(.+)\]\[TCM_FN\]\s*(__attribute__.*)/)
187 {
188 #[ADT][XXX][TCM_FN] __attribute__ ((section("INTSRAM_ROCODE"))) __attribute__ ((noinline))
189 $ADDITIONAL_ADT_TAG = $1;
190 $section_adt[2] = $2;
191
192 }elsif( /^\s*(\S+)\s*,?\s*($search_file_1|$search_file_2)\b/ )
193 {
194 my $func_name = $1;
195 if($ADDITIONAL_ADT_TAG !~ /[A-Za-z0-9_]+/ )
196 {
197 if( exists($ITCM_LIST{$func_name}) && (scalar(@section_adt)==0) )
198 {
199 #print FILE_LOG "\t$error_prefix Cannot put $func_name in two different section!\n";
200 &print_error_info_die( "\t$error_prefix Cannot put $func_name in two different section!\n" );
201 }
202 else
203 {
204 $ITCM_LIST{$func_name} = 0;
205 $ITCM_LIST_SECTION{$func_name} = (scalar(@section_adt)==0)? $section : "$section_adt[0],$section_adt[1],$section_adt[2]";
206 #printf "[ADT_DBG] $ITCM_LIST_SECTION{$func_name}\t$func_name\n";
207 }
208 }
209 else
210 {
211 if( exists($ADDITIONAL_ITCM_LIST{$func_name}) && (scalar(@section_adt)==0) )
212 {
213 #print FILE_LOG "\t$error_prefix Cannot put $func_name in two different section!\n";
214 &print_error_info_die( "\t$error_prefix Cannot put $func_name in two different section!\n" );
215 }
216 else
217 {
218 $ITCM_LIST_ADDITIONAL_ADT_TAG{$func_name} = (scalar(@section_adt)==0)? '' : "$ADDITIONAL_ADT_TAG";
219 $ADDITIONAL_ITCM_LIST{$func_name} = 0;
220 $ADDITIONAL_ITCM_LIST_SECTION{$func_name} = (scalar(@section_adt)==0)? $section : "$section_adt[0],$section_adt[1],$section_adt[2]";
221 }
222 }
223 }
224 }
225
226 close FILE_ITCM;
227
228 return scalar(keys %ITCM_LIST)+scalar(keys %ADDITIONAL_ITCM_LIST);
229}
230
231#-------------------------------------------------------------------
232
233sub Extract_DTCM_List
234{
235 my $list = $_[0];
236
237 return 0 if( $list eq $nolist_keyword );
238
239 my $search_file_1 = $_[1];
240 my $search_file_2 = $search_file_1;
241 $search_file_2 =~ s/\.c$/\.obj/;
242
243
244 #default RO/RW/ZI attribute section
245 $attribute_dtcm_ro[0] = '__attribute__ ((section("INTSRAM_RODATA")))';
246 $attribute_dtcm_rw[0] = '__attribute__ ((section("INTSRAM_RW")))';
247 $attribute_dtcm_zi[0] = '__attribute__ ((section("INTSRAM_ZI"))) __attribute__ ((zero_init))';
248 $section_idx = 0;
249
250 # Open TCM variables list file
251 open (FILE_DTCM, "<$list" ) or &print_error_info_die("$error_prefix Can't open TCM variable list file $list!\n");
252
253 my $section = '';
254 my $attribute_block_start = 0;
255 my $line_no = 0;
256
257 while (<FILE_DTCM>)
258 {
259 $line_no++;
260
261 s/#.*//;
262 s/^\s*//;
263 s/\s*$//;
264
265 next if( $_ eq '' );
266 my $line_in = $_;
267
268
269 if( /^\[(\w+)\]\s*(__attribute__.+)/)
270 {
271 if( $attribute_block_start == 0 )
272 {
273 $section_idx++;
274 $attribute_dtcm_ro[$section_idx] = '';
275 $attribute_dtcm_rw[$section_idx] = '';
276 $attribute_dtcm_zi[$section_idx] = '';
277 }
278 $attribute_block_start++;
279
280 if($1 eq 'RO')
281 { $attribute_dtcm_ro[$section_idx] = $2;
282 }elsif($1 eq 'RW')
283 { $attribute_dtcm_rw[$section_idx] = $2;
284 }elsif($1 eq 'ZI')
285 { $attribute_dtcm_zi[$section_idx] = $2;
286 }else
287 { &print_error_info_die("$error_prefix Can't idenify line $line_no of TCM data list file $list: $line_in\n");
288 }
289
290 }else
291 {
292 if($attribute_block_start!=0)
293 {
294 &print_error_info_die("$error_prefix 3 data section attribute of RO & ZI & RW are necessary. Please check line $line_no of TCM data list file $list\n") if($attribute_block_start!=3);
295 $attribute_block_start = 0;
296
297 #print "$attribute_dtcm_ro[$section_idx]\n";
298 #print "$attribute_dtcm_rw[$section_idx]\n";
299 #print "$attribute_dtcm_zi[$section_idx]\n";
300
301 }
302
303 if ( /^\s*(\S+)\s*,?\s*($search_file_1|$search_file_2)\b/ )
304 {
305 if( exists($DTCM_LIST{$1}) )
306 {
307 &print_error_info_die( "\t$error_prefix Cannot put $1 in two different section!\n" );
308 }
309 else
310 {
311 $DTCM_LIST{$1} = 0;
312 $DTCM_LIST_SECTION_IDX{$1} = $section_idx;
313 }
314 }
315
316 }
317 }
318
319 close FILE_DTCM;
320
321 return scalar(keys %DTCM_LIST);
322}
323
324#-------------------------------------------------------------------
325
326sub Find_ITCM_List
327{
328 my $imm = $_[0]; #Input is immediate file
329
330 # Open imm file, which is output of pre-processor
331 open (FILE_IMM, "<$imm" ) or &print_error_info_die("$error_prefix Can't open immediated file $imm!\n");
332
333 my $line_in = '';
334 my $line_in_old = '';
335 my $line_number = 0;
336 my $brace_l_cnt = 0; # left brace conter
337 my $brace_r_cnt = 0; # right brace conter
338 my $hited_target = undef;
339 my $hited_lineno = undef;
340 my $hited_lineno_noadt = undef;
341 my $spec_fmt_func = 0;
342
343 my $hited_section = '';
344 my $hited_is_adt = 0;
345 my $hited_linein = '';
346
347 my $adt_func_body = '';
348 my $adt_var_list = '';
349 my $adt_jump_fp = '';
350 my $adt_jump_func = '';
351 my $adt_jump_fp_set_func = '';
352
353 my $adt_section_jmp_fp = '';
354 my $adt_section_jmp_fn = '';
355 my $adt_section_tcm_fn = '';
356
357 my $adt_func_linemarker = '';
358 my $linemarker_lineno = 0;
359 my $linemarker_filename;
360
361#--------------additional ADT section use----------begin-------
362 my $additional_adt_func_body = '';
363 my $additional_adt_func_body_emi = '';
364 my $additional_adt_var_list = '';
365 my $additional_adt_jump_fp = '';
366 my $additional_adt_jump_func = '';
367 my $additional_adt_jump_fp_set_func = '';
368
369 my $additional_adt_section_jmp_fp = '';
370 my $additional_adt_section_jmp_fn = '';
371 my $additional_adt_section_tcm_fn = '';
372
373 my $additional_adt_func_linemarker = '';
374 my $additional_hited_is_adt = 0;
375 my $additional_adt_func_only = 0;
376#--------------additional ADT section use----------end-------
377
378 while( <FILE_IMM> )
379 {
380 $line_in = $_;
381 $line_in_ori = $_;
382 $line_number++;
383
384 $linemarker_lineno++;
385
386 if($hited_is_adt)
387 {
388 if($line_in_ori =~ /\bstatic\s+.+\;/)
389 {
390 &print_error_info_die("$error_prefix Cannot use static local variable! Line:$linemarker_lineno\n");
391 #print FILE_LOG "\t$error_prefix Cannot use static local variable! Line:$linemarker_lineno\n";
392 }
393 $adt_func_body .= $line_in_ori;
394 }
395
396#--------------additional ADT section use----------begin-------
397 if($additional_hited_is_adt)
398 {
399 if($line_in_ori =~ /\bstatic\s+.+\;/)
400 {
401 &print_error_info_die("$error_prefix Cannot use static local variable! Line:$linemarker_lineno\n");
402 #print FILE_LOG "\t$error_prefix Cannot use static local variable! Line:$linemarker_lineno\n";
403 }
404 $additional_adt_func_body .= $line_in_ori;
405 $additional_adt_func_body_emi .= $line_in_ori;
406 }
407#--------------additional ADT section use----------end-------
408
409 next unless ( $line_in =~ /\S/ ); #Skip all blank line
410
411 if( $line_in =~ /^\#\s+(\d+)\s+(\".*\")/) #Ex:# 1978 "l1core/modem/el1/el1d/lcsfun.c"
412 {
413 $linemarker_lineno = $1 - 1;
414 $linemarker_filename = $2;
415 next;
416 }
417
418
419 $line_in =~ s/\".*?[^\\]\"/\"!!STRING!!\"/g; # Replace string with spcial keyword
420
421 if($brace_l_cnt == $brace_r_cnt) # '{' & '}' number is the same
422 {
423 foreach( sort keys %ITCM_LIST )
424 {
425 my $target = $_;
426
427 if( $line_in =~ /\S+\s+\**$target\s*\(/ )
428 {
429 $hited_target = $target;
430 $hited_lineno = $line_number;
431 $hited_lineno_noadt = $line_number;
432 $hited_linein = $line_in_ori;
433
434 $adt_func_body = '';
435
436 my $section_str = $ITCM_LIST_SECTION{ $hited_target };
437
438 if( $section_str =~ /,/ )
439 {
440 $hited_is_adt = 1;
441 ($adt_section_jmp_fp, $adt_section_jmp_fn, $adt_section_tcm_fn) = split( /,/, $section_str );
442
443 $adt_func_body .= $line_in_ori;
444 $adt_func_linemarker = "# $linemarker_lineno $linemarker_filename";
445 }
446 else
447 {
448 $hited_is_adt = 0;
449 $hited_section = $section_str;
450 #print "$hited_section\n$line_in_ori\n";
451 }
452
453 last;
454 }
455 elsif ( $line_in =~ /\b$target\s*\(/ )
456 {
457 $spec_fmt_func = 1;
458 $hited_target = $target;
459 $hited_lineno = $line_number;
460 $hited_lineno_noadt = $line_number-1;
461 $hited_linein = $line_in_old.$line_in_ori;
462 $hited_linein =~ s/\n/ /g;
463
464 $adt_func_body = '';
465
466 my $section_str = $ITCM_LIST_SECTION{ $hited_target };
467
468 if( $section_str =~ /,/ )
469 {
470 $hited_is_adt = 1;
471 ($adt_section_jmp_fp, $adt_section_jmp_fn, $adt_section_tcm_fn) = split( /,/, $section_str );
472
473 $adt_func_body .= $hited_linein;
474 $adt_func_linemarker = "# $linemarker_lineno $linemarker_filename";
475 }
476 else
477 {
478 $hited_is_adt = 0;
479 $hited_section = $section_str;
480 #print "$hited_section\n$line_in_ori\n";
481 }
482
483 last;
484 }
485 }
486
487
488 }
489
490 if($hited_target && $line_in =~ /([{;])/ )
491 {
492 if( $1 eq '{' ) # Function body is detected.
493 {
494 $ITCM_LIST{ $hited_target }++; # hit and increase hit counter
495
496 if( $hited_is_adt == 0 )
497 {
498 $ADDED_ATTRIBUTE{ $hited_lineno_noadt } = $hited_section; #$ITCM_LIST_SECTION{ $hited_target };
499
500 }else
501 {
502 my $new_func_name_tcm = $hited_target."__tcm";
503 my $new_func_name_emi = $hited_target."__emi";
504
505 my $adt_func_prototype = get_func_prototype($adt_func_body);
506 $adt_func_prototype =~ /\)$/ or print_error_info_die("$error_prefix Failed to extract ADT fucntion \"$hited_target\" prototype!\n$imm:$line_number $adt_func_prototype\n");
507
508 my $adt_func_argu = $adt_func_prototype;
509 $adt_func_argu =~ s/^.*?\b$hited_target\s*\(\s*(.*?)\s*\)$/$1/ or print_error_info_die("$error_prefix Failed to extract ADT fucntion \"$hited_target\" arguments!\n$imm:$line_number $adt_func_argu\n");
510 $adt_func_argu = get_func_argu_names($adt_func_argu, $hited_target);
511
512 #Rename original function with postfix "__emi"
513 my $replace_code = $hited_linein;
514 $replace_code =~ s/(\S+\s+\**)$hited_target(\s*\()/$1$new_func_name_emi$2/;
515 $REPLACED_CODE{$hited_lineno} = "$adt_func_prototype; $replace_code";
516 if( $spec_fmt_func == 1 )
517 {
518 $REPLACED_CODE{$hited_lineno-1} = "\n";
519 $spec_fmt_func = 0;
520 }
521
522 #Create jump function and jump function pointer
523 #Example:
524 #void* ADTFP_EL1D_CAM_Is_CCA = EL1D_CAM_Is_CCA__tcm;
525 #BOOL EL1D_CAM_Is_CCA__test2( void )
526 #{
527 # BOOL (*pf)(void) = ADTFP_EL1D_CAM_Is_CCA;
528 # return pf();
529 #}
530
531 my $global_pf = "$hited_target"."__adtfp";
532 my $local_pf = $adt_func_prototype;
533 $local_pf =~ s/\b$hited_target\b/\(\*pf\)/;
534 $local_pf =~ s/\bstatic\b//;
535
536 $adt_jump_fp = "void* $global_pf = $new_func_name_emi;";
537
538 $adt_jump_func = "$adt_func_prototype";
539 $adt_jump_func .= "{ $local_pf = $global_pf;";
540 $adt_jump_func .= " return " unless( $adt_func_prototype =~ /void\s+$hited_target\s*\(/ ); #void function or not
541 $adt_jump_func .= " pf($adt_func_argu);";
542 $adt_jump_func .= "}";
543
544 $adt_jump_fp_set_func = "__attribute__((always_inline)) void $hited_target"."__adtfp_set_tcm( void )";
545 $adt_jump_fp_set_func .= "{ $global_pf = $new_func_name_tcm; }";
546 $adt_jump_fp_set_func .= "\n";
547 $adt_jump_fp_set_func .= "__attribute__((always_inline)) void $hited_target"."__adtfp_set_emi( void )";
548 $adt_jump_fp_set_func .= "{ $global_pf = $new_func_name_emi; }";
549
550 $adt_func_body =~ s/(\S+\s+\**)$hited_target(\s*\()/$1$new_func_name_tcm$2/;
551
552 }
553 $hited_target = undef;
554 }else #if ';' is found first, it is only a function prototype
555 {
556 $hited_target = undef;
557 $hited_is_adt = 0;
558
559 }
560
561
562 }
563
564#--------------additional ADT section use----------begin-------
565
566 if($brace_l_cnt == $brace_r_cnt) # '{' & '}' number is the same
567 {
568 foreach( sort keys %ADDITIONAL_ITCM_LIST )
569 {
570 my $target2 = $_;
571
572 if( $line_in =~ /\S+\s+\**$target2\s*\(/ )
573 {
574 $hited_target2 = $target2;
575 $hited_lineno = $line_number;
576 $hited_linein = $line_in_ori;
577
578 $additional_adt_func_body = '';
579 $additional_adt_func_body_emi = '';
580
581 my $section_str2 = $ADDITIONAL_ITCM_LIST_SECTION{ $hited_target2 };
582
583 if( $section_str2 =~ /,/ )
584 {
585 $additional_hited_is_adt = 1;
586 ($additional_adt_section_jmp_fp, $additional_adt_section_jmp_fn, $additional_adt_section_tcm_fn) = split( /,/, $section_str2 );
587
588 $additional_adt_func_body .= $line_in_ori;
589 $additional_adt_func_body_emi .= $line_in_ori;
590 $additional_adt_func_linemarker = "# $linemarker_lineno $linemarker_filename";
591 }
592
593
594 last;
595 }
596 }
597 }
598 if($hited_target2 && $line_in =~ /([{;])/ )
599 {
600 if( $1 eq '{' ) # Function body is detected.
601 {
602 if($additional_hited_is_adt == 1)
603 {
604 $ADDITIONAL_ITCM_LIST{ $hited_target2 }++; # hit and increase hit counter
605
606 my $global_pf = "$hited_target2"."__adtfp";
607
608 my $addi_new_func_name_tcm = $hited_target2."__".$ITCM_LIST_ADDITIONAL_ADT_TAG{$hited_target2}."__tcm";
609 my $addi_new_func_name_emi = $hited_target2."__emi";
610
611 my $addi_adt_func_prototype = get_func_prototype($additional_adt_func_body);
612 $addi_adt_func_prototype =~ /\)$/ or print_error_info_die("$error_prefix Failed to extract ADT fucntion \"$hited_target2\" prototype!\n$imm:$line_number $addi_adt_func_prototype\n");
613
614 my $addi_adt_func_argu = $addi_adt_func_prototype;
615 $addi_adt_func_argu =~ s/^.*?\b$hited_target2\s*\(\s*(.*?)\s*\)$/$1/ or print_error_info_die("$error_prefix Failed to extract ADT fucntion \"$hited_target2\" arguments!\n$imm:$line_number $addi_adt_func_argu\n");
616 $addi_adt_func_argu = get_func_argu_names($addi_adt_func_argu, $hited_target2);
617
618
619 if(!$ITCM_LIST{ $hited_target2 }) #normal ADT section doesn't have this function, but additional one have
620 {
621 $additional_adt_func_only = 1; #normal ADT section doesn't have this function, but additional one have
622
623 #Rename original function with postfix "__emi"
624 my $addi_replace_code = $hited_linein;
625 $addi_replace_code =~ s/(\S+\s+\**)$hited_target2(\s*\()/$1$addi_new_func_name_emi$2/;
626 $REPLACED_CODE{$hited_lineno} = "$addi_adt_func_prototype; $addi_replace_code";
627
628 #Create jump function and jump function pointer
629 #Example:
630 #void* ADTFP_EL1D_CAM_Is_CCA = EL1D_CAM_Is_CCA__tcm;
631 #BOOL EL1D_CAM_Is_CCA__test2( void )
632 #{
633 # BOOL (*pf)(void) = ADTFP_EL1D_CAM_Is_CCA;
634 # return pf();
635 #}
636
637 my $global_pf = "$hited_target2"."__adtfp";
638 my $addi_local_pf = $addi_adt_func_prototype;
639 $addi_local_pf =~ s/\b$hited_target2\b/\(\*pf\)/;
640 $addi_local_pf =~ s/\bstatic\b//;
641
642 $additional_adt_jump_fp = "void* $global_pf = $addi_new_func_name_emi;";
643
644 $additional_adt_jump_func = "$addi_adt_func_prototype";
645 $additional_adt_jump_func .= "{ $addi_local_pf = $global_pf;";
646 $additional_adt_jump_func .= " return " unless( $addi_adt_func_prototype =~ /void\s+$hited_target2\s*\(/ ); #void function or not
647 $additional_adt_jump_func .= " pf($addi_adt_func_argu);";
648 $additional_adt_jump_func .= "}";
649 }
650 else
651 {
652 $additional_adt_func_only = 0;
653 }
654 $additional_adt_jump_fp_set_func = "__attribute__((always_inline)) void $hited_target2"."__".$ITCM_LIST_ADDITIONAL_ADT_TAG{$hited_target2}."__adtfp_set_tcm( void )";
655 $additional_adt_jump_fp_set_func .= "{ $global_pf = $addi_new_func_name_tcm; }";
656 $additional_adt_jump_fp_set_func .= "\n";
657 $additional_adt_jump_fp_set_func .= "__attribute__((always_inline)) void $hited_target2"."__".$ITCM_LIST_ADDITIONAL_ADT_TAG{$hited_target2}."__adtfp_set_emi( void )";
658 $additional_adt_jump_fp_set_func .= "{ $global_pf = $addi_new_func_name_emi; }";
659
660 $additional_adt_func_body =~ s/(\S+\s+\**)$hited_target2(\s*\()/$1$addi_new_func_name_tcm$2/;
661 if($ITCM_LIST{ $hited_target2 }) #Both normal ADT section and additional ADT section have this function
662 {
663 $additional_adt_func_body_emi =~ s/(\S+\s+\**)$hited_target2(\s*\()/$1$addi_new_func_name_emi$2/;
664 }
665 }
666
667 $hited_target2 = undef;
668 }
669 else #if ';' is found first, it is only a function prototype
670 {
671 $hited_target2 = undef;
672 $additional_hited_is_adt = 0;
673 }
674
675 }
676#--------------additional ADT section use----------end-------
677
678 $brace_l_cnt += $line_in =~ tr/{//; #count { number
679 $brace_r_cnt += $line_in =~ tr/}//; #count } number
680
681 if( (!$hited_target) && $hited_is_adt && ($brace_l_cnt==$brace_r_cnt))
682 {
683 $hited_is_adt = 0;
684
685 $ADDED_ADT_CODE .= "$adt_func_linemarker\n";
686 $ADDED_ADT_CODE .= "$adt_section_tcm_fn $adt_func_body\n";
687
688 $ADDED_ADT_CODE .= "$adt_func_linemarker\n";
689 $ADDED_ADT_CODE .= "$adt_section_jmp_fp $adt_jump_fp\n";
690
691 $ADDED_ADT_CODE .= "$adt_func_linemarker\n";
692 $ADDED_ADT_CODE .= "$adt_section_jmp_fn $adt_jump_func\n";
693
694 $ADDED_ADT_CODE .= "# 1 \"<built-in>\"\n";
695 $ADDED_ADT_CODE .= "$adt_jump_fp_set_func\n";
696 $ADDED_ADT_CODE .= "\n\n";
697
698 }
699
700 if( (!$hited_target2) && $additional_hited_is_adt && ($brace_l_cnt==$brace_r_cnt))
701 {
702 $additional_hited_is_adt = 0;
703
704 $ADDED_ADT_CODE .= "$additional_adt_func_linemarker\n";
705 $ADDED_ADT_CODE .= "$additional_adt_section_tcm_fn $additional_adt_func_body\n";
706
707 if($additional_adt_func_only == 0)
708 {
709 $ADDED_ADT_CODE .= "$additional_adt_func_linemarker\n";
710 #$ADDED_ADT_CODE .= "$additional_adt_func_body_emi\n";
711 }
712 else
713 {
714 $ADDED_ADT_CODE .= "$additional_adt_func_linemarker\n";
715 $ADDED_ADT_CODE .= "$additional_adt_section_jmp_fp $additional_adt_jump_fp\n";
716
717 $ADDED_ADT_CODE .= "$additional_adt_func_linemarker\n";
718 $ADDED_ADT_CODE .= "$additional_adt_section_jmp_fn $additional_adt_jump_func\n";
719 }
720 $ADDED_ADT_CODE .= "# 1 \"<built-in>\"\n";
721 $ADDED_ADT_CODE .= "$additional_adt_jump_fp_set_func\n";
722 $ADDED_ADT_CODE .= "\n\n";
723
724 }
725
726 $line_in_old = $line_in_ori;
727 }
728
729 my $number_hit_once = 0;
730 my $report_hit_once = '';
731 my $report_hit_miss = '';
732 my $report_hit_other = '';
733
734 my $addi_number_hit_once = 0;
735 my $addi_report_hit_once = '';
736 my $addi_report_hit_miss = '';
737 my $addi_report_hit_other = '';
738
739 while( ($function, $hit_cnt) = each %ITCM_LIST)
740 {
741 if( $hit_cnt == 1 )
742 {
743 $number_hit_once++;
744 $report_hit_once .= "\tTCM Function $function() is found.\n";
745
746 }elsif( $hit_cnt == 0 )
747 {
748 $report_hit_miss .= "\t$warning_prefix TCM Function $function() is missed.\n";
749
750 }else
751 {
752 $report_hit_other .= "\t$warning_prefix TCM Function $function() is found $hit_cnt times.\n";
753 }
754 }
755
756 while( ($function, $hit_cnt) = each %ADDITIONAL_ITCM_LIST)
757 {
758 if( $hit_cnt == 1 )
759 {
760 $addi_number_hit_once++;
761 $addi_report_hit_once .= "\tAdditional TCM Function $function() is found.\n";
762
763 }elsif( $hit_cnt == 0 )
764 {
765 $addi_report_hit_miss .= "\t$warning_prefix additional TCM Function $function() is missed.\n";
766
767 }else
768 {
769 $addi_report_hit_other .= "\t$warning_prefix additional TCM Function $function() is found $hit_cnt times.\n";
770 }
771 }
772
773 unless( $report_hit_miss eq '' )
774 {
775 print "$report_hit_miss";
776 print FILE_LOG "$report_hit_miss";
777 }
778
779 unless( $report_hit_other eq '' )
780 {
781 print "$report_hit_other";
782 print FILE_LOG "$report_hit_other";
783 }
784
785 if($number_hit_once>0)
786 {
787 print FILE_LOG "$report_hit_once" if( $DEBUG_MODE );
788 print FILE_LOG "\t$number_hit_once TCM functions are found.\n";
789 }
790
791 unless( $addi_report_hit_miss eq '' )
792 {
793 print "$addi_report_hit_miss";
794 print FILE_LOG "$addi_report_hit_miss";
795 }
796
797 unless( $addi_report_hit_other eq '' )
798 {
799 print "$addi_report_hit_other";
800 print FILE_LOG "$addi_report_hit_other";
801 }
802
803 if($addi_number_hit_once>0)
804 {
805 print FILE_LOG "$addi_report_hit_once" if( $DEBUG_MODE );
806 print FILE_LOG "\t$addi_number_hit_once TCM functions are found.\n";
807 }
808
809 if($brace_l_cnt != $brace_r_cnt)
810 {
811 print "\t$warning_prefix Left brace and right brace are not paried! { : }= $brace_l_cnt:$brace_l_cnt\n";
812 print FILE_LOG "\t$warning_prefix Left brace and right brace are not paried! { : }= $brace_l_cnt:$brace_l_cnt\n";
813 }
814
815 close FILE_IMM;
816
817}
818
819#-------------------------------------------------------------------
820
821sub Find_DTCM_List
822{
823 my $imm = $_[0]; #Input is immediated file
824
825 # Open imm file, which is output of pre-processor
826 open (FILE_IMM, "<$imm" ) or &print_error_info_die("$error_prefix Can't open immediated file $imm!\n");
827
828 my $line_in = '';
829 my $line_number = 0;
830 my $brace_l_sum = 0; # left brace { conter
831 my $brace_r_sum = 0; # right brace } conter
832 my $struct_hit = 0;
833 my $struct_lineno = 0;
834 my $parentheses_tick_all = 0; #number ( - number ) in all file
835
836 while( <FILE_IMM> )
837 {
838 $line_in = $_;
839 $line_number++;
840
841 next if($line_in =~ /^\#line/); # speed up parsing
842 next unless ( $line_in =~ /\S/ ); # speed up parsing
843
844 # Update {} counters
845 my $brace_l_cnt = $line_in =~ tr/{//; #count { number
846 my $brace_r_cnt = $line_in =~ tr/}//; #count } number
847 my $brace_tick_ori = $brace_l_sum - $brace_r_sum;
848 my $brace_tick_new = $brace_tick_ori + ($brace_l_cnt - $brace_r_cnt);
849 $brace_l_sum += $brace_l_cnt;
850 $brace_r_sum += $brace_r_cnt;
851
852 my $parentheses_tick_line = ($line_in =~ tr/(//) - ($line_in =~ tr/)//);
853 $parentheses_tick_all += $parentheses_tick_line;
854
855 $line_in =~ s/\".*?[^\\]\"/\"!!STRING!!\"/g; # Replace string with spcial keyword
856 $line_in =~ s/{.*?}/{!!!!}/g; # Replace content inside {}
857
858 if( $brace_tick_ori == 0 && !($line_in =~ /^\s*{/) ) # Only search global variable
859 {
860 if( $line_in =~ /\bstruct\b/ && $line_in !~ /;/ ) # Match "struct" keyword, but exclude case "struct ##_T symbol;"
861 {
862 $struct_hit = 1;
863 $struct_lineno = $line_number;
864
865 next if( $brace_r_cnt == 0); # next line if there is no }
866
867 }elsif( $parentheses_tick_line==0 && $parentheses_tick_all==0 )
868 {
869 foreach( sort keys %DTCM_LIST )
870 {
871 my $target = $_;
872
873 if( $line_in =~ /(^|,)[^=]*\b$target\b.*[=;,]/ ) # variable name is matched but assignment is excluded
874 {
875 unless( ( $line_in =~ /\bextern\b/ ) # extern is excluded.
876 ||( $line_in =~ /\S+\s+\**\w+\(.*$target.*\)\s*\;?\s*$/ ) # function parameter is excluded. Ex: "void abc( int $target );"
877 )
878 {
879
880 my $section = ($line_in =~ /\bconst\b[^\*]*\b$target/) ? $attribute_dtcm_ro[$DTCM_LIST_SECTION_IDX{$target}] : # It is RO data if include "const" keyword
881 ($line_in =~ /=/ ) ? $attribute_dtcm_rw[$DTCM_LIST_SECTION_IDX{$target}] :
882 $attribute_dtcm_zi[$DTCM_LIST_SECTION_IDX{$target}] ;
883
884 $DTCM_LIST{ $target }++; # hit and increase hit counter
885 $ADDED_ATTRIBUTE{ $line_number } = $section;
886 #last;
887 }
888
889 }#End of if()
890
891 }#End of foreach()
892 }
893 }
894
895 if( $struct_hit==1 && $brace_tick_new==0 && $brace_r_cnt>0 )
896 {
897 $struct_hit = 0;
898
899 foreach( sort keys %DTCM_LIST )
900 {
901 my $target = $_;
902
903 if ( $line_in =~ /\}.*\b$target\b/ )
904 {
905 #print "Struct \"$target\" is found in\n";
906 #print "$line_in\n";
907
908 my $section = ( $line_in =~ /\}.*=/ ) ? $attribute_dtcm_rw[$DTCM_LIST_SECTION_IDX{$target}]:$attribute_dtcm_zi[$DTCM_LIST_SECTION_IDX{$target}];
909
910
911 $DTCM_LIST{ $target }++; # hit and increase hit counter
912 $ADDED_ATTRIBUTE{ $struct_lineno } = $section;
913 #last;
914
915 }
916 }
917 }
918
919 }
920
921 my $number_hit_once = 0;
922 my $report_hit_once ='';
923 my $report_hit_miss ='';
924 my $report_hit_other ='';
925
926 while( ($data, $hit_cnt) = each %DTCM_LIST )
927 {
928 if( $hit_cnt == 1 )
929 {
930 $number_hit_once++;
931 $report_hit_once .= "\tTCM Variable \"$data\" is found.\n";
932
933 }elsif( $hit_cnt == 0 )
934 {
935 $report_hit_miss .= "\t$warning_prefix TCM Variable \"$data\" is missed.\n";
936
937 }else
938 {
939 $report_hit_other .= "\t$warning_prefix TCM Variable \"$data\" is found $hit_cnt times.\n";
940 }
941 }
942
943 unless( $report_hit_miss eq '' )
944 {
945 print "$report_hit_miss";
946 print FILE_LOG "$report_hit_miss";
947 }
948
949 unless( $report_hit_other eq '' )
950 {
951 print "$report_hit_other";
952 print FILE_LOG "$report_hit_other";
953 }
954
955 if($number_hit_once>0)
956 {
957 #print FILE_LOG "$report_hit_once";
958 print FILE_LOG "\t$number_hit_once TCM variables are found.\n";
959 }
960
961
962# if($brace_l_sum != $brace_r_sum)
963# {
964# print "\t$warning_prefix Left brace and right brace are not paried! { : }= $brace_l_cnt:$brace_l_cnt\n";
965# print FILE_LOG "\t$warning_prefix Left brace and right brace are not paried! { : }= $brace_l_sum:$brace_r_sum\n";
966# }
967
968 close FILE_IMM;
969
970}
971
972#-------------------------------------------------------------------
973
974sub Add_Attribute_Code
975{
976 my $file_ori = shift @_;
977 my $file_new = shift @_;
978
979 open (FILE_IN, "<$file_ori" ) or &print_error_info_die("$error_prefix Can't open original immediated file $file_ori!\n");
980 open (FILE_OUT, ">$file_new" ) or &print_error_info_die("$error_prefix Can't open output file $file_new!\n");
981
982 my $line_number = 0;
983 my $line_in = '';
984 my $log_on = 0;
985
986 while( <FILE_IN> )
987 {
988 $line_in = $_;
989 $line_number++;
990
991 if( exists $ADDED_ATTRIBUTE{$line_number} )
992 {
993 my $added = $ADDED_ATTRIBUTE{$line_number};
994 print FILE_OUT "$added ";
995 print FILE_OUT $line_in;
996
997 if( $DEBUG_MODE == 1 )
998 {
999 print FILE_LOG "$added ";
1000 $log_on = 1;
1001 }
1002
1003 }elsif( exists $REPLACED_CODE{$line_number} )
1004 {
1005 print FILE_OUT "$REPLACED_CODE{$line_number}";
1006
1007 if( $DEBUG_MODE == 1 )
1008 {
1009 print FILE_LOG "Replace $line_in";
1010 print FILE_LOG "with $REPLACED_CODE{$line_number}\n";
1011 }
1012
1013 }else
1014 {
1015 print FILE_OUT $line_in;
1016 }
1017
1018
1019
1020 if($log_on==1)
1021 {
1022 print FILE_LOG $line_in;
1023
1024 if( $line_in =~ /[={\;]/ )
1025 {
1026 $log_on= 0;
1027 print FILE_LOG "\n";
1028 }
1029 }
1030
1031 }
1032
1033 print FILE_OUT "\n$ADDED_ADT_CODE\n" if( $ADDED_ADT_CODE ne '' );
1034
1035 close FILE_IN;
1036 close FILE_OUT;
1037
1038}
1039
1040#-------------------------------------------------------------------
1041
1042sub print_error_info_die
1043{
1044 my $error_info = $_[0];
1045 print FILE_LOG $error_info;
1046 print STDERR $error_info;
1047 exit(1);
1048
1049}
1050
1051#-------------------------------------------------------------------
1052sub get_func_prototype
1053{
1054 my $func = shift @_;
1055
1056 chop($func);
1057 $func =~ s/\s*{.*//;
1058 $func =~ s/\n//g;
1059 $func =~ s/,\s+/, /g;
1060
1061 return $func;
1062}
1063
1064sub get_func_argu_names
1065{
1066 #Example:
1067 #[Input ] "void (*code)(void*), void* data"
1068 #[Output] "code, data"
1069
1070 my $argu_names = shift @_;
1071 my $func_name = shift @_;
1072
1073 $argu_names =~ s/^\s*//;
1074 $argu_names =~ s/\s*$//;
1075
1076 if( $argu_names eq 'void' )
1077 {
1078 $argu_names = ' ';
1079
1080 }else
1081 {
1082 my @argu_list = split(/,/, $argu_names);
1083 foreach( @argu_list)
1084 {
1085 s/^.*?(\w+)\s*$/$1/ or #UINT8* agc_gain_info_num_p --> agc_gain_info_num_p
1086 s/^.*?\(\s*\*\s*(\w+)\s*\)\(.*?\)\s*$/$1/ or #function pointer case: void (*code)(void*) --> code
1087 s/^.*?(\w+)(\[.*?\])+\s*$/$1/ or # EL1D_POS_AGC_GAIN_INFO_T agc_gain_info[(2)][(30)]
1088 print_error_info_die("$error_prefix Failed to extract ADT fucntion argument name: $func_name($argu_names)\n");
1089
1090 }
1091 $argu_names = join( ', ', @argu_list);
1092 }
1093
1094 return $argu_names;
1095}
1096
1097
1098
1099#-------------------------------------------------------------------