lib/xlat_tables_v2/xlat_tables_core.c
/*
 * Returns a block/page table descriptor for the given level and attributes.
 */
Returns a block/page table descriptor for the given level and attributes.
Returns a block / page table descriptor for the given level and attributes .
uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr,
		   unsigned long long addr_pa, unsigned int level)
{
	uint64_t desc;
	uint32_t mem_type;
	assert((addr_pa & XLAT_BLOCK_MASK(level)) == 0U);
	desc = addr_pa;
	desc |= (level == XLAT_TABLE_LEVEL_MAX) ? PAGE_DESC : BLOCK_DESC;
	desc |= LOWER_ATTRS(ACCESS_FLAG);
	desc |= ((attr & MT_NS) != 0U) ? LOWER_ATTRS(NS) : 0U;
	desc |= ((attr & MT_RW) != 0U) ? LOWER_ATTRS(AP_RW) : LOWER_ATTRS(AP_RO);
	if (ctx->xlat_regime == EL1_EL0_REGIME) {
		if ((attr & MT_USER) != 0U) {
			desc |= LOWER_ATTRS(AP_ACCESS_UNPRIVILEGED);
		} else {
			desc |= LOWER_ATTRS(AP_NO_ACCESS_UNPRIVILEGED);
		}
	} else {
		assert(ctx->xlat_regime == EL3_REGIME);
		desc |= LOWER_ATTRS(AP_ONE_VA_RANGE_RES1);
	}
	mem_type = MT_TYPE(attr);
	if (mem_type == MT_DEVICE) {
		desc |= LOWER_ATTRS(ATTR_DEVICE_INDEX | OSH);
		desc |= xlat_arch_regime_get_xn_desc(ctx->xlat_regime);
	} else { 
		if (((attr & MT_RW) != 0U) || ((attr & MT_EXECUTE_NEVER) != 0U)) {
			desc |= xlat_arch_regime_get_xn_desc(ctx->xlat_regime);
		}
		if (mem_type == MT_MEMORY) {
			desc |= LOWER_ATTRS(ATTR_IWBWA_OWBWA_NTR_INDEX | ISH);
		} else {
			assert(mem_type == MT_NON_CACHEABLE);
			desc |= LOWER_ATTRS(ATTR_NON_CACHEABLE_INDEX | OSH);
		}
	}
	return desc;
}
uint64_t xlat_desc ( const xlat_ctx_t * ctx , uint32_t attr , unsigned long long addr_pa , unsigned int level ) { uint64_t desc ; uint32_t mem_type ; assert ( ( addr_pa & XLAT_BLOCK_MASK ( level ) ) == 0U ) ; desc = addr_pa ; desc |= ( level == XLAT_TABLE_LEVEL_MAX ) ? PAGE_DESC : BLOCK_DESC ; desc |= LOWER_ATTRS ( ACCESS_FLAG ) ; desc |= ( ( attr & MT_NS ) != 0U ) ? LOWER_ATTRS ( NS ) : 0U ; desc |= ( ( attr & MT_RW ) != 0U ) ? LOWER_ATTRS ( AP_RW ) : LOWER_ATTRS ( AP_RO ) ; if ( ctx -> xlat_regime == EL1_EL0_REGIME ) { if ( ( attr & MT_USER ) != 0U ) { desc |= LOWER_ATTRS ( AP_ACCESS_UNPRIVILEGED ) ; } else { desc |= LOWER_ATTRS ( AP_NO_ACCESS_UNPRIVILEGED ) ; } } else { assert ( ctx -> xlat_regime == EL3_REGIME ) ; desc |= LOWER_ATTRS ( AP_ONE_VA_RANGE_RES1 ) ; } mem_type = MT_TYPE ( attr ) ; if ( mem_type == MT_DEVICE ) { desc |= LOWER_ATTRS ( ATTR_DEVICE_INDEX | OSH ) ; desc |= xlat_arch_regime_get_xn_desc ( ctx -> xlat_regime ) ; } else { if ( ( ( attr & MT_RW ) != 0U ) || ( ( attr & MT_EXECUTE_NEVER ) != 0U ) ) { desc |= xlat_arch_regime_get_xn_desc ( ctx -> xlat_regime ) ; } if ( mem_type == MT_MEMORY ) { desc |= LOWER_ATTRS ( ATTR_IWBWA_OWBWA_NTR_INDEX | ISH ) ; } else { assert ( mem_type == MT_NON_CACHEABLE ) ; desc |= LOWER_ATTRS ( ATTR_NON_CACHEABLE_INDEX | OSH ) ; } } return desc ; }
Returns a block/page table descriptor for the given level and attributes.
Returns a block / page table descriptor for the given level and attributes .
/* Make sure that the granularity is fine enough to map this address. */ /*
	 * There are different translation table descriptors for level 3 and the
	 * rest.
	 */ /*
	 * Always set the access flag, as this library assumes access flag
	 * faults aren't managed.
	 */ /*
	 * Deduce other fields of the descriptor based on the MT_NS and MT_RW
	 * memory region attributes.
	 */ /*
	 * Do not allow unprivileged access when the mapping is for a privileged
	 * EL. For translation regimes that do not have mappings for access for
	 * lower exception levels, set AP[2] to AP_NO_ACCESS_UNPRIVILEGED.
	 */ /* EL0 mapping requested, so we give User access */ /* EL1 mapping requested, no User access granted */ /*
	 * Deduce shareability domain and executability of the memory region
	 * from the memory type of the attributes (MT_TYPE).
	 *
	 * Data accesses to device memory and non-cacheable normal memory are
	 * coherent for all observers in the system, and correspondingly are
	 * always treated as being Outer Shareable. Therefore, for these 2 types
	 * of memory, it is not strictly needed to set the shareability field
	 * in the translation tables.
	 */ /*
		 * Always map device memory as execute-never.
		 * This is to avoid the possibility of a speculative instruction
		 * fetch, which could be an issue if this memory region
		 * corresponds to a read-sensitive peripheral.
		 */ /* Normal memory */ /*
		 * Always map read-write normal memory as execute-never.
		 * This library assumes that it is used by software that does
		 * not self-modify its code, therefore R/W memory is reserved
		 * for data storage, which must not be executable.
		 *
		 * Note that setting the XN bit here is for consistency only.
		 * The function that enables the MMU sets the SCTLR_ELx.WXN bit,
		 * which makes any writable memory region to be treated as
		 * execute-never, regardless of the value of the XN bit in the
		 * translation table.
		 *
		 * For read-only memory, rely on the MT_EXECUTE/MT_EXECUTE_NEVER
		 * attribute to figure out the value of the XN bit.  The actual
		 * XN bit(s) to set in the descriptor depends on the context's
		 * translation regime and the policy applied in
		 * xlat_arch_regime_get_xn_desc().
		 */