utils_memory.h (19713B)
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-2020 Broadcom Inc. All rights reserved. 5 */ 6 7 #ifndef D_UTILS_MEMORY_H_INCLUDED 8 /* { */ 9 #define D_UTILS_MEMORY_H_INCLUDED 10 11 #if !DUNE_BCM 12 13 /* 14 * General include file for reference design. 15 */ 16 #include "Pub/include/ref_sys.h" 17 /* 18 * INCLUDE FILES: 19 */ 20 #ifndef __DUNE_SSF__ 21 #include "../../../../H/usrApp.h" 22 #endif 23 24 #if defined(SAND_LOW_LEVEL_SIMULATION) 25 /* { */ 26 #include "stdio.h" 27 #include "string.h" 28 #include "ctype.h" 29 #include "stdlib.h" 30 #include "time.h" 31 /* 32 * Utilities include file. 33 */ 34 #include "Pub/include/utils_defx.h" 35 /* 36 * User interface external include file. 37 */ 38 #include "Pub/include/ui_defx.h" 39 /* 40 * Dune chips include file. 41 */ 42 #include "Pub/include/dune_chips.h" 43 /* } */ 44 #else 45 /* { */ 46 #include "stdio.h" 47 #include "string.h" 48 #include "ctype.h" 49 #include "stdlib.h" 50 #include "taskLib.h" 51 #include "errnoLib.h" 52 #include "usrLib.h" 53 #include "tickLib.h" 54 #include "ioLib.h" 55 #include "iosLib.h" 56 #include "logLib.h" 57 #include "pipeDrv.h" 58 #include "timers.h" 59 #include "sigLib.h" 60 #include <usrApp.h> 61 /* 62 * This file is required to complete definitions 63 * related to timers and clocks. For display/debug 64 * purposes only. 65 */ 66 #include "private\timerLibP.h" 67 #include "shellLib.h" 68 #include "dbgLib.h" 69 #include "flash28.h" 70 /* 71 * Utilities include file. 72 */ 73 #include "Pub/include/utils_defx.h" 74 /* 75 * Dune chips include file. 76 */ 77 #include "Pub/include/dune_chips.h" 78 /* } */ 79 #endif 80 81 #ifndef __DUNE_SSF__ 82 #include "FMC/include/fmc_common_agent.h" 83 #endif 84 #include "FMC/include/fmc_transport_layer_dcl.h" 85 86 #include "RefDesign/include/dune_rpc.h" 87 88 #endif /* !DUNE_BCM */ 89 90 typedef enum 91 { 92 XOR_OP = 0, 93 OR_OP, 94 AND_OP, 95 NO_OPERATION 96 } OPERATION; 97 98 typedef enum 99 { 100 WR_FORMAT_BYTE = 1, 101 WR_FORMAT_SHORT = 2, 102 WR_FORMAT_LONG = 4 103 } WR_FORMAT; 104 typedef struct 105 { 106 /* 107 * Name of memory block. 108 */ 109 char *block_name ; 110 /* 111 * Start address of memory block 112 */ 113 char *start_address ; 114 /* 115 * Number of bytes in memory block 116 */ 117 unsigned long block_size ; 118 /* 119 * Chip select used for this block. 120 */ 121 unsigned int chip_select_number ; 122 /* 123 * Number of access bits (width). 124 */ 125 unsigned int width ; 126 /* 127 * Attributes for this block. 128 */ 129 unsigned long attributes ; 130 /* 131 * Identifier of this block within CLI. 132 */ 133 unsigned int block_equivalent ; 134 } MEMORY_BLOCK ; 135 typedef struct 136 { 137 /* 138 * Number of elements in array pointed to by 'memory_block'. 139 */ 140 unsigned int num_blocks ; 141 /* 142 * Array of memory block descriptors. 143 */ 144 MEMORY_BLOCK *memory_block ; 145 } MEMORY_MAP ; 146 147 /* 148 * Object: Buff_mem 149 * This object enables the user to store 'mem read' results 150 * in local memory to later be retriebed. This feature enables 151 * faster working with an external script agent (like proComm). 152 * Storage is always in units of char (one byte). 153 * { 154 */ 155 unsigned 156 int 157 get_buff_mem_size( 158 void 159 ); 160 161 /***************************************************** 162 *NAME 163 * is_buff_mem_offset_legit 164 *TYPE: PROC 165 *DATE: 12/FEB/2003 166 *FUNCTION: 167 * Check whether specified offset and number of bytes 168 * to write into or from local buffer, assigned for 'mem' 169 * operations, make a legitimate set. 170 *CALLING SEQUENCE: 171 * is_buff_mem_offset_legit(offset,val_size) 172 *INPUT: 173 * SOC_SAND_DIRECT: 174 * unsigned int offset - 175 * Offset, in local buffer, in units of bytes, 176 * which is planned to start reading from or 177 * writing to. 178 * unsigned int val_size - 179 * Number of bytes planned to be copied. 180 * SOC_SAND_INDIRECT: 181 * Size of Buff_mem. 182 *OUTPUT: 183 * SOC_SAND_DIRECT: 184 * If non zero then input was found illegal. 185 * SOC_SAND_INDIRECT: 186 * None. 187 *REMARKS: 188 * 189 *SEE ALSO: 190 */ 191 int 192 is_buff_mem_offset_legit( 193 unsigned int offset, 194 unsigned int val_size 195 ); 196 197 /***************************************************** 198 *NAME 199 * get_buff_mem_ptr 200 *TYPE: PROC 201 *DATE: 12/FEB/2003 202 *FUNCTION: 203 * Get memory address of specified offset in 204 * local buffer assigned for 'mem' 205 * operations (copy from). 206 *CALLING SEQUENCE: 207 * get_buff_mem_ptr(offset) 208 *INPUT: 209 * SOC_SAND_DIRECT: 210 * unsigned int offset - 211 * Offset in local buffer (in units of bytes). 212 *OUTPUT: 213 * SOC_SAND_DIRECT: 214 * If non zero then input was found illegal and 215 * operation has not been carried out. 216 * SOC_SAND_INDIRECT: 217 * Updated Buff_mem. 218 *REMARKS: 219 * 220 *SEE ALSO: 221 */ 222 char 223 *get_buff_mem_ptr( 224 unsigned int offset 225 ); 226 227 /***************************************************** 228 *NAME 229 * write_memory 230 *TYPE: PROC 231 *DATE: 04/MARCH/2002 232 *FUNCTION: 233 * Write specified contents into specified 234 * memory address using specified format. 235 *CALLING SEQUENCE: 236 * write_memory(addr,len,format,write_data) 237 *INPUT: 238 * SOC_SAND_DIRECT: 239 * char *addr - 240 * Memory address to start writing to. 241 * unsigned int len - 242 * Number of bytes to display. 243 * unsigned int format - 244 * Memory access method format: 245 * 1 - CHAR_EQUIVALENT - Byte 246 * 2 - SHORT_EQUIVALENT - Short 247 * 4 - LONG_EQUIVALENT - Long 248 * Otherwise - Byte 249 * unsigned long *write_data - 250 * Pointer to data to write into memory. 251 * unsigned int eeprom_access - 252 * Flag. If 'true' then access memory using 253 * special EEPROM access procedures. 254 * Currently, only byte access is allowed for 255 * EEPROM. 256 * SOC_SAND_INDIRECT: 257 * None. 258 *OUTPUT: 259 * SOC_SAND_DIRECT: 260 * None. 261 * SOC_SAND_INDIRECT: 262 * Displayed memory. 263 *REMARKS: 264 * Calling procedure is assumed to have checked 265 * legitimacy of memory range. 266 *SEE ALSO: 267 */ 268 void 269 write_memory( 270 char *addr, 271 unsigned int len, 272 WR_FORMAT format, 273 unsigned long *write_data, 274 unsigned int eeprom_access, 275 unsigned int silent 276 ); 277 278 /***************************************************** 279 *NAME 280 * write_memory_do_op 281 *TYPE: PROC 282 *DATE: 04/MARCH/2002 283 *FUNCTION: 284 * Reading specified address, do xor/and/or with specified data 285 * than Write the result into specified memory address 286 * using specified format. 287 *CALLING SEQUENCE: 288 * write_memory_do_op(addr,len,format,write_data,op) 289 *INPUT: 290 * SOC_SAND_DIRECT: 291 * char *addr - 292 * Memory address to start writing to. 293 * unsigned int len - 294 * Number of bytes to display. 295 * unsigned int format - 296 * Memory access method format: 297 * 1 - CHAR_EQUIVALENT - Byte 298 * 2 - SHORT_EQUIVALENT - Short 299 * 4 - LONG_EQUIVALENT - Long 300 * Otherwise - Byte 301 * unsigned long *write_data - 302 * Pointer to data to write into memory. 303 * unsigned int eeprom_access - 304 * Flag. If 'true' then access memory using 305 * special EEPROM access procedures. 306 * Currently, only byte access is allowed for 307 * EEPROM. 308 * OPERATION op - 309 * 3 bit wise operation - XOR, AND & OR 310 * SOC_SAND_INDIRECT: 311 * None. 312 *OUTPUT: 313 * SOC_SAND_DIRECT: 314 * None. 315 * SOC_SAND_INDIRECT: 316 * Displayed memory. 317 *REMARKS: 318 * Calling procedure is assumed to have checked 319 * legitimacy of memory range. 320 *SEE ALSO: 321 */ 322 void 323 write_memory_do_op( 324 char *addr, 325 unsigned int len, 326 WR_FORMAT format, 327 unsigned long *write_data, 328 unsigned int eeprom_access, 329 OPERATION op, 330 unsigned int silent 331 ); 332 333 unsigned 334 int 335 get_read_compare_error_counter( 336 void 337 ); 338 339 void 340 clear_read_compare_error_counter( 341 void 342 ); 343 344 void 345 inc_read_compare_error_counter( 346 void 347 ); 348 349 /***************************************************** 350 *NAME 351 * display_get_mem_counter 352 *TYPE: PROC 353 *DATE: 09/FEB/2003 354 *FUNCTION: 355 * Display contents of specified counter related 356 * to memory operation. 357 *CALLING SEQUENCE: 358 * display_get_mem_counter(counter_id,silent) 359 *INPUT: 360 * SOC_SAND_DIRECT: 361 * unsigned int counter_id - 362 * Identifier of counter to display. Current 363 * list of counters: 364 * VAL_READ_FAILURES_EQUIVALENT - 365 * Number of 'val_read' failures. 366 * If identifier is unknown then 367 * VAL_READ_FAILURES_EQUIVALENT is used by 368 * default. 369 * unsigned int silent - 370 * FALSE 371 * Verbose all comments 372 * TRUE 373 * Print value with no text. 374 * SOC_SAND_INDIRECT: 375 * Read_compare_error_counter. 376 * Last_time_rce_counter_cleared. 377 *OUTPUT: 378 * SOC_SAND_DIRECT: 379 * None. 380 * SOC_SAND_INDIRECT: 381 * Displayed value. 382 * Read_compare_error_counter 383 *REMARKS: 384 * None. 385 *SEE ALSO: 386 */ 387 void 388 display_get_mem_counter( 389 unsigned int counter_id, 390 unsigned int silent 391 ); 392 393 /***************************************************** 394 *NAME 395 * display_clear_mem_counter 396 *TYPE: PROC 397 *DATE: 09/FEB/2003 398 *FUNCTION: 399 * Clear and display info on specified counter related 400 * memory operation. 401 *CALLING SEQUENCE: 402 * display_clear_mem_counter(counter_id,silent) 403 *INPUT: 404 * SOC_SAND_DIRECT: 405 * unsigned int counter_id - 406 * Identifier of counter to clear. Current 407 * list of counters: 408 * VAL_READ_FAILURES_EQUIVALENT - 409 * Number of 'val_read' failures. 410 * If identifier is unknown then 411 * VAL_READ_FAILURES_EQUIVALENT is used by 412 * default. 413 * unsigned int silent - 414 * FALSE 415 * Verbose all comments 416 * TRUE 417 * Print nothing. 418 * SOC_SAND_INDIRECT: 419 * Last_time_rce_counter_cleared. 420 *OUTPUT: 421 * SOC_SAND_DIRECT: 422 * None. 423 * SOC_SAND_INDIRECT: 424 * Displayed info. 425 * Last_time_rce_counter_cleared 426 * Read_compare_error_counter 427 *REMARKS: 428 * None. 429 *SEE ALSO: 430 */ 431 void 432 display_clear_mem_counter( 433 unsigned int counter_id, 434 unsigned int silent 435 ); 436 437 /***************************************************** 438 *NAME 439 * read_compare_memory 440 *TYPE: PROC 441 *DATE: 06/FEB/2003 442 *FUNCTION: 443 * Read contents of specified memory address using 444 * specified format and compare (via mask) until 445 * timeout has expired or match found. 446 *CALLING SEQUENCE: 447 * read_compare_memory(addr,format,val, 448 * mask,operation,timeout, 449 * silent) 450 *INPUT: 451 * SOC_SAND_DIRECT: 452 * char *addr - 453 * Memory address to start display of. 454 * unsigned int format - 455 * Memory access method format: 456 * 1 - CHAR_EQUIVALENT - Byte 457 * 2 - SHORT_EQUIVALENT - Short 458 * 4 - LONG_EQUIVALENT - Long 459 * Otherwise - Byte 460 * unsigned long val - 461 * Value to compare with after mask. 462 * unsigned long mask - 463 * Mask to apply to read data before comparing 464 * with 'val'. 465 * unsigned int operation - 466 * Compare operation: 467 * 0 - EQUAL_EQUIVALENT 468 * 1 - NOT_EQUAL_EQUIVALENT 469 * unsigned long timeout - 470 * Time period, in microseconds, to carry out 471 * compare operation before giving up. (Of course, 472 * If match is found before that then this procedure 473 * returns with 'success' indication). 474 * unsigned int silent - 475 * FALSE 476 * Verbose all comments 477 * TRUE 478 * Print nothing on success but indicate error 479 * or failure. 480 * SOC_SAND_INDIRECT: 481 * Read_compare_error_counter. 482 *OUTPUT: 483 * SOC_SAND_DIRECT: 484 * int - 485 * If non zero then compare operation has failed. 486 * Otherwise, compare was successful. 487 * SOC_SAND_INDIRECT: 488 * Read memory (to compare). 489 * Read_compare_error_counter 490 *REMARKS: 491 * Calling procedure is assumed to have checked 492 * legitimacy of memory range. 493 *SEE ALSO: 494 */ 495 int 496 read_compare_memory( 497 char *addr, 498 unsigned int format, 499 unsigned long val, 500 unsigned long mask, 501 unsigned int operation, 502 unsigned long timeout, 503 unsigned int silent 504 ); 505 506 /***************************************************** 507 *NAME 508 * display_memory 509 *TYPE: PROC 510 *DATE: 24/FEB/2002 511 *FUNCTION: 512 * Display contents of specified 513 * memory address using specified formats. 514 *CALLING SEQUENCE: 515 * display_memory(addr,len,format,disp) 516 *INPUT: 517 * SOC_SAND_DIRECT: 518 * char *addr - 519 * Memory address to start display of. 520 * unsigned int len - 521 * Number of bytes/shorts/longs to display. 522 * unsigned int format - 523 * Memory access method format: 524 * 1 - CHAR_EQUIVALENT - Byte 525 * 2 - SHORT_EQUIVALENT - Short 526 * 4 - LONG_EQUIVALENT - Long 527 * Otherwise - Byte 528 * unsigned int disp - 529 * Display format: 530 * 1 - HEX_EQUIVALENT - hex 531 * 2 - UNSIGNED_INTEGER_EQUIVALENT - unsigned_integer 532 * 3 - SIGNED_INTEGER_EQUIVALENT - signed_integer 533 * Otherwise - hex 534 * unsigned int silent - 535 * FALSE 536 * Verbose all comments 537 * TRUE 538 * Print only the read memory 539 * unsigned int use_mem_buff - 540 * Flag. If non-zero then the next parameter 541 * is meaningful and this procedure is required 542 * to store read values in local buffer (for 543 * future retrieval): 544 * If 'use_mem_buff' is non-zero: 545 * If 'use_mem_buff' is '1' 546 * then the dedicated 'mem_buff' is used - 547 * See get_buff_mem_ptr(). In that case 548 * 'mem_buff_offset' is the offest into 549 * this buffer. 550 * Otherwise (different than 1 and different than 0) 551 * then the a general memory buffer is used 552 * and 'mem_buff_offset' is its absolute 553 * address. 554 * unsigned long mem_buff_offset - 555 * if 'use_mem_buff' is '1': 556 * Offset in Buff_mem (local storage buffer) to load 557 * read values into. Number of bytes to load is deduced 558 * from 'len'. 559 * if 'use_mem_buff' is not '1' and is also not '0': 560 * General input memory buffer to load read values 561 * into. Number of bytes to load is deduced 562 * from 'len'. 563 * This parameter is only meaningful if 'use_mem_buff' 564 * is 'non-zero'. 565 * SOC_SAND_INDIRECT: 566 * None. 567 *OUTPUT: 568 * SOC_SAND_DIRECT: 569 * None. 570 * SOC_SAND_INDIRECT: 571 * Displayed memory. 572 * loaded Buff_mem 573 *REMARKS: 574 * Calling procedure is assumed to have checked 575 * legitimacy of memory range. 576 * Paraneters 'mem_buff_offset' and 'len' are 577 * assumed to have been checked for legitimacy 578 * (concerning Buff_mem) by the caller. 579 *SEE ALSO: 580 */ 581 void 582 display_memory( 583 char *addr, 584 unsigned int len, 585 unsigned int format, 586 unsigned int disp, 587 unsigned int silent, 588 unsigned int use_mem_buff, 589 unsigned long mem_buff_offset 590 ); 591 592 /***************************************************** 593 *NAME 594 * ptr_to_offset 595 *TYPE: PROC 596 *DATE: 22/MAR/2002 597 *FUNCTION: 598 * Convert memory address (within this system's 599 * memory map) to offset from the beginning 600 * of the corresponding memory block. 601 *CALLING SEQUENCE: 602 * ptr_to_offset(mem_addr,offset_ptr) 603 *INPUT: 604 * SOC_SAND_DIRECT: 605 * char *mem_addr - 606 * Pointer to memory to which access is required. 607 * unsigned int *offset_ptr - 608 * This procedure will load pointed memory 609 * by offset from the corresponding block. 610 * only meaningful if return value does not 611 * indicate error condition. 612 * SOC_SAND_INDIRECT: 613 * Memory map details. 614 *OUTPUT: 615 * SOC_SAND_DIRECT: 616 * MEMORY_BLOCK * - 617 * If non zero then input memory address 618 * is within memory map and output 619 * poiner is aimed at the corresponding 620 * memory block. 621 * Otherwise, if return value is NULL, input 622 * pointer is not within memory map. 623 * SOC_SAND_INDIRECT: 624 * None. 625 *REMARKS: 626 * None. 627 *SEE ALSO: 628 */ 629 MEMORY_BLOCK 630 *ptr_to_offset( 631 char *mem_addr, 632 unsigned int *offset_ptr 633 ); 634 635 /***************************************************** 636 *NAME 637 * is_ptr_in_blocks 638 *TYPE: PROC 639 *DATE: 24/FEB/2002 640 *FUNCTION: 641 * Indicate whether input pointer points to a memory 642 * location within this system's memory map. 643 *CALLING SEQUENCE: 644 * is_ptr_in_blocks(mem_ptr) 645 *INPUT: 646 * SOC_SAND_DIRECT: 647 * char *mem_ptr - 648 * Pointer to memory to which access is required. 649 * SOC_SAND_INDIRECT: 650 * Memory map details. 651 *OUTPUT: 652 * SOC_SAND_DIRECT: 653 * MEMORY_BLOCK * - 654 * If non zero then input pointer is within 655 * memory map and poiner is aimed at the 656 * corresponding memory block. Otherwise, 657 * if return value is NULL, input pointer 658 * is not within memory map. 659 * SOC_SAND_INDIRECT: 660 * None. 661 *REMARKS: 662 * None. 663 *SEE ALSO: 664 */ 665 MEMORY_BLOCK 666 *is_ptr_in_blocks( 667 char *mem_ptr 668 ); 669 670 /***************************************************** 671 *NAME 672 * block_id_to_ptr 673 *TYPE: PROC 674 *DATE: 03/MAR/2002 675 *FUNCTION: 676 * Convert CLI identifier of a memory block into 677 * pointer to the corresponding memory block. 678 *CALLING SEQUENCE: 679 * block_id_to_base(block_equivalent) 680 *INPUT: 681 * SOC_SAND_DIRECT: 682 * unsigned int block_equivalent - 683 * CLI identifier of memory block. 684 * SOC_SAND_INDIRECT: 685 * Memory map details. 686 *OUTPUT: 687 * SOC_SAND_DIRECT: 688 * MEMORY_BLOCK * - 689 * If non zero then this is the pointer to the 690 * corresponding memory block. Otherwise, 691 * if return value is NULL, no corresponding 692 * block has been found. 693 * SOC_SAND_INDIRECT: 694 * None. 695 *REMARKS: 696 * None. 697 *SEE ALSO: 698 */ 699 MEMORY_BLOCK 700 *block_id_to_ptr( 701 unsigned int block_equivalent 702 ); 703 704 /***************************************************** 705 *NAME 706 * print_mem_banks_info 707 *TYPE: PROC 708 *DATE: 22/FEB/2002 709 *FUNCTION: 710 * Print information on all memory banks available 711 * via 'mem' command. 712 *CALLING SEQUENCE: 713 * print_mem_banks_info() 714 *INPUT: 715 * SOC_SAND_DIRECT: 716 * None. 717 * SOC_SAND_INDIRECT: 718 * Dune chips details. 719 *OUTPUT: 720 * SOC_SAND_DIRECT: 721 * int - 722 * If non zero then some error has occurred. 723 * SOC_SAND_INDIRECT: 724 * Displayed info concerning memory banks. 725 *REMARKS: 726 * None. 727 *SEE ALSO: 728 */ 729 void 730 print_mem_banks_info( 731 void 732 ); 733 734 /***************************************************** 735 *NAME 736 * init_mem_db 737 *TYPE: PROC 738 *DATE: 19/FEB/2002 739 *FUNCTION: 740 * Allocate memory for and itialize all variables 741 * related to the 'mem' option within CLI. 742 *CALLING SEQUENCE: 743 * init_mem_db() 744 *INPUT: 745 * SOC_SAND_DIRECT: 746 * None. 747 * SOC_SAND_INDIRECT: 748 * Dune chips details. 749 *OUTPUT: 750 * SOC_SAND_DIRECT: 751 * int - 752 * If non zero then some error has occurred. 753 * SOC_SAND_INDIRECT: 754 * Allocated initialized memory. 755 *REMARKS: 756 * None. 757 *SEE ALSO: 758 */ 759 int 760 init_mem_db( 761 void 762 ); 763 764 /***************************************************** 765 *NAME 766 * TYPE_MEM_CHECKER 767 *TYPE: PROC 768 *DATE: 20/MAY/2003 769 *FUNCTION: 770 * Check memory type as entered by the user in 771 * the context of 'mem ... type ' command on CLI. 772 * Make sure field is valid for this system ('old' 773 * or 'new' mezzanine). 774 *CALLING SEQUENCE: 775 * type_mem_checker( 776 * current_line_ptr,data_value, 777 * err_msg,partial) 778 *INPUT: 779 * SOC_SAND_DIRECT: 780 * void *current_line_ptr - 781 * Pointer to a structure of type 'CURRENT_LINE': 782 * current prompt line. 783 * unsigned long data_value - 784 * Value entered by the user. 785 * char *err_msg - 786 * This output is only meaningful when return value 787 * is non-zero. Pointer to string to load with 788 * explanation of why validation of input parameter 789 * has failed. Caller must prepare space for 790 * 160 characters (incl. ending null). 791 * unsigned long partial - 792 * Flag. 793 * If 'TRUE' then input field may be 794 * partial (i.e. user has not yet filled the 795 * whole field.) Check legitimacy so far. 796 * If 'FALSE' then input string must be 797 * a complete legitimate field. This 798 * means that it should conform to all 799 * legitimacy checks. 800 * SOC_SAND_INDIRECT: 801 * Desc_fe_reg array. 802 *OUTPUT: 803 * SOC_SAND_DIRECT: 804 * int - 805 * If non-zero then indicated input is 806 * out of range or some other error has been 807 * encountered. 808 * SOC_SAND_INDIRECT: 809 * None. 810 *REMARKS: 811 * None 812 *SEE ALSO: 813 */ 814 int 815 type_mem_checker( 816 void *current_line_ptr, 817 unsigned long data_value, 818 char *err_msg, 819 unsigned long partial 820 ); 821 822 #endif /* } D_UTILS_MEMORY_H_INCLUDED */