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