Esempio n. 1
0
void init_sec_mon(unsigned long nsec_entry)
{
	struct plat_nsec_ctx *plat_ctx;
	struct sm_nsec_ctx *nsec_ctx;

	plat_ctx = phys_to_virt(nsec_entry, MEM_AREA_IO_SEC);
	if (!plat_ctx)
		panic();

	/* Invalidate cache to fetch data from external memory */
	cache_op_inner(DCACHE_AREA_INVALIDATE,
			plat_ctx, sizeof(*plat_ctx));

	/* Initialize secure monitor */
	nsec_ctx = sm_get_nsec_ctx();

	nsec_ctx->mode_regs.usr_sp = plat_ctx->usr_sp;
	nsec_ctx->mode_regs.usr_lr = plat_ctx->usr_lr;
	nsec_ctx->mode_regs.irq_spsr = plat_ctx->irq_spsr;
	nsec_ctx->mode_regs.irq_sp = plat_ctx->irq_sp;
	nsec_ctx->mode_regs.irq_lr = plat_ctx->irq_lr;
	nsec_ctx->mode_regs.svc_spsr = plat_ctx->svc_spsr;
	nsec_ctx->mode_regs.svc_sp = plat_ctx->svc_sp;
	nsec_ctx->mode_regs.svc_lr = plat_ctx->svc_lr;
	nsec_ctx->mode_regs.abt_spsr = plat_ctx->abt_spsr;
	nsec_ctx->mode_regs.abt_sp = plat_ctx->abt_sp;
	nsec_ctx->mode_regs.abt_lr = plat_ctx->abt_lr;
	nsec_ctx->mode_regs.und_spsr = plat_ctx->und_spsr;
	nsec_ctx->mode_regs.und_sp = plat_ctx->und_sp;
	nsec_ctx->mode_regs.und_lr = plat_ctx->und_lr;
	nsec_ctx->mon_lr = plat_ctx->mon_lr;
	nsec_ctx->mon_spsr = plat_ctx->mon_spsr;
}
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;
}