GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <lib/utils.h>
|
||||
#include <lib/xlat_tables/xlat_tables_compat.h>
|
||||
|
||||
/*
|
||||
* All the regions defined in mem_region_t must have the following properties
|
||||
*
|
||||
* - Any contiguous regions must be merged into a single entry.
|
||||
* - The number of bytes of each region must be greater than zero.
|
||||
* - The calculation of the highest address within the region (base + nbytes-1)
|
||||
* doesn't produce an overflow.
|
||||
*
|
||||
* These conditions must be fulfilled by the caller and they aren't checked
|
||||
* at runtime.
|
||||
*/
|
||||
|
||||
/*
|
||||
* zero_normalmem all the regions defined in tbl.
|
||||
* It assumes that MMU is enabled and the memory is Normal memory.
|
||||
* tbl must be a valid pointer to a memory mem_region_t array,
|
||||
* nregions is the size of the array.
|
||||
*/
|
||||
void clear_mem_regions(mem_region_t *tbl, size_t nregions)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
assert(tbl != NULL);
|
||||
assert(nregions > 0U);
|
||||
|
||||
for (i = 0; i < nregions; i++) {
|
||||
assert(tbl->nbytes > 0);
|
||||
assert(!check_uptr_overflow(tbl->base, tbl->nbytes-1));
|
||||
zero_normalmem((void *) (tbl->base), tbl->nbytes);
|
||||
tbl++;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(PLAT_XLAT_TABLES_DYNAMIC)
|
||||
/*
|
||||
* zero_normalmem all the regions defined in regions.
|
||||
* It assumes that MMU is enabled and the memory is Normal memory.
|
||||
* regions must be a valid pointer to a memory mem_region_t array,
|
||||
* nregions is the size of the array. va is the virtual address
|
||||
* where we want to map the physical pages that are going to
|
||||
* be cleared, and chunk is the amount of memory mapped and
|
||||
* cleared in every iteration.
|
||||
*/
|
||||
void clear_map_dyn_mem_regions(struct mem_region *regions,
|
||||
size_t nregions,
|
||||
uintptr_t va,
|
||||
size_t chunk)
|
||||
{
|
||||
uintptr_t begin;
|
||||
int r;
|
||||
size_t size;
|
||||
const unsigned int attr = MT_MEMORY | MT_RW | MT_NS;
|
||||
|
||||
assert(regions != NULL);
|
||||
assert(nregions != 0U);
|
||||
assert(chunk != 0U);
|
||||
|
||||
for (unsigned int i = 0U; i < nregions; i++) {
|
||||
begin = regions[i].base;
|
||||
size = regions[i].nbytes;
|
||||
if (((begin & (chunk-1U)) != 0U) ||
|
||||
((size & (chunk-1U)) != 0U)) {
|
||||
INFO("PSCI: Not correctly aligned region\n");
|
||||
panic();
|
||||
}
|
||||
|
||||
while (size > 0U) {
|
||||
r = mmap_add_dynamic_region(begin, va, chunk, attr);
|
||||
if (r != 0) {
|
||||
INFO("PSCI: %s failed with %d\n",
|
||||
"mmap_add_dynamic_region", r);
|
||||
panic();
|
||||
}
|
||||
|
||||
zero_normalmem((void *)va, chunk);
|
||||
|
||||
r = mmap_remove_dynamic_region(va, chunk);
|
||||
if (r != 0) {
|
||||
INFO("PSCI: %s failed with %d\n",
|
||||
"mmap_remove_dynamic_region", r);
|
||||
panic();
|
||||
}
|
||||
|
||||
begin += chunk;
|
||||
size -= chunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This function checks that a region (addr + nbytes-1) of memory is totally
|
||||
* covered by one of the regions defined in tbl.
|
||||
* tbl must be a valid pointer to a memory mem_region_t array, nregions
|
||||
* is the size of the array and the region described by addr and nbytes must
|
||||
* not generate an overflow.
|
||||
* Returns:
|
||||
* -1 means that the region is not covered by any of the regions
|
||||
* described in tbl.
|
||||
* 0 the region (addr + nbytes-1) is covered by one of the regions described
|
||||
* in tbl
|
||||
*/
|
||||
int mem_region_in_array_chk(mem_region_t *tbl, size_t nregions,
|
||||
uintptr_t addr, size_t nbytes)
|
||||
{
|
||||
uintptr_t region_start, region_end, start, end;
|
||||
size_t i;
|
||||
|
||||
assert(tbl != NULL);
|
||||
assert(nbytes != 0U);
|
||||
assert(!check_uptr_overflow(addr, nbytes-1));
|
||||
|
||||
region_start = addr;
|
||||
region_end = addr + (nbytes - 1U);
|
||||
for (i = 0U; i < nregions; i++) {
|
||||
assert(tbl->nbytes > 0);
|
||||
assert(!check_uptr_overflow(tbl->base, tbl->nbytes-1));
|
||||
start = tbl->base;
|
||||
end = start + (tbl->nbytes - 1);
|
||||
if ((region_start >= start) && (region_end <= end)) {
|
||||
return 0;
|
||||
}
|
||||
tbl++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
Reference in New Issue
Block a user