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