cmicx_sim_util.c (6560B)
1 /* 2 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 3 * 4 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 5 */ 6 7 8 /* 9 * cmicx_sim_util.c 10 * 11 * does definitions for stuff in cmicx_sim_util.h. this includes output logging functions, error logging functions, etc. 12 */ 13 14 15 /* includes */ 16 #include <stdio.h> 17 #include <string.h> 18 #include <stdlib.h> 19 #include <time.h> 20 #ifndef CMICX_STANDALONE_SIM 21 #include <../systems/sim/pcid/cmicx_sim_util.h> 22 #include <../systems/sim/pcid/cmicx_sim_schan.h> 23 #include <../systems/sim/pcid/cmicsim.h> 24 #include <../include/soc/schanmsg.h> 25 26 #else 27 #include "cmicx_sim_util.h" 28 #endif 29 30 31 /* static global variables for cmicx sim log functions. file pointer for the log file - since we only need this in this file. */ 32 static FILE *cmicx_log_file; 33 static int cmicx_current_log_level; 34 static int cmicx_cutoff_log_level; 35 36 /* external cmicx global pointer and pcid info */ 37 extern pcid_info_t pcid_info; 38 39 /* initialize cmicx logging to a certain file */ 40 bool cmicx_logging_init(char *file_name) { 41 cmicx_log_file = fopen(file_name,"a"); 42 if (cmicx_log_file==NULL) { 43 return false; 44 } 45 #ifdef CMICX_STANDALONE_SIM 46 cmicx_current_log_level = 3; 47 cmicx_cutoff_log_level = 3; 48 #else 49 cmicx_current_log_level = 3; 50 cmicx_cutoff_log_level = 3; 51 #endif 52 #if defined(BCM_DNX_SUPPORT) || defined(BCM_DNXF_SUPPORT) 53 cmicx_current_log_level = cmicx_cutoff_log_level - 1; 54 #endif 55 return true; 56 } 57 58 /* set the log level for subsequently logged messages */ 59 void cmicx_log_level_set(int level) { 60 if(pcid_info.opt_verbose == 1) { 61 cmicx_current_log_level = level; 62 } else { 63 cmicx_current_log_level = -1; 64 } 65 } 66 67 /* set the current cut-off point for cmicx logging */ 68 void cmicx_log_level_cutoff_set(int level) { 69 cmicx_cutoff_log_level = level; 70 } 71 72 /* logs a specified message to the opened log file (and derivative functions) */ 73 void cmicx_log(char *str) { 74 cmicx_log_str(str); 75 } 76 void cmicx_log_str(char *str) { 77 if (cmicx_current_log_level>=cmicx_cutoff_log_level) { 78 printf("%s",str); 79 if (cmicx_log_file!=NULL) { 80 fprintf(cmicx_log_file,"%s",str); 81 fflush(cmicx_log_file); 82 } 83 } 84 } 85 void cmicx_log_addr(addr_t addr) { 86 if (cmicx_current_log_level>=cmicx_cutoff_log_level) { 87 printf("0x%08X",addr); 88 if (cmicx_log_file!=NULL) { 89 fprintf(cmicx_log_file,"0x%08X",addr); 90 fflush(cmicx_log_file); 91 } 92 } 93 } 94 void cmicx_log_reg(reg_t reg) { 95 if (cmicx_current_log_level>=cmicx_cutoff_log_level) { 96 printf("0x%08X",reg); 97 if (cmicx_log_file!=NULL) { 98 fprintf(cmicx_log_file,"0x%08X",reg); 99 fflush(cmicx_log_file); 100 } 101 } 102 } 103 void cmicx_log_int(int num) { 104 if (cmicx_current_log_level>=cmicx_cutoff_log_level) { 105 printf("%d",num); 106 if (cmicx_log_file!=NULL) { 107 fprintf(cmicx_log_file,"%d",num); 108 fflush(cmicx_log_file); 109 } 110 } 111 } 112 void cmicx_log_unsigned(unsigned int num) { 113 if (cmicx_current_log_level>=cmicx_cutoff_log_level) { 114 printf("%u",num); 115 if (cmicx_log_file!=NULL) { 116 fprintf(cmicx_log_file,"%u",num); 117 fflush(cmicx_log_file); 118 } 119 } 120 } 121 void cmicx_log_hex(unsigned int num) { 122 if (cmicx_current_log_level>=cmicx_cutoff_log_level) { 123 printf("0x%08X",num); 124 if (cmicx_log_file!=NULL) { 125 fprintf(cmicx_log_file,"0x%08X",num); 126 fflush(cmicx_log_file); 127 } 128 } 129 } 130 void cmicx_log_uint64(uint64_t num) { 131 if (cmicx_current_log_level>=cmicx_cutoff_log_level) { 132 printf("0x%08X%08X",(uint32_t) ((num) >> 32), (uint32_t) num); 133 if (cmicx_log_file!=NULL) { 134 fprintf(cmicx_log_file,"0x%08X%08X",(uint32_t) ((num) >> 32), (uint32_t) num); 135 fflush(cmicx_log_file); 136 } 137 } 138 } 139 void cmicx_log_byte(unsigned char num) { 140 if (cmicx_current_log_level>=cmicx_cutoff_log_level) { 141 printf("%02X",(unsigned)num); 142 if (cmicx_log_file!=NULL) { 143 fprintf(cmicx_log_file,"%02X",(unsigned)num); 144 fflush(cmicx_log_file); 145 } 146 } 147 } 148 void cmicx_log_long(unsigned long num) { 149 if (cmicx_current_log_level>=cmicx_cutoff_log_level) { 150 printf("%ld", num); 151 if (cmicx_log_file!=NULL) { 152 fprintf(cmicx_log_file,"%ld", num); 153 fflush(cmicx_log_file); 154 } 155 } 156 } 157 void cmicx_log_newline(void) { 158 if (cmicx_current_log_level>=cmicx_cutoff_log_level) { 159 printf("\n[SIM] "); 160 if (cmicx_log_file!=NULL) { 161 fprintf(cmicx_log_file,"\n[SIM] "); 162 fflush(cmicx_log_file); 163 } 164 } 165 } 166 167 /* function to log the elapsed time since the last time this function was called. */ 168 void cmicx_log_elapsed_time(void) { 169 170 static struct timespec last_time; 171 struct timespec time; 172 struct timespec time_diff; 173 174 clock_gettime(CLOCK_REALTIME,&time); 175 cmicx_timespec_diff(&last_time,&time,&time_diff); 176 cmicx_log_long(time_diff.tv_sec); 177 cmicx_log("s, "); 178 cmicx_log_long(time_diff.tv_nsec); 179 cmicx_log("ns "); 180 last_time = time; 181 182 } 183 184 /* send an error message to stdout, stderr, and the log file, and terminate the simulation if a \n is recieved */ 185 void cmicx_error(char *str) { 186 187 fprintf(stdout,"%s",str); 188 fprintf(stderr,"%s",str); 189 if (cmicx_log_file!=NULL) { 190 fprintf(cmicx_log_file,"%s",str); 191 fflush(cmicx_log_file); 192 } 193 194 if (strchr(str,'\n')!=NULL) { 195 fclose(cmicx_log_file); 196 exit(1); 197 } 198 199 } 200 201 202 /* returns the timespec formatted difference in time between two timespecs */ 203 void cmicx_timespec_diff(const struct timespec * const start_time, 204 const struct timespec * const end_time, 205 struct timespec * const diff_time) { 206 207 if ((end_time->tv_nsec-start_time->tv_nsec) < 0) { 208 diff_time->tv_sec = end_time->tv_sec - start_time->tv_sec - 1; 209 diff_time->tv_nsec = 1000000000 + (end_time->tv_nsec - start_time->tv_nsec); 210 } 211 else { 212 diff_time->tv_sec = end_time->tv_sec - start_time->tv_sec; 213 diff_time->tv_nsec = end_time->tv_nsec - start_time->tv_nsec; 214 } 215 216 } 217 218 219 /* function to reverse word endianness */ 220 reg_t cmicx_reverse_word_endianness(reg_t val) { 221 222 reg_t return_val; 223 int i; 224 225 for (i=0; i<sizeof(reg_t); i++) { 226 ((char *)&return_val)[(sizeof(reg_t)-i-1)] = ((char *)&val)[i]; 227 } 228 229 return return_val; 230 } 231 232