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