merlin16_functions.h (16201B)
1 /********************************************************************************* 2 ********************************************************************************* 3 * File Name : merlin16_functions.h 4 * Created On : 29/04/2013 5 * Created By : Kiran Divakar 6 * Description: Header file with API functions for Serdes IPs 7 * Revision : 8 * 9 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 10 * 11 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 12 * No portions of this material may be reproduced in any form without 13 * the written permission of: 14 * 15 * Broadcom Corporation 16 * 5300 California Avenue 17 * Irvine, CA 92617 18 * 19 * All information contained in this document is Broadcom Corporation 20 * company private proprietary, and trade secret. 21 */ 22 23 /** @file 24 * Protoypes of all API functions for engineering use 25 */ 26 27 #ifndef MERLIN16_API_FUNCTIONS_H 28 #define MERLIN16_API_FUNCTIONS_H 29 30 #ifdef _MSC_VER 31 #pragma warning ( disable : 4127 ) 32 #endif 33 34 #include "common/srds_api_err_code.h" 35 #include "common/srds_api_types.h" 36 #include "merlin16_internal_error.h" 37 #include "merlin16_usr_includes.h" 38 39 /**************************************************************************** 40 * @name Error-Code Storage Addresses. 41 * 42 * Used by error-checking expression-wrapper macros. Expands to the address 43 * where the macros are meant to store the error codes on which they operate, 44 * which depends on the target core and type of executable image being built. 45 * 46 * These are defined well ahead of the error-checking macros themselves to 47 * facilitate definition of RAM- and register-access macros generally used 48 * in their argyments. 49 */ 50 /**@{*/ 51 52 53 /** 54 * Error-code storage address. 55 * 56 * This is a standard API build that directs error-checking expression-wrapper 57 * macros to use a block-local error codes for efficient. local optimization. 58 */ 59 #define __ERR &__err 60 61 /**@}*/ 62 63 /**************************************************************************** 64 * @name Error-Checking Expression Wrappers 65 * 66 * These macros simplify checking and forwarding of error codes returned 67 * either directly or indirectly in the context of functions that themselves 68 * return error codes directly or indirectly. 69 * 70 * All expand to unterminated statements and dereference `__ERR' (defined as 71 * a macro in the same header) to access either private, block-internal error 72 * codes (`__err') or a common error-code cache (e.g. `global_err_code' in 73 * SerDes team post-silicon evaluation builds). 74 * 75 * Neither `__err' nor `__ERR' should be used directly outside the API; and 76 * their names may change to comply with the C Language standard reservation 77 * of identifiers beginning with `__' for use by compiler implementers. 78 * 79 * Great care is taken to ensure not only that error returns are checked but 80 * that use of an error-code cache (as in SerDes team post-silicon evaluation 81 * builds) does not cause "unused variable" warnings. 82 */ 83 /**@{*/ 84 85 /** 86 * Error-check a function call, returning error codes returned. 87 * 88 * Evaluates an expression (typically function call), stores its value into 89 * `*(__ERR)' and returns it from a containing function if it is unequal to 90 * `ERR_CODE_NONE'. 91 * 92 * EFUN() is intended for use in functions returning error codes directly to 93 * check calls to functions also returning error codes directly, e.g.: 94 * 95 * err_code_t foo(...) NOTE: remaining arguments elided 96 * { 97 * ... 98 * EFUN(wrc_core_s_rstb(0x0)); 99 * ... 100 * return ERR_CODE_NONE; 101 * } 102 */ 103 104 #define EFUN(expr) \ 105 do { \ 106 err_code_t __err; \ 107 *(__ERR) = (expr); \ 108 if (*(__ERR) != ERR_CODE_NONE) \ 109 return _error(*(__ERR)); \ 110 (void)__err; \ 111 } while(0) 112 113 /** 114 * Error-check a statement, returning error codes forwarded. 115 * 116 * Evaluates an expression (typically unterminated statement) that may modify 117 * `*(__ERR)' and returns it from a containing function if it is unequal to 118 * `ERR_CODE_NONE'. 119 * 120 * ESTM() is intended for use in functions returning error codes directly to 121 * check calls to functions returning error codes indirectly, e.g.: 122 * 123 * err_code_t foo(...) NOTE: remaining arguments elided 124 * { 125 * uint8_t rst; 126 * ... 127 * ESTM(rst = rdc_core_s_rstb()); 128 * ... 129 * return ERR_CODE_NONE; 130 * } 131 */ 132 133 #define ESTM(expr) \ 134 do { \ 135 err_code_t __err; \ 136 *(__ERR) = ERR_CODE_NONE; \ 137 (expr); \ 138 if (*(__ERR) != ERR_CODE_NONE) \ 139 return _error(*(__ERR)); \ 140 (void)__err; \ 141 } while(0) 142 143 /** 144 * Error-check a function call, defaulting when forwarding error codes 145 * returned. 146 * 147 * In a function taking an argument `err_code_t *err_code_p' in lieu of 148 * returning an error code directly, evaluates an expression (typically 149 * function call), stores its value into `*(__ERR)', combines this (bitwise 150 * inclusive ore) into `*(err_code_p)', and returns a default value if either 151 * `*(__ERR)' or `*(err_code_p)' is not `ERR_CODE_NONE'. 152 * 153 * EPFUN2() is intended for use in functions returning error codes indirectly 154 * to check calls to functions returning error codes directly, e.g.: 155 * 156 * uint8_t foo(err_code_t *err_code_p, ...) NOTE: remaining arguments elided 157 * { 158 * uint8_t result = 0x0; 159 * ... 160 * EPFUN2(wrc_core_s_rstb(0x0), 0x1); 161 * ... 162 * return result; 163 * } 164 */ 165 166 #define EPFUN2(expr, on_err) \ 167 do { \ 168 err_code_t __err; \ 169 *(__ERR) = (expr); \ 170 *(err_code_p) |= *(__ERR); \ 171 if ((*(err_code_p) != ERR_CODE_NONE) \ 172 || (*(__ERR) != ERR_CODE_NONE)) \ 173 return (on_err); \ 174 (void)__err; \ 175 } while(0) 176 177 /** 178 * Error-check a statement, defaulting when forwarding error codes forwarded. 179 * 180 * In a function taking an argument `err_code_t *err_code_p' in lieu of 181 * returning an error code directly, evaluates an expression (typically 182 * unterminated statement), stores its value into `*(__ERR)', combines this 183 * (bitwise inclusive ore) into `*(err_code_p)', and returns a default value 184 * if either `*(__ERR)' or `*(err_code_p)' is not `ERR_CODE_NONE'. 185 * 186 * EPSTM2() is intended for use in functions returning error codes indirectly 187 * to check calls to functions also returning error codes indirectly, e.g.: 188 * 189 * uint8_t foo(err_code_t *err_code_p, ...) NOTE: remaining arguments elided 190 * { 191 * uint8_t result; 192 * ... 193 * EPSTM(result = rdc_core_s_rstb(), 0x1); 194 * ... 195 * return result; 196 * } 197 */ 198 199 #define EPSTM2(expr, on_err) \ 200 do { \ 201 err_code_t __err; \ 202 *(__ERR) = ERR_CODE_NONE; \ 203 (expr); \ 204 *(err_code_p) |= *(__ERR); \ 205 if ((*(err_code_p )!= ERR_CODE_NONE) \ 206 || (*(__ERR) != ERR_CODE_NONE)) \ 207 return (on_err); \ 208 (void)__err; \ 209 } while(0) 210 211 /** 212 * Error-check a function call, defaulting to zero when forwarding error codes 213 * returned. 214 * 215 * Supplies a default value of zero to EPFUN2() to reduce clutter in the most 216 * common case. 217 * 218 * EPFUN() is intended for use in functions returning error codes indirectly 219 * to check calls to functions returning error codes directly, e.g.: 220 * 221 * uint8_t foo(err_code_t *err_code_p, ...) NOTE: remaining arguments elided 222 * { 223 * uint8_t result; NOTE: determined below, detail elided 224 * ... 225 * EPFUN(wrc_core_s_rstb(0x0)); 226 * ... 227 * return result; 228 * } 229 */ 230 231 #define EPFUN(expr) EPFUN2((expr), 0) 232 233 /** 234 * Error-check a statement, defaulting to zero when forwarding error codes 235 * forwarded. 236 * 237 * Supplies a default value of zero to EPSTM2() to reduce clutter in the most 238 * common case. 239 * 240 * EPSTM() is intended for use in functions returning error codes indirectly 241 * to check calls to functions also returning error codes indirectly, e.g.: 242 * 243 * uint8_t foo(err_code_t *err_code_p, ...) NOTE: remaining arguments elided 244 * { 245 * uint8_t result; 246 * ... 247 * EPSTM(result = rdc_core_s_rstb()); 248 * ... 249 * return result; 250 * } 251 */ 252 253 #define EPSTM(expr) EPSTM2((expr), 0) 254 255 /** 256 * Invoke a function with automatic return of error on NULL result. 257 * 258 * ENULL() is intended for use in functions returning error codes directly to 259 * check calls to functions returning pointers, e.g.: 260 * 261 * err_code_t foo(...) NOTE: remaining arguments elided 262 * { 263 * ... 264 * ENULL(strchr("foo", 'q')); 265 * ... 266 * return ERR_CODE_NONE; 267 * } 268 */ 269 #define ENULL(expr) \ 270 EFUN((((void *)0!=(expr))?ERR_CODE_NONE:ERR_CODE_BAD_PTR_OR_INVALID_INPUT)) 271 272 /** 273 * Invoke a function with automatic forward of error on NULL result. 274 * 275 * EPNULL() is intended for use in functions returning error codes indirectly 276 * to check calls to functions returning pointers, e.g.: 277 * 278 * uint8_t foo(err_code_t *err_code_p, ...) NOTE: remaining arguments elided 279 * { 280 * uint8_t result; NOTE: determined below, detail elided 281 * ... 282 * EPNULL(strchr(foo, 'q')); 283 * ... 284 * return result; 285 * } 286 */ 287 #define EPNULL(expr) \ 288 EPFUN((((void *)0!=(expr))?ERR_CODE_NONE:ERR_CODE_BAD_PTR_OR_INVALID_INPUT)) 289 290 /** 291 * Invoke USR_PRINTF(()) with non-error-code-generating arguments. 292 * 293 * Note that the single argument is a parenthesized argument list to be 294 * passed to USR_PRINTF(()). 295 * 296 * EFUN_PRINTF(()) is intended for use in functions returning error codes 297 * directly, with an argument list the elements of which do not generate 298 * error codes of any kind, e.g.: 299 * 300 * err_code_t foo(...) NOTE: remaining arguments elided 301 * { 302 * ... 303 * EFUN_PRINTF(("%u", 1)); 304 * ... 305 * return ERR_CODE_NONE; 306 * } 307 */ 308 #define EFUN_PRINTF(paren_arg_list) USR_PRINTF(paren_arg_list) 309 310 /** 311 * Invoke USR_PRINTF(()) with error-code-generating arguments that would 312 * otherwise be handled by ESTM(). 313 * 314 * Note that the single argument is a parenthesized argument list to be 315 * passed to USR_PRINTF(()). 316 * 317 * EFUN_PRINTF(()) is intended for use in functions returning error codes 318 * directly, with an argument list the elements of which may generate error 319 * codes indirectly, e.g.: 320 * 321 * err_code_t foo(...) NOTE: remaining arguments elided 322 * { 323 * ... 324 * ESTM_PRINTF(("%u", rdc_core_s_rstb())); 325 * ... 326 * return ERR_CODE_NONE; 327 * } 328 */ 329 #define ESTM_PRINTF(paren_arg_list) \ 330 do { \ 331 err_code_t __err; \ 332 *(__ERR) = ERR_CODE_NONE; \ 333 USR_PRINTF(paren_arg_list); \ 334 if (*(__ERR) != ERR_CODE_NONE) \ 335 return _error(*(__ERR)); \ 336 (void)__err; \ 337 } while(0) 338 339 /** 340 * Invoke possibly-remapped 'memset()' and, if it returns NULL, force an 341 * error return. 342 * 343 * Ordinarily, standard implementations of 'memset' will return NULL only if 344 * passed a NULL destination address, and *may already* have overwritten an 345 * inappropriate address range before returning: nevertheless, a specialized 346 * implementation could use a NULL return to indicate other failures. In 347 * either case, execution should not be allowed to proceed on NULL return. 348 */ 349 #define ENULL_MEMSET(mem, val, num) ENULL((USR_MEMSET((mem), (val), (num)))) 350 351 /** 352 * Invoke possibly-remapped 'memset()' and, if it returns NULL, force an 353 * error to be forwarded. 354 * 355 * Ordinarily, standard implementations of 'memset' will return NULL only if 356 * passed a NULL destination address, and *may already* have overwritten an 357 * inappropriate address range before returning: nevertheless, a specialized 358 * implementation could use a NULL return to indicate other failures. In 359 * either case, execution should not be allowed to proceed on NULL return. 360 */ 361 #define EPNULL_MEMSET(mem, val, num) EPNULL((USR_MEMSET((mem), (val), (num)))) 362 363 /** 364 * Invoke possibly-remapped 'strcpy()' and, if it returns NULL, force an 365 * error return. 366 * 367 * Ordinarily, standard implementations of 'strcpy' will return NULL only if 368 * passed a NULL destination address, and *may already* have overwritten an 369 * inappropriate address range before returning: nevertheless, a specialized 370 * implementation could use a NULL return to indicate other failures. In 371 * either case, execution should not be allowed to proceed on NULL return. 372 */ 373 #define ENULL_STRCPY(dst, src) ENULL((USR_STRCPY((dst), (src)))) 374 375 /** 376 * Invoke possibly-remapped 'strcpy()' and, if it returns NULL, force an 377 * error to be forwarded. 378 * 379 * Ordinarily, standard implementations of 'strcpy' will return NULL only if 380 * passed a NULL destination address, and *may already* have overwritten an 381 * inappropriate address range before returning: nevertheless, a specialized 382 * implementation could use a NULL return to indicate other failures. In 383 * either case, execution should not be allowed to proceed on NULL return. 384 */ 385 #define EPNULL_STRCPY(dst, src) EPNULL((USR_STRCPY((dst), (src)))) 386 387 /** 388 * Invoke possibly-remapped 'strncat()' and, if it returns NULL, force an 389 * error return. 390 * 391 * Ordinarily, standard implementations of 'strncat' will return NULL only if 392 * passed a NULL destination address, and *may already* have overwritten an 393 * inappropriate address range before returning: nevertheless, a specialized 394 * implementation could use a NULL return to indicate other failures. In 395 * either case, execution should not be allowed to proceed on NULL return. 396 */ 397 #define ENULL_STRNCAT(dst, src, num) ENULL((USR_STRNCAT((dst), (src), (num)))) 398 399 /** 400 * Invoke possibly-remapped 'strncat()' and, if it returns NULL, force an 401 * error to be forwarded. 402 * 403 * Ordinarily, standard implementations of 'strncat' will return NULL only if 404 * passed a NULL destination address, and *may already* have overwritten an 405 * inappropriate address range before returning: nevertheless, a specialized 406 * implementation could use a NULL return to indicate other failures. In 407 * either case, execution should not be allowed to proceed on NULL return. 408 */ 409 #define EPNULL_STRNCAT(dst, src, num) EPNULL((USR_STRNCAT((dst), (src), (num)))) 410 411 /**@}*/ 412 413 /**************************************************************************** 414 * @name Display Utility Macros 415 */ 416 /**@{*/ 417 418 /** Display a signed integer variable. */ 419 #define DISP(x) ESTM_PRINTF(("%s = %d\n", #x, x)) 420 421 /** Display an unsigned integer variable. */ 422 #define DISPU(x) ESTM_PRINTF(("%s = %u\n", #x, x)) 423 424 /** Display a floating point variable. */ 425 #define DISPF(x) ESTM_PRINTF(("%s = %f\n", #x, x)) 426 427 /** Display an integer variable in hex. */ 428 #define DISPX(x) ESTM_PRINTF(("%s = 0x%x\n", #x, x)) 429 430 /** Read and display the value of a lane register field in decimal. */ 431 #define DISP_REG(x) ESTM_PRINTF(("%s = %d\n", #x, rd_##x())) 432 433 /** Read and display the value of a lane register field in hex. */ 434 #define DISP_REGX(x) ESTM_PRINTF(("%s = 0x%x\n", #x, rd_##x())) 435 436 /** Read and display the value of a core register field in hex. */ 437 #define DISP_REGC(x) ESTM_PRINTF(("%s = 0x%x\n", #x, rdc_##x())) 438 439 /** Display a single member of a lane struct. */ 440 #define DISP_LN_VARS(name,param,format) \ 441 do { \ 442 ESTM_PRINTF(("%-16s\t",name)); \ 443 for(i=0;i<num_lanes;i++) { \ 444 ESTM_PRINTF((format,(lane_st[i].param))); \ 445 } \ 446 EFUN_PRINTF(("\n")); \ 447 } while (0) 448 449 /** Display four members of a lane struct. */ 450 #define DISP_LNQ_VARS(name,param1,param2,param3,param4,format) \ 451 do { \ 452 ESTM_PRINTF(("%-16s\t ",name)); \ 453 for(i=0;i<num_lanes;i++) { \ 454 ESTM_PRINTF((format,(lane_st[i].param1),(lane_st[i].param2),(lane_st[i].param3),(lane_st[i].param4))); \ 455 } \ 456 EFUN_PRINTF(("\n")); \ 457 } while (0) 458 /**@}*/ 459 460 /**************************************************************************** 461 * @name Arithmetic Utility Macros 462 */ 463 /**@{*/ 464 465 /** 466 * Clockwise difference between phase counters. 467 */ 468 #define dist_cw(a,b) (((a)<=(b))?((b)-(a)):((uint16_t)256-(a)+(b))) 469 470 /** 471 * Counter-clockwise difference between phase counters 472 */ 473 #define dist_ccw(a,b) (((a)>=(b))?((a)-(b)):((uint16_t)256+(a)-(b))) 474 475 /**@}*/ 476 #endif