Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / fnx / clib / report / cc / cReport.cc
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: cReport.cc
4// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
5// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
6//
7// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8//
9// This program is free software; you can redistribute it and/or modify
10// it under the terms of the GNU General Public License as published by
11// the Free Software Foundation; version 2 of the License.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21//
22// For the avoidance of doubt, and except that if any non-GPL license
23// choice is available it will apply instead, Sun elects to use only
24// the General Public License version 2 (GPLv2) at this time for any
25// software where a choice of GPL license versions is made
26// available with the language indicating that GPLv2 or any later version
27// may be used, or where a choice of which version of the GPL is applied is
28// otherwise unspecified.
29//
30// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
31// CA 95054 USA or visit www.sun.com if you need additional information or
32// have any questions.
33//
34// ========== Copyright Header End ============================================
35
36#include <stdio.h>
37#include <stdarg.h>
38#include <string.h>
39#include "cReport.h"
40#include "report_msg_format.h"
41#include "report_info.h"
42
43extern "C" int g_cycle_count, g_death_cycle_count, g_exit_on_error;
44
45
46////////////////////////////////////////////////////////////////////////////////
47// Class variable definitions
48//
49PrintLevel ReportClass::global_print_threshold = REPORT_DEFAULT_PRINT_THRESHOLD;
50int ReportClass::max_error_count = REPORT_DEFAULT_MAX_ERROR_COUNT;
51int ReportClass::global_error_count = 0;
52int ReportClass::global_warning_count = 0;
53int ReportClass::use_short_pathnames = 0;
54const char* ReportClass::path_prefix = "";
55int ReportClass::num_remaining_nonfatal_cycles = 0;
56int ReportClass::show_simulation_time = 0;
57int ReportClass::global_print_threshold_locked_by = REPORT_LOCKED_BY_NO_ONE;
58int ReportClass::report_type_display_locked_by[R_NUM_REPORT_TYPES];
59
60////////////////////////////////////////////////////////////////////////////////
61//
62// Message display functions
63
64
65// ReportClass::report
66//
67// Display a message of the given type. The message will use
68// the current print level and error level for this report type.
69// Accepts a printf-like format string and arg list.
70//
71//
72void ReportClass::report(ReportType report_type,
73 const char* time_str, const char* location_str, const char* format_str, ...)
74{
75 void* varargs[REPORT_MAX_NUM_VARARGS];
76 const char* prefix_str;
77 PrintLevel my_print_level = get_print_level(report_type);
78 ErrorLevel my_error_level = get_error_level(report_type);
79
80 // Actually do the output, if the print level is appropriate.
81 if (my_print_level >= global_print_threshold) {
82 // review: 1. Support output redirection here!!!
83
84
85 // - if fatal errors are disabled, make errors into warnings.
86 if (num_remaining_nonfatal_cycles > 0 && my_error_level == RERR_ERROR)
87 prefix_str = get_prefix(report_type, RERR_MESSAGE);
88 else
89 prefix_str = get_prefix(report_type, my_error_level);
90
91
92 if (!get_table_mode(report_type)) {
93 fprintf(stdout, REPORT_MSG_FORMAT_STRING, prefix_str, time_str, location_str);
94 }
95
96 // If fatal error, output the error type.
97 if (my_error_level == RERR_ERROR) {
98 fprintf(stdout, "%s: ", report_type_to_str(report_type));
99 }
100
101 // Print message string, extracting any arguments from the varargs list.
102 // Use the format string to find out how many arguments we should expect.
103 {
104 va_list ap;
105 const char *fp = format_str;
106 int i, j = 0;
107
108 for (i = 0; i < REPORT_MAX_NUM_VARARGS; i++)
109 varargs[i] = 0;
110
111 va_start(ap, format_str);
112 while (fp = strchr(fp, '%'))
113 {
114 // Found another '%' in the formatting string.
115 // If it's actually associated with a vararg, grab the next one.
116 if (*(++fp) != '%')
117 varargs[j++] = va_arg(ap, void*);
118 }
119 va_end(ap);
120 }
121 // This is it. This is where the message is finally printed.
122 fprintf(stdout, format_str,
123 varargs[0], varargs[1], varargs[2], varargs[3], varargs[4],
124 varargs[5], varargs[6], varargs[7], varargs[8], varargs[9]);
125
126 // Print newline (if not in table mode)
127 if (!get_table_mode(report_type)) {
128 fprintf(stdout, "\n");
129 }
130 }
131
132 // If this report produced a fatal error or a warning, deal with the situation.
133 if (my_error_level == RERR_ERROR) {
134 if (get_num_remaining_nonfatal_cycles() == 0) {
135 // Increase the ReportClass's global error count,
136 // but only if fatal errors are not currently disabled!
137 inc_global_error_count();
138 }
139
140 // If this error pushed us over the maximum number of allowable errors,
141 // schedule a cycle soon in which the sim will be killed.
142 if(get_global_error_count() >= get_max_error_count()
143 && !g_death_cycle_count
144 && g_exit_on_error) {
145 g_death_cycle_count = g_cycle_count + REPORT_DEATH_CYCLE_DELAY;
146 fprintf(stdout, "Report:(%0d) [PLI] Scheduling $finish for cycle %0d\n", g_cycle_count, g_death_cycle_count);
147 // Call user handler
148 handle_error();
149 }
150
151 } else if (my_error_level == RERR_WARNING) {
152 // Increase the ReportClass's global warning count.
153 inc_global_warning_count();
154 }
155
156} // ReportClass::report(...)
157
158
159// ReportClass:report_test_complete
160//
161void ReportClass::report_test_complete(int finish_cycle)
162{
163 fprintf(stdout, REPORT_TEST_DONE_FORMAT_STRING, finish_cycle, get_global_error_count(), get_global_warning_count());
164}
165
166
167// ReportClass::will_this_print
168//
169// Return true if the report_type will print, false otherwise
170//
171//
172int ReportClass::this_will_print(ReportType report_type)
173{
174 //fprintf(stdout,"ReportClass::this_will_print: report_type: %d(%d), global_print_threshold: %d\n",
175 //report_type, get_print_level(report_type), global_print_threshold);
176 return( get_print_level(report_type) >= global_print_threshold);
177}
178
179
180////////////////////////////////////////////////////////////////////////////////
181// Accessors for class variables
182
183
184// ReportClass::set_global_print_threshold
185//
186// This accessor may be called with a "lock" variable to prevent further changes.
187// This can be used to lock in changes from the command line, for example.
188// NOTE! The lock variable can only be set once; further changes are ignored.
189//
190//
191void ReportClass::set_global_print_threshold(PrintLevel new_print_threshold, int locked_by)
192{
193 ReportClass temp_report;
194
195 if (ReportClass::global_print_threshold_locked_by == REPORT_LOCKED_BY_NO_ONE)
196 {
197 // No lock currently set for the print threshold.
198 if (locked_by != REPORT_LOCKED_BY_NO_ONE)
199 {
200 // Set the new lock.
201 temp_report.report(RTYP_REPORT_MSG, REPORT_CPP_DEFAULT_TIME_STR, REPORT_CPP_DEFAULT_LOCATION_STR,
202 "Locked global print threshold to %s -- further changes will be ignored",
203 print_level_to_str(new_print_threshold));
204 ReportClass::global_print_threshold_locked_by = locked_by;
205 }
206 else
207 {
208 // No new lock specified -- just change the thing.
209 temp_report.report(RTYP_REPORT_MSG, REPORT_CPP_DEFAULT_TIME_STR, REPORT_CPP_DEFAULT_LOCATION_STR,
210 "Changing global print threshold from %s to %s",
211 print_level_to_str(ReportClass::global_print_threshold),
212 print_level_to_str(new_print_threshold));
213 }
214 ReportClass::global_print_threshold = new_print_threshold;
215 }
216 else
217 {
218 // Print threshold has already been locked.
219 // Only allow changes if 'locked_by' matches the lock.
220 if (locked_by == ReportClass::global_print_threshold_locked_by)
221 {
222 temp_report.report(RTYP_REPORT_MSG, REPORT_CPP_DEFAULT_TIME_STR, REPORT_CPP_DEFAULT_LOCATION_STR,
223 "Changing global print threshold from %s to %s",
224 print_level_to_str(ReportClass::global_print_threshold),
225 print_level_to_str(new_print_threshold));
226 ReportClass::global_print_threshold = new_print_threshold;
227 }
228 else
229 {
230 temp_report.report(RTYP_REPORT_MSG, REPORT_CPP_DEFAULT_TIME_STR, REPORT_CPP_DEFAULT_LOCATION_STR,
231 "Can't change global print threshold to %s -- it's locked!",
232 print_level_to_str(new_print_threshold));
233 }
234 }
235}
236
237
238// ReportClass::get_global_print_threshold
239//
240PrintLevel ReportClass::get_global_print_threshold()
241{
242 return global_print_threshold;
243}
244
245
246// ReportClass::set_max_error_count
247//
248void ReportClass::set_max_error_count(int error_count)
249{
250 ReportClass temp_report;
251 temp_report.report(RTYP_REPORT_MSG, REPORT_CPP_DEFAULT_TIME_STR, REPORT_CPP_DEFAULT_LOCATION_STR,
252 "Changing maximum error count from %d to %d", max_error_count, error_count);
253 max_error_count = error_count;
254}
255
256// ReportClass::get_max_error_count
257//
258int ReportClass::get_max_error_count()
259{
260 return max_error_count;
261}
262
263// ReportClass::get_global_error_count
264//
265int ReportClass::get_global_error_count()
266{
267 return global_error_count;
268}
269
270
271// ReportClass::inc_global_error_count
272//
273// Increase the global error count and generate a "fatal error" report
274// which should cause a test to be marked as failing.
275// NOTE: The simulation itself should be killed by the calling code!
276//
277///
278void ReportClass::inc_global_error_count()
279{
280 ReportClass temp_report;
281 if (++global_error_count == max_error_count)
282 {
283 temp_report.report(RTYP_REPORT_MSG, REPORT_CPP_DEFAULT_TIME_STR, REPORT_CPP_DEFAULT_LOCATION_STR,
284 "Maximum error count of %d has been reached!", max_error_count);
285 }
286}
287
288
289// ReportClass::get_global_warning_count
290//
291int ReportClass::get_global_warning_count()
292{
293 return global_warning_count;
294}
295
296// ReportClass::inc_global_warning_count
297//
298void ReportClass::inc_global_warning_count()
299{
300 ++global_warning_count;
301}
302
303
304// ReportClass::set_short_pathnames
305//
306void ReportClass::set_short_pathnames(int use_short)
307{
308 ReportClass temp_report;
309 if (use_short)
310 temp_report.report(RTYP_REPORT_MSG, REPORT_CPP_DEFAULT_TIME_STR, REPORT_CPP_DEFAULT_LOCATION_STR, "Using short pathnames.");
311 else
312 temp_report.report(RTYP_REPORT_MSG, REPORT_CPP_DEFAULT_TIME_STR, REPORT_CPP_DEFAULT_LOCATION_STR, "Using long pathnames.");
313 use_short_pathnames = use_short;
314}
315
316// ReportClass::get_short_pathnames
317//
318int ReportClass::get_short_pathnames()
319{
320 return use_short_pathnames;
321}
322
323
324//
325void ReportClass::set_path_prefix(const char* prefix)
326{
327 ReportClass temp_report;
328 temp_report.report(RTYP_REPORT_MSG, REPORT_CPP_DEFAULT_TIME_STR, REPORT_CPP_DEFAULT_LOCATION_STR,
329 "Setting path prefix to %s", prefix);
330 path_prefix = prefix;
331}
332
333
334//
335const char* ReportClass::get_path_prefix()
336{
337 return path_prefix;
338}
339
340
341// ReportClass::disable_fatal_errors
342//
343void ReportClass::disable_fatal_errors(int num_cycles)
344{
345 if (num_cycles > 0)
346 {
347 ReportClass temp_report;
348 temp_report.report(RTYP_REPORT_MSG, REPORT_CPP_DEFAULT_TIME_STR, REPORT_CPP_DEFAULT_LOCATION_STR,
349 "Disabling fatal errors for %0d cycles.", num_cycles);
350 num_remaining_nonfatal_cycles = num_cycles;
351 }
352}
353
354
355// ReportClass::get_num_remaining_nonfatal_cycles
356//
357int ReportClass::get_num_remaining_nonfatal_cycles()
358{
359 return num_remaining_nonfatal_cycles;
360}
361
362
363// ReportClass::dec_num_remaining_nonfatal_cycles
364//
365void ReportClass::dec_num_remaining_nonfatal_cycles()
366{
367 if (get_num_remaining_nonfatal_cycles() == 0)
368 {
369 ReportClass temp_report;
370 temp_report.report(RTYP_WARNING, REPORT_CPP_DEFAULT_TIME_STR, REPORT_CPP_DEFAULT_LOCATION_STR,
371 "Attempting to decrement a num_remaining_nonfatal_cycles of zero!");
372 }
373 else
374 num_remaining_nonfatal_cycles--;
375}
376
377// ReportClass::set_show_simulation_time
378//
379void ReportClass::set_show_simulation_time(int sim_time)
380{
381 ReportClass temp_report;
382 if (!sim_time)
383 temp_report.report(RTYP_REPORT_MSG, REPORT_CPP_DEFAULT_TIME_STR, REPORT_CPP_DEFAULT_LOCATION_STR,
384 "Not displaying simulation time.");
385 else
386 temp_report.report(RTYP_REPORT_MSG, REPORT_CPP_DEFAULT_TIME_STR, REPORT_CPP_DEFAULT_LOCATION_STR,
387 "Displaying simulation time.");
388 show_simulation_time = sim_time;
389}
390
391
392// ReportClass::get_show_simulation_time
393//
394int ReportClass::get_show_simulation_time()
395{
396 return show_simulation_time;
397}
398
399////////////////////////////////////////////////////////////////////////////////
400//
401// Accessors for instance variables
402
403// ReportClass::set_default_print_level
404// Changes the print level of all messages which have not thus far been
405// overridden by set_print_level.
406//
407void ReportClass::set_default_print_level(ReportType report_type, PrintLevel new_print_level) {
408 report(RTYP_REPORT_MSG, REPORT_CPP_DEFAULT_TIME_STR,
409 REPORT_CPP_DEFAULT_LOCATION_STR, "Setting *default* print level for type %s to %s",
410 report_type_to_str(report_type),
411 print_level_to_str(new_print_level));
412
413 // If the type is "ALL_REPORTS", set everything. Otherwise, just set the desired type.
414 if (report_type == RTYP_ALL_REPORTS) {
415 for (int type = __RTYP_FIRST_TYPE; type <= __RTYP_LAST_TYPE; type++) {
416 default_print_level_by_type[type] = new_print_level;
417 }
418 } else {
419 default_print_level_by_type[report_type] = new_print_level;
420 }
421}
422
423
424// ReportClass::set_default_error_level
425// Changes the error level of all messages which have not thus far been
426// overridden by set_error_level.
427//
428void ReportClass::set_default_error_level(ReportType report_type, ErrorLevel new_error_level) {
429 report(RTYP_REPORT_MSG, REPORT_CPP_DEFAULT_TIME_STR,
430 REPORT_CPP_DEFAULT_LOCATION_STR, "Setting *default* error level for type %s to %s",
431 report_type_to_str(report_type),
432 error_level_to_str(new_error_level));
433
434 // If the type is "ALL_REPORTS", set everything. Otherwise, just set the desired type.
435 if (report_type == RTYP_ALL_REPORTS) {
436 for (int type = __RTYP_FIRST_TYPE; type <= __RTYP_LAST_TYPE; type++) {
437 default_error_level_by_type[type] = new_error_level;
438 }
439 } else {
440 default_error_level_by_type[report_type] = new_error_level;
441 }
442}
443
444
445// ReportClass::set_default_table_mode
446// Changes the table_mode of all messages which have not thus far been
447// overridden by set_table_mode.
448//
449void ReportClass::set_default_table_mode(ReportType report_type, int mode) {
450 report(RTYP_REPORT_MSG, REPORT_CPP_DEFAULT_TIME_STR,
451 REPORT_CPP_DEFAULT_LOCATION_STR, "Setting *default* print level for type %s to %s",
452 report_type_to_str(report_type),
453 mode ? "ON" : "OFF");
454
455 // If the type is "ALL_REPORTS", set everything. Otherwise, just set the desired type.
456 if (report_type == RTYP_ALL_REPORTS) {
457 for (int type = __RTYP_FIRST_TYPE; type <= __RTYP_LAST_TYPE; type++) {
458 default_table_mode_by_type[type] = mode;
459 }
460 } else {
461 default_table_mode_by_type[report_type] = mode;
462 }
463}
464
465//////////////////////////////////////////////////////////////////
466//
467// ReportClass::set_print_level
468// Changes the print level of this message type only, on this
469// ReportClass instance only.
470//
471void ReportClass::set_print_level(ReportType report_type, PrintLevel new_print_level, int silent) {
472 if (!silent) {
473 report(RTYP_REPORT_MSG, REPORT_CPP_DEFAULT_TIME_STR,
474 REPORT_CPP_DEFAULT_LOCATION_STR, "Setting print level for type %s to %s",
475 report_type_to_str(report_type),
476 print_level_to_str(new_print_level));
477 }
478
479 if (localized_print_level_by_type == NULL) {
480 // copy the default array.
481 localized_print_level_by_type = new PrintLevel[R_NUM_REPORT_TYPES];
482 for (int type = __RTYP_FIRST_TYPE; type <= __RTYP_LAST_TYPE; type++) {
483 localized_print_level_by_type[type] = default_print_level_by_type[type];
484 }
485 }
486
487 // If the type is "ALL_REPORTS", set everything. Otherwise, just set the desired type.
488 if (report_type == RTYP_ALL_REPORTS) {
489 for (int type = __RTYP_FIRST_TYPE; type <= __RTYP_LAST_TYPE; type++) {
490 localized_print_level_by_type[type] = new_print_level;
491 }
492 } else {
493 localized_print_level_by_type[report_type] = new_print_level;
494 }
495}
496
497
498// ReportClass::get_print_level
499//
500PrintLevel ReportClass::get_print_level(ReportType report_type) {
501 return localized_print_level_by_type == NULL ? default_print_level_by_type[report_type] : localized_print_level_by_type[report_type];
502}
503
504
505// ReportClass::set_error_level
506// Changes the error level of this message type only, on this
507// ReportClass instance only.
508//
509void ReportClass::set_error_level(ReportType report_type, ErrorLevel new_error_level, int silent) {
510 if (!silent) {
511 report(RTYP_REPORT_MSG, REPORT_CPP_DEFAULT_TIME_STR,
512 REPORT_CPP_DEFAULT_LOCATION_STR, "Setting error level for type %s to %s",
513 report_type_to_str(report_type),
514 error_level_to_str(new_error_level));
515 }
516
517 if (localized_error_level_by_type == NULL) {
518 // copy the default array.
519 localized_error_level_by_type = new ErrorLevel[R_NUM_REPORT_TYPES];
520 for (int type = __RTYP_FIRST_TYPE; type <= __RTYP_LAST_TYPE; type++) {
521 localized_error_level_by_type[type] = default_error_level_by_type[type];
522 }
523 }
524
525 // If the type is "ALL_REPORTS", set everything. Otherwise, just set the desired type.
526 if (report_type == RTYP_ALL_REPORTS) {
527 for (int type = __RTYP_FIRST_TYPE; type <= __RTYP_LAST_TYPE; type++) {
528 localized_error_level_by_type[type] = new_error_level;
529 }
530 } else {
531 localized_error_level_by_type[report_type] = new_error_level;
532 }
533}
534
535// ReportClass::get_error_level
536//
537ErrorLevel ReportClass::get_error_level(ReportType report_type) {
538 return localized_error_level_by_type == NULL ? default_error_level_by_type[report_type] : localized_error_level_by_type[report_type];
539}
540
541
542// ReportClass::set_table_mode
543//
544void ReportClass::set_table_mode(ReportType report_type, int mode, int silent) {
545 if (!silent) {
546 report(RTYP_REPORT_MSG, REPORT_CPP_DEFAULT_TIME_STR,
547 REPORT_CPP_DEFAULT_LOCATION_STR, "Set table mode for type %s to %s.",
548 report_type_to_str(report_type),
549 mode ? "ON" : "OFF");
550 }
551
552 if (localized_table_mode_by_type == NULL) {
553 // copy the default array.
554 localized_table_mode_by_type = new int[R_NUM_REPORT_TYPES];
555 for (int type = __RTYP_FIRST_TYPE; type <= __RTYP_LAST_TYPE; type++) {
556 localized_table_mode_by_type[type] = default_table_mode_by_type[type];
557 }
558 }
559
560 // If the type is "ALL_REPORTS", set everything. Otherwise, just set the desired type.
561 if (report_type == RTYP_ALL_REPORTS) {
562 for (int type = __RTYP_FIRST_TYPE; type <= __RTYP_LAST_TYPE; type++) {
563 localized_table_mode_by_type[type] = mode;
564 }
565 } else {
566 localized_table_mode_by_type[report_type] = mode;
567 }
568}
569
570
571// ReportClass::get_table_mode
572//
573int ReportClass::get_table_mode(ReportType report_type) {
574 return localized_table_mode_by_type == NULL ? default_table_mode_by_type[report_type] : localized_table_mode_by_type[report_type];
575}
576
577//
578////////////////////////////////////////////////////////////////////////////////
579
580