1ed81f3ebSSandrine Bailleux /* 2638b034cSRoberto Vargas * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. 3ed81f3ebSSandrine Bailleux * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 5ed81f3ebSSandrine Bailleux */ 6ed81f3ebSSandrine Bailleux 7*c3cf06f1SAntonio Nino Diaz #ifndef UTILS_H 8*c3cf06f1SAntonio Nino Diaz #define UTILS_H 9ed81f3ebSSandrine Bailleux 10308d359bSDouglas Raillard /* 11308d359bSDouglas Raillard * C code should be put in this part of the header to avoid breaking ASM files 12308d359bSDouglas Raillard * or linker scripts including it. 13308d359bSDouglas Raillard */ 14308d359bSDouglas Raillard #if !(defined(__LINKER__) || defined(__ASSEMBLY__)) 15308d359bSDouglas Raillard 1693c78ed2SAntonio Nino Diaz #include <stdint.h> 17308d359bSDouglas Raillard 18109ae263SMasahiro Yamada typedef struct mem_region { 1943cbaf06SRoberto Vargas uintptr_t base; 2043cbaf06SRoberto Vargas size_t nbytes; 2143cbaf06SRoberto Vargas } mem_region_t; 2243cbaf06SRoberto Vargas 2343cbaf06SRoberto Vargas /* 2443cbaf06SRoberto Vargas * zero_normalmem all the regions defined in tbl. 2543cbaf06SRoberto Vargas */ 2643cbaf06SRoberto Vargas void clear_mem_regions(mem_region_t *tbl, size_t nregions); 2743cbaf06SRoberto Vargas 28638b034cSRoberto Vargas /* 29638b034cSRoberto Vargas * zero_normalmem all the regions defined in region. It dynamically 30638b034cSRoberto Vargas * maps chunks of 'chunk_size' in 'va' virtual address and clears them. 31638b034cSRoberto Vargas * For this reason memory regions must be multiple of chunk_size and 32638b034cSRoberto Vargas * must be aligned to it as well. chunk_size and va can be selected 33638b034cSRoberto Vargas * in a way that they minimize the number of entries used in the 34638b034cSRoberto Vargas * translation tables. 35638b034cSRoberto Vargas */ 36c96f297fSRoberto Vargas void clear_map_dyn_mem_regions(struct mem_region *regions, 37638b034cSRoberto Vargas size_t nregions, 38638b034cSRoberto Vargas uintptr_t va, 39c96f297fSRoberto Vargas size_t chunk); 4043cbaf06SRoberto Vargas 4143cbaf06SRoberto Vargas /* 4243cbaf06SRoberto Vargas * checks that a region (addr + nbytes-1) of memory is totally covered by 4343cbaf06SRoberto Vargas * one of the regions defined in tbl. Caller must ensure that (addr+nbytes-1) 4443cbaf06SRoberto Vargas * doesn't overflow. 4543cbaf06SRoberto Vargas */ 4643cbaf06SRoberto Vargas int mem_region_in_array_chk(mem_region_t *tbl, size_t nregions, 4743cbaf06SRoberto Vargas uintptr_t addr, size_t nbytes); 4843cbaf06SRoberto Vargas 49308d359bSDouglas Raillard /* 50308d359bSDouglas Raillard * Fill a region of normal memory of size "length" in bytes with zero bytes. 51308d359bSDouglas Raillard * 52308d359bSDouglas Raillard * WARNING: This function can only operate on normal memory. This means that 53308d359bSDouglas Raillard * the MMU must be enabled when using this function. Otherwise, use 54308d359bSDouglas Raillard * zeromem. 55308d359bSDouglas Raillard */ 56308d359bSDouglas Raillard void zero_normalmem(void *mem, u_register_t length); 57308d359bSDouglas Raillard 58308d359bSDouglas Raillard /* 59308d359bSDouglas Raillard * Fill a region of memory of size "length" in bytes with null bytes. 60308d359bSDouglas Raillard * 61308d359bSDouglas Raillard * Unlike zero_normalmem, this function has no restriction on the type of 62308d359bSDouglas Raillard * memory targeted and can be used for any device memory as well as normal 63308d359bSDouglas Raillard * memory. This function must be used instead of zero_normalmem when MMU is 64308d359bSDouglas Raillard * disabled. 65308d359bSDouglas Raillard * 66308d359bSDouglas Raillard * NOTE: When data cache and MMU are enabled, prefer zero_normalmem for faster 67308d359bSDouglas Raillard * zeroing. 68308d359bSDouglas Raillard */ 69308d359bSDouglas Raillard void zeromem(void *mem, u_register_t length); 706a7b3005SSoby Mathew 716a7b3005SSoby Mathew /* 726a7b3005SSoby Mathew * Utility function to return the address of a symbol. By default, the 736a7b3005SSoby Mathew * compiler generates adr/adrp instruction pair to return the reference 746a7b3005SSoby Mathew * to the symbol and this utility is used to override this compiler 756a7b3005SSoby Mathew * generated to code to use `ldr` instruction. 766a7b3005SSoby Mathew * 776a7b3005SSoby Mathew * This helps when Position Independent Executable needs to reference a symbol 786a7b3005SSoby Mathew * which is constant and does not depend on the execute address of the binary. 796a7b3005SSoby Mathew */ 806a7b3005SSoby Mathew #define DEFINE_LOAD_SYM_ADDR(_name) \ 816a7b3005SSoby Mathew static inline u_register_t load_addr_## _name(void) \ 826a7b3005SSoby Mathew { \ 836a7b3005SSoby Mathew u_register_t v; \ 846a7b3005SSoby Mathew /* Create a void reference to silence compiler */ \ 856a7b3005SSoby Mathew (void) _name; \ 866a7b3005SSoby Mathew __asm__ volatile ("ldr %0, =" #_name : "=r" (v)); \ 876a7b3005SSoby Mathew return v; \ 886a7b3005SSoby Mathew } 896a7b3005SSoby Mathew 906a7b3005SSoby Mathew /* Helper to invoke the function defined by DEFINE_LOAD_SYM_ADDR() */ 916a7b3005SSoby Mathew #define LOAD_ADDR_OF(_name) (typeof(_name) *) load_addr_## _name() 926a7b3005SSoby Mathew 93308d359bSDouglas Raillard #endif /* !(defined(__LINKER__) || defined(__ASSEMBLY__)) */ 94308d359bSDouglas Raillard 95*c3cf06f1SAntonio Nino Diaz #endif /* UTILS_H */ 96