1 /*
2 * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <assert.h>
8 #include <utils.h>
9
10 /*
11 * All the regions defined in mem_region_t must have the following properties
12 *
13 * - Any contiguous regions must be merged into a single entry.
14 * - The number of bytes of each region must be greater than zero.
15 * - The calculation of the highest address within the region (base + nbytes-1)
16 * doesn't produce an overflow.
17 *
18 * These conditions must be fulfilled by the caller and they aren't checked
19 * at runtime.
20 */
21
22 /*
23 * zero_normalmem all the regions defined in tbl.
24 * It assumes that MMU is enabled and the memory is Normal memory.
25 * tbl must be a valid pointer to a memory mem_region_t array,
26 * nregions is the size of the array.
27 */
clear_mem_regions(mem_region_t * tbl,size_t nregions)28 void clear_mem_regions(mem_region_t *tbl, size_t nregions)
29 {
30 size_t i;
31
32 assert(tbl);
33 assert(nregions > 0);
34
35 for (i = 0; i < nregions; i++) {
36 assert(tbl->nbytes > 0);
37 assert(!check_uptr_overflow(tbl->base, tbl->nbytes-1));
38 zero_normalmem((void *) (tbl->base), tbl->nbytes);
39 tbl++;
40 }
41 }
42
43 /*
44 * This function checks that a region (addr + nbytes-1) of memory is totally
45 * covered by one of the regions defined in tbl.
46 * tbl must be a valid pointer to a memory mem_region_t array, nregions
47 * is the size of the array and the region described by addr and nbytes must
48 * not generate an overflow.
49 * Returns:
50 * -1 means that the region is not covered by any of the regions
51 * described in tbl.
52 * 0 the region (addr + nbytes-1) is covered by one of the regions described
53 * in tbl
54 */
mem_region_in_array_chk(mem_region_t * tbl,size_t nregions,uintptr_t addr,size_t nbytes)55 int mem_region_in_array_chk(mem_region_t *tbl, size_t nregions,
56 uintptr_t addr, size_t nbytes)
57 {
58 uintptr_t region_start, region_end, start, end;
59 size_t i;
60
61 assert(tbl);
62 assert(nbytes > 0);
63 assert(!check_uptr_overflow(addr, nbytes-1));
64
65 region_start = addr;
66 region_end = addr + (nbytes - 1);
67 for (i = 0; i < nregions; i++) {
68 assert(tbl->nbytes > 0);
69 assert(!check_uptr_overflow(tbl->base, tbl->nbytes-1));
70 start = tbl->base;
71 end = start + (tbl->nbytes - 1);
72 if (region_start >= start && region_end <= end)
73 return 0;
74 tbl++;
75 }
76
77 return -1;
78 }
79