1 #define _POSIX_SOURCE
2 #include "tx_api.h"
3 #include "gx_api.h"
4 #include "gx_system.h"
5 #include "gx_validation_utility.h"
6 #include "gx_validation_verify.h"
7 #include "stdio.h"
8 
9 /* Check version definitions. */
10 #ifndef __PRODUCT_GUIX__
11 #error "__PRODUCT_GUIX__ is not defined."
12 #endif /* __PRODUCT_GUIX__ */
13 
14 #if defined(EXPECTED_MAJOR_VERSION) && ( !defined(__GUIX_MAJOR_VERSION) || (__GUIX_MAJOR_VERSION != EXPECTED_MAJOR_VERSION))
15 #error "__GUIX_MAJOR_VERSION"
16 #endif /* EXPECTED_MAJOR_VERSION */
17 
18 #if defined(EXPECTED_MINOR_VERSION) && ( !defined(__GUIX_MINOR_VERSION) || (__GUIX_MINOR_VERSION != EXPECTED_MINOR_VERSION))
19 #error "__GUIX_MINOR_VERSION"
20 #endif /* EXPECTED_MINOR_VERSION */
21 
22 #if defined(__linux) && defined(RUNTIME_LIMITATION)
23 #include <unistd.h>
24 #include <signal.h>
25 #include <sys/types.h>
26 #include <sys/wait.h>
27 
28 static pid_t child_pid = -1;
29 
kill_child(int sig)30 void kill_child(int sig)
31 {
32     kill(child_pid, SIGKILL);
33     printf("%s: RUNNING OUT OF TIME!\n", test_parameter.test_name);
34 }
35 #endif
36 
37 static char output_failures_file_string[256];
38 static char golden_checksum_file_string[256];
39 static char output_checksum_file_string[256];
40 static char golden_file_string[256];
41 static char output_file_string[256];
42 static char golden_file_path[128];
43 static char output_file_path[128];
44 static char golden_file_name[128];
45 static char output_file_name[128];
46 static FILE *output_file = GX_NULL;
47 static FILE *output_checksum_file = GX_NULL;
48 static FILE *output_failures_file = GX_NULL;
49 static int  do_compare = 1;
50 static int  checksum = 0;
51 static int  generate = 0;
52 
53 static int total_frames = 0;
54 static int total_failures = 0;
55 static ULONG gx_validation_frame_capture_timeout = 0;
56 static int gx_validation_frame_capture_max_frame = 0;
57 static char **gx_validation_frame_capture_comments = NULL;
58 static int gx_validation_frame_capture_comments_max = 0;
59 static int gx_validation_frame_capture_current = 0;
60 static GX_BOOL gx_validation_no_output = GX_TRUE;
61 extern TEST_PARAM test_parameter;
62 
63 char *gx_validation_frame_buffer = NULL;
64 int   gx_validation_frame_size = 0;
65 int   gx_validation_frame_id = 0;
66 char *gx_validation_frame_comment = NULL;
67 int   gx_validation_frame_width = 0;
68 int   gx_validation_frame_height = 0;
69 char *gx_validation_frame_color_depth = NULL;
70 int   gx_validation_record_frame = 0;
71 
72 TX_SEMAPHORE *gx_validation_semaphore = NULL;
73 TX_SEMAPHORE gx_validation_timer_semaphore;
74 
75 #define GX_VALIDATION_MAX_QUEUE_TIMERS  48
76 #define QUOTIENT 0x04c11db7
77 
78 static unsigned int crc_table[256];
gx_validation_crc32_init(void)79 static void gx_validation_crc32_init(void)
80 {
81     int i, j;
82 
83     unsigned int crc;
84 
85     for (i = 0; i < 256; i++)
86     {
87         crc = i << 24;
88         for (j = 0; j < 8; j++)
89         {
90             if (crc & 0x80000000)
91                 crc = (crc << 1) ^ QUOTIENT;
92             else
93                 crc = crc << 1;
94         }
95         crc_table[i] = crc;
96     }
97 }
98 
gx_validation_calc_crc(unsigned char * data,int len)99 static unsigned int gx_validation_calc_crc(unsigned char *data, int len)
100 {
101     unsigned int        result;
102     int                 i;
103 
104     result = *data++ << 24;
105     result |= *data++ << 16;
106     result |= *data++ << 8;
107     result |= *data++;
108     result = ~ result;
109     len -=4;
110 
111     for (i=0; i<len; i++)
112     {
113         result = (result << 8 | *data++) ^ crc_table[result >> 24];
114     }
115 
116     return ~result;
117 }
118 
gx_validation_setup(int argc,char ** argv)119 void gx_validation_setup(int argc, char **argv)
120 {
121 #if defined(__linux) && defined(RUNTIME_LIMITATION)
122     int status;
123 #endif
124     int i;
125 
126     memset(golden_checksum_file_string, 0, sizeof(golden_checksum_file_string));
127     memset(output_checksum_file_string, 0, sizeof(output_checksum_file_string));
128     memset(golden_file_string, 0, sizeof(golden_file_string));
129     memset(output_file_string, 0, sizeof(output_file_string));
130     memset(golden_file_path, 0, sizeof(golden_file_path));
131     memset(golden_file_name, 0, sizeof(golden_file_name));
132     memset(output_file_path, 0, sizeof(output_file_path));
133     memset(output_file_name, 0, sizeof(output_file_name));
134 
135 
136     /* Set the default golden file path and output file path */
137     memcpy(golden_file_path, DEFAULT_GOLDEN_FILE_PATH, sizeof(DEFAULT_GOLDEN_FILE_PATH));
138     memcpy(output_file_path, DEFAULT_OUTPUT_FILE_PATH, sizeof(DEFAULT_OUTPUT_FILE_PATH));
139 
140     sprintf(golden_file_name, "%s"DATAFILE_EXTENSION, test_parameter.test_name);
141     sprintf(output_file_name, "%s"DATAFILE_EXTENSION, test_parameter.test_name);
142 
143     for(i = 1; i < argc; i++)
144     {
145         if(strcmp(argv[i], GOLDEN_FILE_PATH_FLAG) == 0)
146         {
147             i++;
148             strncpy(golden_file_path, argv[i], sizeof(golden_file_path) - 1);
149         }
150         else if(strcmp(argv[i], GOLDEN_FILE_NAME_FLAG) == 0)
151         {
152             i++;
153             strncpy(golden_file_name, argv[i], sizeof(golden_file_name) - 1);
154         }
155 
156         if(strcmp(argv[i], OUTPUT_FILE_PATH_FLAG) == 0)
157         {
158             i++;
159             strncpy(output_file_path, argv[i], sizeof(output_file_path) - 1);
160         }
161         else if(strcmp(argv[i], OUTPUT_FILE_NAME_FLAG) == 0)
162         {
163             i++;
164             strncpy(output_file_name, argv[i], sizeof(output_file_name) - 1);
165         }
166         else if(strcmp(argv[i], RUN_ONLY_FLAG) == 0)
167         {
168             do_compare = 0;
169         }
170         else if(strcmp(argv[i], CHECKSUM_FLAG) == 0)
171         {
172             /* Compare with checksum. */
173             checksum = 1;
174         }
175         else if(strcmp(argv[i], GENERATE_FLAG) == 0)
176         {
177             /* Generate golden file. */
178             generate = 1;
179         }
180     }
181 
182     gx_validation_no_output = GX_FALSE;
183 
184     sprintf(output_failures_file_string, "%s%s_failures.bin", output_file_path, test_parameter.test_name);
185 
186     sprintf(golden_checksum_file_string, "%s%s.checksum", golden_file_path, test_parameter.test_name);
187     sprintf(output_checksum_file_string, "%s%s.checksum", output_file_path, test_parameter.test_name);
188 
189     strncpy(golden_file_string, golden_file_path, sizeof(golden_file_string));
190     strncat(golden_file_string, golden_file_name, sizeof(golden_file_string));
191     strncpy(output_file_string, output_file_path, sizeof(output_file_string));
192     strncat(output_file_string, output_file_name, sizeof(output_file_string));
193 
194     if(generate || checksum)
195     {
196         gx_validation_crc32_init();
197     }
198 
199     if(do_compare)
200     {
201         if(checksum)
202         {
203             gx_validation_verify_start(test_parameter.test_name, golden_checksum_file_string, checksum);
204         }
205         else
206         {
207             gx_validation_verify_start(test_parameter.test_name, golden_file_string, checksum);
208         }
209 
210     }
211 
212 #if defined(__linux) && defined(RUNTIME_LIMITATION)
213     signal(SIGALRM, (void (*)(int))kill_child);
214     child_pid = fork();
215     if (child_pid > 0)
216     {
217         alarm(RUNTIME_LIMITATION);
218         wait(&status);
219         exit(WEXITSTATUS(status));
220     }
221 #endif
222 }
223 
gx_validation_frame_info_set(char * color_depth,int width,int height)224 void gx_validation_frame_info_set(char *color_depth, int width, int height)
225 {
226     gx_validation_frame_width = width;
227     gx_validation_frame_height = height;
228     gx_validation_frame_color_depth = color_depth;
229 }
230 
gx_validation_write_output_file_header(FILE * output_file)231 void gx_validation_write_output_file_header(FILE *output_file)
232 {
233     fputs(TOTAL_FRAMES"          \n", output_file);
234     fprintf(output_file, FILE_FORMAT"%d\n", FILE_FORMAT_VERSION_CURRENT);
235     fprintf(output_file, GX_VERSION_MAJOR"%d\n", __GUIX_MAJOR_VERSION);
236     fprintf(output_file, GX_VERSION_MINOR"%d\n", __GUIX_MINOR_VERSION);
237     fprintf(output_file, FILE_CREATE_DATE"%s %s\n", __DATE__, __TIME__);
238     fprintf(output_file, COLOR_DEPTH"%s\n", gx_validation_frame_color_depth);
239     fprintf(output_file, WIDTH"%d\n", gx_validation_frame_width);
240     fprintf(output_file, HEIGHT"%d\n", gx_validation_frame_height);
241 }
242 
gx_validation_create_output_file(char * color_depth,int width,int height)243 int gx_validation_create_output_file(char *color_depth, int width, int height)
244 {
245     gx_validation_frame_info_set(color_depth, width, height);
246 
247     /* Open output file for write */
248     if(generate)
249     {
250         output_file = fopen(output_file_string, "wb");
251         output_checksum_file = fopen(output_checksum_file_string, "wb");
252 
253         if((output_file == 0) || (output_checksum_file == 0))
254         {
255             return -1;
256         }
257         gx_validation_write_output_file_header(output_file);
258         gx_validation_write_output_file_header(output_checksum_file);
259     }
260     return 0;
261 }
262 
gx_validation_create_output_failures_file()263 int gx_validation_create_output_failures_file()
264 {
265     output_failures_file = fopen(output_failures_file_string, "wb");
266 
267     if(output_failures_file == 0)
268     {
269         return -1;
270     }
271 
272     gx_validation_write_output_file_header(output_failures_file);
273 
274     return 0;
275 }
276 
gx_validation_create_frame_buffer(int frame_size)277 int gx_validation_create_frame_buffer(int frame_size)
278 {
279     /* Allocate memory for frame buffer. */
280     if(gx_validation_frame_buffer)
281     {
282         free(gx_validation_frame_buffer);
283         gx_validation_frame_buffer = NULL;
284     }
285 
286     gx_validation_frame_size = frame_size;
287 
288     gx_validation_frame_buffer = (char *)malloc(frame_size);
289     memset(gx_validation_frame_buffer, 0, frame_size);
290 
291     if(!gx_validation_no_output)
292     {
293         tx_semaphore_create(&gx_validation_timer_semaphore, "timer_semaphore", 0);
294         _gx_system_timer.tx_timer_internal.tx_timer_internal_timeout_function = gx_validation_system_timer_expiration;
295     }
296 
297     return(0);
298 }
299 
gx_validation_write_one_frame(FILE * file)300 void gx_validation_write_one_frame(FILE *file)
301 {
302     /* Write the frame number */
303     fprintf(file, "\n\n"FRAME_ID"%d\n", gx_validation_frame_id);
304     if(gx_validation_frame_comment)
305     {
306         fprintf(file, FRAME_COMMENT"%s\n", gx_validation_frame_comment);
307     }
308     fprintf(file, FRAME_DATA"\n");
309 
310     /* Write the frame data */
311     fwrite((char *)gx_validation_frame_buffer, sizeof(char), gx_validation_frame_size, file);
312 
313 }
314 
gx_validation_write_frame_buffer(void)315 void gx_validation_write_frame_buffer(void)
316 {
317 unsigned int result = 0;
318 int status;
319 TX_INTERRUPT_SAVE_AREA
320 
321     TX_DISABLE
322 
323     gx_validation_record_frame = 0;
324 
325     if(generate || checksum)
326     {
327         /* Calculate checksum for canvas data. */
328         result = gx_validation_calc_crc((unsigned char *)gx_validation_frame_buffer, gx_validation_frame_size);
329     }
330 
331     if(generate)
332     {
333         if(output_file)
334         {
335             gx_validation_write_one_frame(output_file);
336         }
337 
338         if(output_checksum_file)
339         {
340             /* Write the frame number */
341             fprintf(output_checksum_file, "\n\n"FRAME_ID"%d\n", gx_validation_frame_id);
342             fprintf(output_checksum_file, FRAME_DATA"\n");
343 
344             /* Write checksum value. */
345             fwrite((void *)&result, sizeof(result), sizeof(result), output_checksum_file);
346         }
347     }
348 
349     if(do_compare)
350     {
351         if(checksum)
352         {
353             /* Verify frame with checksum, */
354             status = gx_validation_verify_one_frame((void *)&result, sizeof(result), gx_validation_frame_id);
355         }
356         else
357         {
358             /* Verify frame with canvas data. */
359             status = gx_validation_verify_one_frame(gx_validation_frame_buffer,
360                                                     gx_validation_frame_size,
361                                                     gx_validation_frame_id);
362         }
363 
364         if(status != GX_VALIDATION_SUCCESS)
365         {
366             if(total_failures == 0)
367             {
368                 if (gx_validation_create_output_failures_file() == 0)
369                 {
370                     gx_validation_write_one_frame(output_failures_file);
371                 }
372             }
373 
374             total_failures++;
375         }
376     }
377 
378     gx_validation_frame_comment = NULL;
379 
380     TX_RESTORE
381     total_frames++;
382 
383     /* If we are in the frame catpure mode, set up information for the next frame. */
384     if((gx_validation_frame_capture_timeout >= tx_time_get()) &&
385        (gx_validation_frame_capture_current != gx_validation_frame_capture_max_frame))
386     {
387         gx_validation_frame_id ++;
388 
389         gx_validation_frame_capture_current++;
390 
391         if(gx_validation_frame_capture_current < gx_validation_frame_capture_comments_max)
392         {
393             gx_validation_frame_comment = gx_validation_frame_capture_comments[gx_validation_frame_capture_current];
394         }
395 
396         if(gx_validation_frame_capture_current != gx_validation_frame_capture_max_frame)
397         {
398             gx_validation_record_frame = 1;
399         }
400     }
401 
402     if(gx_validation_frame_capture_current == gx_validation_frame_capture_max_frame)
403     {
404         if(gx_validation_semaphore)
405         {
406             tx_semaphore_put(gx_validation_semaphore);
407         }
408     }
409 }
410 
gx_validation_validate_data_frame(char * golden_file,char * test_output)411 int gx_validation_validate_data_frame(char *golden_file, char *test_output)
412 {
413     return(0);
414 
415 }
416 
gx_validation_close_output_file(void)417 void gx_validation_close_output_file(void)
418 {
419     if(output_file)
420     {
421         fseek(output_file, 0, SEEK_SET);
422         /* skip the first line, which is the file format info */
423 
424         fprintf(output_file, TOTAL_FRAMES"%d\n", total_frames);
425         fclose(output_file);
426     }
427 
428     if(output_checksum_file)
429     {
430         fseek(output_checksum_file, 0, SEEK_SET);
431         /* skip the first line, which is the file format info */
432 
433         fprintf(output_checksum_file, TOTAL_FRAMES"%d\n", total_frames);
434         fclose(output_checksum_file);
435 
436     }
437 
438     if(output_failures_file)
439     {
440        fseek(output_failures_file, 0, SEEK_SET);
441 
442        /* skip the first line, which is the file format info */
443        fprintf(output_failures_file, TOTAL_FRAMES"%d\n", total_failures);
444        fclose(output_failures_file);
445     }
446 }
447 
gx_validation_end(void)448 void gx_validation_end(void)
449 {
450     GX_ENTER_CRITICAL
451     gx_validation_close_output_file();
452 
453     if(gx_validation_frame_buffer)
454     {
455         free(gx_validation_frame_buffer);
456         gx_validation_frame_buffer = NULL;
457         gx_validation_frame_size = 0;
458     }
459 
460     if(gx_validation_semaphore)
461     {
462         tx_semaphore_delete(gx_validation_semaphore);
463         gx_validation_semaphore = NULL;
464     }
465 
466     if(do_compare)
467     {
468         gx_validation_verify_end(total_frames);
469     }
470     GX_EXIT_CRITICAL
471 }
472 
gx_validation_watchdog_create(int tick)473 void gx_validation_watchdog_create(int tick)
474 {
475 
476 }
477 
gx_validation_set_frame_comment(char * comment)478 void gx_validation_set_frame_comment(char *comment)
479 {
480     gx_validation_frame_comment = comment;
481 }
482 
gx_validation_set_frame_id(int frame_id)483 void gx_validation_set_frame_id(int frame_id)
484 {
485     gx_validation_frame_id = frame_id;
486     gx_validation_record_frame = 1;
487 
488     /* Clear any capture operation started early on */
489     if(gx_validation_frame_capture_timeout)
490     {
491         gx_validation_frame_capture_timeout = 0;
492         gx_validation_frame_capture_max_frame = 0;
493         gx_validation_frame_capture_comments = NULL;
494         gx_validation_frame_capture_comments_max = 0;
495         gx_validation_frame_capture_current = 0;
496     }
497 }
498 
gx_validation_capture_frames(int start_id,int expected_frames,char ** comments,int num_comments,int max_time)499 void gx_validation_capture_frames(int start_id, int expected_frames, char **comments, int num_comments, int max_time)
500 {
501     gx_validation_frame_capture_timeout = tx_time_get() + max_time;
502     gx_validation_frame_id = start_id;
503     gx_validation_frame_capture_max_frame = expected_frames;
504     gx_validation_frame_capture_comments = comments;
505     gx_validation_frame_capture_comments_max = num_comments;
506     gx_validation_frame_capture_current = 0;
507 
508     if(num_comments && comments)
509         gx_validation_frame_comment = comments[0];
510 
511     if(!gx_validation_semaphore)
512     {
513         gx_validation_semaphore = (TX_SEMAPHORE *)malloc(sizeof(TX_SEMAPHORE));
514         tx_semaphore_create(gx_validation_semaphore, "capture_semaphore", 0);
515     }
516     gx_validation_record_frame = 1;
517 }
518 
gx_validation_capture_frames_wait()519 void gx_validation_capture_frames_wait()
520 {
521     tx_semaphore_get(gx_validation_semaphore, 1000);
522 }
523 
gx_validation_current_frame_id_get(int * current_frame)524 void gx_validation_current_frame_id_get(int *current_frame)
525 {
526     *current_frame = gx_validation_frame_id;
527 
528     return;
529 
530 }
531 
532 
gx_validation_screen_refresh(void)533 void gx_validation_screen_refresh(void)
534 {
535 GX_EVENT my_event;
536 
537     memset(&my_event, 0, sizeof(GX_EVENT));
538     my_event.gx_event_type = GX_EVENT_REDRAW;
539     gx_system_event_send(&my_event);
540 }
541 
542 
543 static TX_THREAD control_thread;
544 static ULONG     control_thread_stack[CONTROL_STACK_SIZE / sizeof(ULONG)];
545 static TX_THREAD timer_control_thread;
546 static ULONG     timer_control_thread_stack[CONTROL_STACK_SIZE / sizeof(ULONG)];
547 
timer_control_thread_entry()548 void timer_control_thread_entry()
549 {
550 TX_INTERRUPT_SAVE_AREA
551 
552     while(1)
553     {
554         tx_semaphore_get(&gx_validation_timer_semaphore, TX_WAIT_FOREVER);
555         while(_gx_system_event_queue.tx_queue_enqueued != 0)
556         {
557             tx_thread_sleep(1);
558         }
559 
560         TX_DISABLE
561         _gx_system_timer_expiration(0);
562         TX_RESTORE
563   }
564 }
565 
gx_validation_control_thread_create(VOID (* func)(ULONG))566 void gx_validation_control_thread_create(VOID (*func)(ULONG))
567 {
568     tx_thread_create(&control_thread, "GUIX Validation Control Thread", func,
569                      0, control_thread_stack, sizeof(control_thread_stack),
570                      CONTROL_THREAD_PRIORITY, CONTROL_THREAD_PRIORITY,
571                      TX_NO_TIME_SLICE, TX_AUTO_START);
572 
573     if(!gx_validation_no_output)
574     {
575         tx_thread_create(&timer_control_thread, "GUIX Validation Timer Control Thread", timer_control_thread_entry,
576                          0, timer_control_thread_stack, sizeof(timer_control_thread_stack),
577                          CONTROL_THREAD_PRIORITY, CONTROL_THREAD_PRIORITY,
578                          TX_NO_TIME_SLICE, TX_AUTO_START);
579     }
580 }
581 
582 
gx_validation_write_palette(ULONG * palette,int size)583 void gx_validation_write_palette(ULONG *palette, int size)
584 {
585 int i;
586 
587     if(generate && output_file)
588     {
589         GX_ENTER_CRITICAL
590         fprintf(output_file, "\nPALETTE DATA SIZE: %d\n", size);
591         fprintf(output_file, "PALETTE DATA:\n");
592         for(i = 0; i < size; i++)
593         {
594             fprintf(output_file, "%lu ", palette[i]);
595         }
596         fprintf(output_file, "\n");
597         GX_EXIT_CRITICAL
598     }
599 }
600 
gx_validation_system_timer_expiration(ULONG val)601 void gx_validation_system_timer_expiration(ULONG val)
602 {
603     tx_semaphore_put(&gx_validation_timer_semaphore);
604 }
605 
gx_validation_print_test_result(int result)606 void gx_validation_print_test_result(int result)
607 {
608 char *test_padder = "................................................................................";
609 
610     if(result == TEST_SUCCESS)
611     {
612         printf("Guix Test:   %s%sSuccess!\n", test_parameter.test_name, test_padder + strlen(test_parameter.test_name));
613     }
614     else
615     {
616         printf("Guix Test:   %s%s.Failed!\n", test_parameter.test_name, test_padder + strlen(test_parameter.test_name));
617     }
618 }
619 
gx_validation_extract_path(char * pathname,char * path,int * pathlen)620 void gx_validation_extract_path(char *pathname, char *path, int *pathlen)
621 {
622 int index = strlen(pathname) - 1;
623 
624     while(index >= 0)
625     {
626         if(pathname[index] == '/')
627         {
628             memcpy(path, pathname, index+1);
629             path[index + 1]='\0';
630             break;
631         }
632         index--;
633     }
634 
635    *pathlen = index + 1;
636 }
637