utils.h 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. * Copyright (c) 2016-2019, Arm Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #ifndef UTILS_H
  7. #define UTILS_H
  8. /*
  9. * C code should be put in this part of the header to avoid breaking ASM files
  10. * or linker scripts including it.
  11. */
  12. #if !(defined(__LINKER__) || defined(__ASSEMBLER__))
  13. #include <stddef.h>
  14. #include <stdint.h>
  15. typedef struct mem_region {
  16. uintptr_t base;
  17. size_t nbytes;
  18. } mem_region_t;
  19. /*
  20. * zero_normalmem all the regions defined in tbl.
  21. */
  22. void clear_mem_regions(mem_region_t *tbl, size_t nregions);
  23. /*
  24. * zero_normalmem all the regions defined in region. It dynamically
  25. * maps chunks of 'chunk_size' in 'va' virtual address and clears them.
  26. * For this reason memory regions must be multiple of chunk_size and
  27. * must be aligned to it as well. chunk_size and va can be selected
  28. * in a way that they minimize the number of entries used in the
  29. * translation tables.
  30. */
  31. void clear_map_dyn_mem_regions(struct mem_region *regions,
  32. size_t nregions,
  33. uintptr_t va,
  34. size_t chunk);
  35. /*
  36. * checks that a region (addr + nbytes-1) of memory is totally covered by
  37. * one of the regions defined in tbl. Caller must ensure that (addr+nbytes-1)
  38. * doesn't overflow.
  39. */
  40. int mem_region_in_array_chk(mem_region_t *tbl, size_t nregions,
  41. uintptr_t addr, size_t nbytes);
  42. /*
  43. * Fill a region of normal memory of size "length" in bytes with zero bytes.
  44. *
  45. * WARNING: This function can only operate on normal memory. This means that
  46. * the MMU must be enabled when using this function. Otherwise, use
  47. * zeromem.
  48. */
  49. void zero_normalmem(void *mem, u_register_t length);
  50. /*
  51. * Fill a region of memory of size "length" in bytes with null bytes.
  52. *
  53. * Unlike zero_normalmem, this function has no restriction on the type of
  54. * memory targeted and can be used for any device memory as well as normal
  55. * memory. This function must be used instead of zero_normalmem when MMU is
  56. * disabled.
  57. *
  58. * NOTE: When data cache and MMU are enabled, prefer zero_normalmem for faster
  59. * zeroing.
  60. */
  61. void zeromem(void *mem, u_register_t length);
  62. /*
  63. * Utility function to return the address of a symbol. By default, the
  64. * compiler generates adr/adrp instruction pair to return the reference
  65. * to the symbol and this utility is used to override this compiler
  66. * generated to code to use `ldr` instruction.
  67. *
  68. * This helps when Position Independent Executable needs to reference a symbol
  69. * which is constant and does not depend on the execute address of the binary.
  70. */
  71. #define DEFINE_LOAD_SYM_ADDR(_name) \
  72. static inline u_register_t load_addr_## _name(void) \
  73. { \
  74. u_register_t v; \
  75. __asm__ volatile ("ldr %0, =" #_name : "=r" (v) : "X" (#_name));\
  76. return v; \
  77. }
  78. /* Helper to invoke the function defined by DEFINE_LOAD_SYM_ADDR() */
  79. #define LOAD_ADDR_OF(_name) (typeof(_name) *) load_addr_## _name()
  80. #endif /* !(defined(__LINKER__) || defined(__ASSEMBLER__)) */
  81. #endif /* UTILS_H */