xref: /rk3399_ARM-atf/lib/utils/mem_region.c (revision c948f77136c42a92d0bb660543a3600c36dcf7f1)
1 /*
2  * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 
9 #include <lib/utils.h>
10 
11 /*
12  * All the regions defined in mem_region_t must have the following properties
13  *
14  * - Any contiguous regions must be merged into a single entry.
15  * - The number of bytes of each region must be greater than zero.
16  * - The calculation of the highest address within the region (base + nbytes-1)
17  *   doesn't produce an overflow.
18  *
19  * These conditions must be fulfilled by the caller and they aren't checked
20  * at runtime.
21  */
22 
23 /*
24  * zero_normalmem all the regions defined in tbl.
25  * It assumes that MMU is enabled and the memory is Normal memory.
26  * tbl must be a valid pointer to a memory mem_region_t array,
27  * nregions is the size of the array.
28  */
29 void clear_mem_regions(mem_region_t *tbl, size_t nregions)
30 {
31 	size_t i;
32 
33 	assert(tbl);
34 	assert(nregions > 0);
35 
36 	for (i = 0; i < nregions; i++) {
37 		assert(tbl->nbytes > 0);
38 		assert(!check_uptr_overflow(tbl->base, tbl->nbytes-1));
39 		zero_normalmem((void *) (tbl->base), tbl->nbytes);
40 		tbl++;
41 	}
42 }
43 
44 #if defined(PLAT_XLAT_TABLES_DYNAMIC)
45 /*
46  * zero_normalmem all the regions defined in regions.
47  * It assumes that MMU is enabled and the memory is Normal memory.
48  * regions must be a valid pointer to a memory mem_region_t array,
49  * nregions is the size of the array. va is the virtual address
50  * where we want to map the physical pages that are going to
51  * be cleared, and chunk is the amount of memory mapped and
52  * cleared in every iteration.
53  */
54 void clear_map_dyn_mem_regions(struct mem_region *regions,
55 			       size_t nregions,
56 			       uintptr_t va,
57 			       size_t chunk)
58 {
59 	uintptr_t begin;
60 	int r;
61 	size_t size;
62 	const unsigned int attr = MT_MEMORY | MT_RW | MT_NS;
63 
64 	assert(regions != NULL);
65 	assert(nregions > 0 && chunk > 0);
66 
67 	for ( ; nregions--; regions++) {
68 		begin = regions->base;
69 		size = regions->nbytes;
70 		if ((begin & (chunk-1)) != 0 || (size & (chunk-1)) != 0) {
71 			INFO("PSCI: Not correctly aligned region\n");
72 			panic();
73 		}
74 
75 		while (size > 0) {
76 			r = mmap_add_dynamic_region(begin, va, chunk, attr);
77 			if (r != 0) {
78 				INFO("PSCI: mmap_add_dynamic_region failed with %d\n", r);
79 				panic();
80 			}
81 
82 			zero_normalmem((void *) va, chunk);
83 
84 			r = mmap_remove_dynamic_region(va, chunk);
85 			if (r != 0) {
86 				INFO("PSCI: mmap_remove_dynamic_region failed with %d\n", r);
87 				panic();
88 			}
89 
90 			begin += chunk;
91 			size -= chunk;
92 		}
93 	}
94 }
95 #endif
96 
97 /*
98  * This function checks that a region (addr + nbytes-1) of memory is totally
99  * covered by one of the regions defined in tbl.
100  * tbl must be a valid pointer to a memory mem_region_t array, nregions
101  * is the size of the array and the region described by addr and nbytes must
102  * not generate an overflow.
103  * Returns:
104  *  -1 means that the region is not covered by any of the regions
105  *     described in tbl.
106  *   0 the region (addr + nbytes-1) is covered by one of the regions described
107  *     in tbl
108  */
109 int mem_region_in_array_chk(mem_region_t *tbl, size_t nregions,
110 			    uintptr_t addr, size_t nbytes)
111 {
112 	uintptr_t region_start, region_end, start, end;
113 	size_t i;
114 
115 	assert(tbl);
116 	assert(nbytes > 0);
117 	assert(!check_uptr_overflow(addr, nbytes-1));
118 
119 	region_start = addr;
120 	region_end = addr + (nbytes - 1);
121 	for (i = 0; i < nregions; i++) {
122 		assert(tbl->nbytes > 0);
123 		assert(!check_uptr_overflow(tbl->base, tbl->nbytes-1));
124 		start = tbl->base;
125 		end = start + (tbl->nbytes - 1);
126 		if (region_start >= start && region_end <= end)
127 			return 0;
128 		tbl++;
129 	}
130 
131 	return -1;
132 }
133