blob: cd402c1a698ae9087063d0fba7d7ce61f7393ae9 [file] [log] [blame]
Sandrine Bailleuxed81f3e2016-07-05 09:55:03 +01001/*
Ambroise Vincentd0196912019-07-18 10:56:14 +01002 * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
Sandrine Bailleuxed81f3e2016-07-05 09:55:03 +01003 *
dp-arm82cb2c12017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Sandrine Bailleuxed81f3e2016-07-05 09:55:03 +01005 */
6
Antonio Nino Diazc3cf06f2018-11-08 10:20:19 +00007#ifndef UTILS_H
8#define UTILS_H
Sandrine Bailleuxed81f3e2016-07-05 09:55:03 +01009
Douglas Raillard308d3592016-12-02 13:51:54 +000010/*
11 * C code should be put in this part of the header to avoid breaking ASM files
12 * or linker scripts including it.
13 */
Julius Wernerd5dfdeb2019-07-09 13:49:11 -070014#if !(defined(__LINKER__) || defined(__ASSEMBLER__))
Douglas Raillard308d3592016-12-02 13:51:54 +000015
Antonio Nino Diaz09d40e02018-12-14 00:18:21 +000016#include <stddef.h>
Antonio Nino Diaz93c78ed2018-08-16 16:52:57 +010017#include <stdint.h>
Douglas Raillard308d3592016-12-02 13:51:54 +000018
Masahiro Yamada109ae262018-01-16 23:15:38 +090019typedef struct mem_region {
Roberto Vargas43cbaf02017-08-03 08:56:38 +010020 uintptr_t base;
21 size_t nbytes;
22} mem_region_t;
23
Lucian Paul-Trifu3519afe2022-03-08 15:02:31 +000024typedef struct p_mem_region {
25 unsigned long long base;
26 unsigned long long nbytes;
27} p_mem_region_t;
28
Roberto Vargas43cbaf02017-08-03 08:56:38 +010029/*
30 * zero_normalmem all the regions defined in tbl.
31 */
32void clear_mem_regions(mem_region_t *tbl, size_t nregions);
33
Roberto Vargas638b0342018-01-05 16:00:05 +000034/*
35 * zero_normalmem all the regions defined in region. It dynamically
36 * maps chunks of 'chunk_size' in 'va' virtual address and clears them.
37 * For this reason memory regions must be multiple of chunk_size and
38 * must be aligned to it as well. chunk_size and va can be selected
39 * in a way that they minimize the number of entries used in the
40 * translation tables.
41 */
Roberto Vargasc96f2972018-02-12 12:36:17 +000042void clear_map_dyn_mem_regions(struct mem_region *regions,
Roberto Vargas638b0342018-01-05 16:00:05 +000043 size_t nregions,
44 uintptr_t va,
Roberto Vargasc96f2972018-02-12 12:36:17 +000045 size_t chunk);
Roberto Vargas43cbaf02017-08-03 08:56:38 +010046
47/*
48 * checks that a region (addr + nbytes-1) of memory is totally covered by
49 * one of the regions defined in tbl. Caller must ensure that (addr+nbytes-1)
50 * doesn't overflow.
51 */
52int mem_region_in_array_chk(mem_region_t *tbl, size_t nregions,
53 uintptr_t addr, size_t nbytes);
54
Douglas Raillard308d3592016-12-02 13:51:54 +000055/*
56 * Fill a region of normal memory of size "length" in bytes with zero bytes.
57 *
58 * WARNING: This function can only operate on normal memory. This means that
59 * the MMU must be enabled when using this function. Otherwise, use
60 * zeromem.
61 */
62void zero_normalmem(void *mem, u_register_t length);
63
64/*
65 * Fill a region of memory of size "length" in bytes with null bytes.
66 *
67 * Unlike zero_normalmem, this function has no restriction on the type of
68 * memory targeted and can be used for any device memory as well as normal
69 * memory. This function must be used instead of zero_normalmem when MMU is
70 * disabled.
71 *
72 * NOTE: When data cache and MMU are enabled, prefer zero_normalmem for faster
73 * zeroing.
74 */
75void zeromem(void *mem, u_register_t length);
Soby Mathew6a7b3002018-10-12 16:26:20 +010076
77/*
78 * Utility function to return the address of a symbol. By default, the
79 * compiler generates adr/adrp instruction pair to return the reference
80 * to the symbol and this utility is used to override this compiler
81 * generated to code to use `ldr` instruction.
82 *
83 * This helps when Position Independent Executable needs to reference a symbol
84 * which is constant and does not depend on the execute address of the binary.
85 */
86#define DEFINE_LOAD_SYM_ADDR(_name) \
Ambroise Vincentd0196912019-07-18 10:56:14 +010087static inline u_register_t load_addr_## _name(void) \
88{ \
89 u_register_t v; \
90 __asm__ volatile ("ldr %0, =" #_name : "=r" (v) : "X" (#_name));\
91 return v; \
Soby Mathew6a7b3002018-10-12 16:26:20 +010092}
93
94/* Helper to invoke the function defined by DEFINE_LOAD_SYM_ADDR() */
95#define LOAD_ADDR_OF(_name) (typeof(_name) *) load_addr_## _name()
96
Julius Wernerd5dfdeb2019-07-09 13:49:11 -070097#endif /* !(defined(__LINKER__) || defined(__ASSEMBLER__)) */
Douglas Raillard308d3592016-12-02 13:51:54 +000098
Antonio Nino Diazc3cf06f2018-11-08 10:20:19 +000099#endif /* UTILS_H */