bool sm_platform_handler(struct sm_ctx *ctx)
{
	if (ctx->nsec.r12 == 0x200)
		return true;

	switch (ctx->nsec.r12) {
	case 0x0:
		switch (ctx->nsec.r0) {
		case SECURE_SVC_PM_LATE_SUSPEND:
			sm_pm_cpu_do_suspend(suspend_regs);
			cache_op_inner(DCACHE_AREA_CLEAN,
				       suspend_regs,
				       sizeof(suspend_regs));
			cache_op_outer(DCACHE_AREA_CLEAN,
				       virt_to_phys(suspend_regs),
				       sizeof(suspend_regs));
			ctx->nsec.r0 = API_HAL_RET_VALUE_OK;
			break;
		default:
			ctx->nsec.r0 = API_HAL_RET_VALUE_SERVICE_UNKNWON;
			break;
		}
		break;
	case API_MONITOR_L2CACHE_SETDEBUG_INDEX:
		write32(ctx->nsec.r0, pl310_base() + PL310_DEBUG_CTRL);
		ctx->nsec.r0 = API_HAL_RET_VALUE_OK;
		break;
	case API_MONITOR_L2CACHE_CLEANINVBYPA_INDEX:
		arm_cl2_cleaninvbypa(pl310_base(), ctx->nsec.r0,
				     (ctx->nsec.r0 + ctx->nsec.r1));
		ctx->nsec.r0 = API_HAL_RET_VALUE_OK;
		break;
	case API_MONITOR_L2CACHE_SETCONTROL_INDEX:
		write32(ctx->nsec.r0, pl310_base() + PL310_CTRL);
		ctx->nsec.r0 = API_HAL_RET_VALUE_OK;
		break;
	case API_MONITOR_L2CACHE_SETAUXILIARYCONTROL_INDEX:
		write32(ctx->nsec.r0, pl310_base() + PL310_AUX_CTRL);
		ctx->nsec.r0 = API_HAL_RET_VALUE_OK;
		break;
	case API_MONITOR_L2CACHE_SETLATENCY_INDEX:
		write32(ctx->nsec.r0, pl310_base() + PL310_TAG_RAM_CTRL);
		write32(ctx->nsec.r1, pl310_base() + PL310_DATA_RAM_CTRL);
		ctx->nsec.r0 = API_HAL_RET_VALUE_OK;
		break;
	case API_MONITOR_L2CACHE_SETPREFETCHCONTROL_INDEX:
		write32(ctx->nsec.r0, pl310_base() + PL310_PREFETCH_CTRL);
		ctx->nsec.r0 = API_HAL_RET_VALUE_OK;
		break;
	default:
		ctx->nsec.r0 = API_HAL_RET_VALUE_SERVICE_UNKNWON;
		break;
	}

	return false;
}
Esempio n. 2
0
unsigned int cache_maintenance_l2(int op, paddr_t pa, size_t len)
{
	unsigned int ret = TEE_SUCCESS;
	uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_IRQ);

	tee_l2cc_mutex_lock();
	switch (op) {
	case L2CACHE_INVALIDATE:
		arm_cl2_invbyway(pl310_base());
		break;
	case L2CACHE_AREA_INVALIDATE:
		if (len)
			arm_cl2_invbypa(pl310_base(), pa, pa + len - 1);
		break;
	case L2CACHE_CLEAN:
		arm_cl2_cleanbyway(pl310_base());
		break;
	case L2CACHE_AREA_CLEAN:
		if (len)
			arm_cl2_cleanbypa(pl310_base(), pa, pa + len - 1);
		break;
	case L2CACHE_CLEAN_INV:
		arm_cl2_cleaninvbyway(pl310_base());
		break;
	case L2CACHE_AREA_CLEAN_INV:
		if (len)
			arm_cl2_cleaninvbypa(pl310_base(), pa, pa + len - 1);
		break;
	default:
		ret = TEE_ERROR_NOT_IMPLEMENTED;
	}

	tee_l2cc_mutex_unlock();
	thread_set_exceptions(exceptions);
	return ret;
}