예제 #1
0
void init_xlat_tables(void)
{
	print_mmap();
	init_xlation_table(mmap, 0, l1_xlation_table, 1);
	tcr_ps_bits = calc_physical_addr_size_bits(max_pa);
	assert(max_va < ADDR_SPACE_SIZE);
}
예제 #2
0
static mmap_region_t *init_xlation_table(mmap_region_t *mm,
					unsigned long base_va,
					unsigned long *table, unsigned level)
{
	unsigned level_size_shift = L1_XLAT_ADDRESS_SHIFT - (level - 1) *
						XLAT_TABLE_ENTRIES_SHIFT;
	unsigned level_size = 1 << level_size_shift;
	unsigned long level_index_mask = XLAT_TABLE_ENTRIES_MASK << level_size_shift;

	assert(level <= 3);

	debug_print("New xlat table:\n");

	do  {
		unsigned long desc = UNSET_DESC;

		if (mm->base_va + mm->size <= base_va) {
			/* Area now after the region so skip it */
			++mm;
			continue;
		}

		debug_print("      %010lx %8lx " + 6 - 2 * level, base_va,
				level_size);

		if (mm->base_va >= base_va + level_size) {
			/* Next region is after area so nothing to map yet */
			desc = INVALID_DESC;
		} else if (mm->base_va <= base_va && mm->base_va + mm->size >=
				base_va + level_size) {
			/* Next region covers all of area */
			int attr = mmap_region_attr(mm, base_va, level_size);
			if (attr >= 0)
				desc = mmap_desc(attr,
					base_va - mm->base_va + mm->base_pa,
					level);
		}
		/* else Next region only partially covers area, so need */

		if (desc == UNSET_DESC) {
			/* Area not covered by a region so need finer table */
			unsigned long *new_table = xlat_tables[next_xlat++];
			assert(next_xlat <= MAX_XLAT_TABLES);
			desc = TABLE_DESC | (unsigned long)new_table;

			/* Recurse to fill in new table */
			mm = init_xlation_table(mm, base_va,
						new_table, level+1);
		}

		debug_print("\n");

		*table++ = desc;
		base_va += level_size;
	} while (mm->size && (base_va & level_index_mask));

	return mm;
}
예제 #3
0
void init_xlat_tables(void)
{
	unsigned long long max_pa;
	uintptr_t max_va;
	print_mmap();
	init_xlation_table(0, base_xlation_table, XLAT_TABLE_LEVEL_BASE,
			   &max_va, &max_pa);
	tcr_ps_bits = calc_physical_addr_size_bits(max_pa);
	assert(max_va < ADDR_SPACE_SIZE);
}
예제 #4
0
void init_xlat_tables(void)
{
	unsigned long long max_pa;
	uintptr_t max_va;
	print_mmap();
	init_xlation_table(0, base_xlation_table, XLAT_TABLE_LEVEL_BASE,
			   &max_va, &max_pa);

	assert(max_va <= PLAT_VIRT_ADDR_SPACE_SIZE - 1);
	assert(max_pa <= PLAT_PHY_ADDR_SPACE_SIZE - 1);
	assert((PLAT_PHY_ADDR_SPACE_SIZE - 1) <= get_max_supported_pa());

	tcr_ps_bits = calc_physical_addr_size_bits(max_pa);
}
예제 #5
0
void core_init_mmu_tables(struct tee_mmap_region *mm)
{
	paddr_t max_pa = 0;
	uint64_t max_va = 0;
	size_t n;

	for (n = 0; mm[n].size; n++) {
		paddr_t pa_end;
		vaddr_t va_end;

		debug_print(" %010" PRIxVA " %010" PRIxPA " %10zx %x",
			    mm[n].va, mm[n].pa, mm[n].size, mm[n].attr);

		assert(IS_PAGE_ALIGNED(mm[n].pa));
		assert(IS_PAGE_ALIGNED(mm[n].size));

		pa_end = mm[n].pa + mm[n].size - 1;
		va_end = mm[n].va + mm[n].size - 1;
		if (pa_end > max_pa)
			max_pa = pa_end;
		if (va_end > max_va)
			max_va = va_end;
	}

	/* Clear table before use */
	memset(l1_xlation_table[0], 0, NUM_L1_ENTRIES * XLAT_ENTRY_SIZE);
	init_xlation_table(mm, 0, l1_xlation_table[0], 1);
	for (n = 1; n < CFG_TEE_CORE_NB_CORE; n++)
		memcpy(l1_xlation_table[n], l1_xlation_table[0],
			XLAT_ENTRY_SIZE * NUM_L1_ENTRIES);

	for (n = 0; n < NUM_L1_ENTRIES; n++) {
		if (!l1_xlation_table[0][n]) {
			user_va_idx = n;
			break;
		}
	}
	assert(user_va_idx != -1);

	tcr_ps_bits = calc_physical_addr_size_bits(max_pa);
	COMPILE_TIME_ASSERT(ADDR_SPACE_SIZE > 0);
	assert(max_va < ADDR_SPACE_SIZE);
}
예제 #6
0
void init_xlat_tables(void)
{
	print_mmap();
	init_xlation_table(mmap, 0, l1_xlation_table, 1);
}
예제 #7
0
static struct tee_mmap_region *init_xlation_table(struct tee_mmap_region *mm,
			uint64_t base_va, uint64_t *table, unsigned level)
{
	unsigned level_size_shift = L1_XLAT_ADDRESS_SHIFT - (level - 1) *
						XLAT_TABLE_ENTRIES_SHIFT;
	unsigned level_size = 1 << level_size_shift;
	uint64_t level_index_mask = XLAT_TABLE_ENTRIES_MASK << level_size_shift;

	assert(level <= 3);

	debug_print("New xlat table (level %u):", level);

	do  {
		uint64_t desc = UNSET_DESC;

		if (mm->va + mm->size <= base_va) {
			/* Area now after the region so skip it */
			mm++;
			continue;
		}


		if (mm->va >= base_va + level_size) {
			/* Next region is after area so nothing to map yet */
			desc = INVALID_DESC;
			debug_print("%*s%010" PRIx64 " %8x",
					level * 2, "", base_va, level_size);
		} else if (mm->va <= base_va && mm->va + mm->size >=
				base_va + level_size) {
			/* Next region covers all of area */
			int attr = mmap_region_attr(mm, base_va, level_size);

			if (attr >= 0) {
				desc = mmap_desc(attr,
						 base_va - mm->va + mm->pa,
						 level);
				debug_print("%*s%010" PRIx64 " %8x %s-%s-%s-%s",
					level * 2, "", base_va, level_size,
					attr & (TEE_MATTR_CACHE_CACHED <<
						TEE_MATTR_CACHE_SHIFT) ?
						"MEM" : "DEV",
					attr & TEE_MATTR_PW ? "RW" : "RO",
					attr & TEE_MATTR_PX ? "X" : "XN",
					attr & TEE_MATTR_SECURE ? "S" : "NS");
			} else {
				debug_print("%*s%010" PRIx64 " %8x",
					level * 2, "", base_va, level_size);
			}
		}
		/* else Next region only partially covers area, so need */

		if (desc == UNSET_DESC) {
			/* Area not covered by a region so need finer table */
			uint64_t *new_table = xlat_tables[next_xlat++];
			/* Clear table before use */
			memset(new_table, 0, XLAT_TABLE_SIZE);

			assert(next_xlat <= MAX_XLAT_TABLES);
			desc = TABLE_DESC | (uint64_t)(uintptr_t)new_table;

			/* Recurse to fill in new table */
			mm = init_xlation_table(mm, base_va, new_table,
					   level + 1);
		}

		*table++ = desc;
		base_va += level_size;
	} while (mm->size && (base_va & level_index_mask));

	return mm;
}