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