/*
 * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <utils.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);
	assert(nregions > 0);

	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(mem_region_t *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 > 0 && chunk > 0);

	for ( ; nregions--; regions++) {
		begin = regions->base;
		size = regions->nbytes;
		if ((begin & (chunk-1)) != 0 || (size & (chunk-1)) != 0) {
			INFO("PSCI: Not correctly aligned region\n");
			panic();
		}

		while (size > 0) {
			r = mmap_add_dynamic_region(begin, va, chunk, attr);
			if (r != 0) {
				INFO("PSCI: mmap_add_dynamic_region failed with %d\n", r);
				panic();
			}

			zero_normalmem((void *) va, chunk);

			r = mmap_remove_dynamic_region(va, chunk);
			if (r != 0) {
				INFO("PSCI: mmap_remove_dynamic_region failed with %d\n", 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);
	assert(nbytes > 0);
	assert(!check_uptr_overflow(addr, nbytes-1));

	region_start = addr;
	region_end = addr + (nbytes - 1);
	for (i = 0; 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;
}
