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