mirror of
				https://source.denx.de/u-boot/u-boot.git
				synced 2025-11-04 10:21:25 +01:00 
			
		
		
		
	Move this uncommon header out of the common header. Signed-off-by: Simon Glass <sjg@chromium.org>
		
			
				
	
	
		
			165 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			165 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
// SPDX-License-Identifier: GPL-2.0+
 | 
						|
/*
 | 
						|
 * Copyright 2015 Freescale Semiconductor, Inc.
 | 
						|
 */
 | 
						|
 | 
						|
#include <common.h>
 | 
						|
#include <fsl_sec_mon.h>
 | 
						|
#include <linux/delay.h>
 | 
						|
 | 
						|
static u32 get_sec_mon_state(void)
 | 
						|
{
 | 
						|
	struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
 | 
						|
						(CONFIG_SYS_SEC_MON_ADDR);
 | 
						|
	return sec_mon_in32(&sec_mon_regs->hp_stat) & HPSR_SSM_ST_MASK;
 | 
						|
}
 | 
						|
 | 
						|
static int set_sec_mon_state_non_sec(void)
 | 
						|
{
 | 
						|
	u32 sts;
 | 
						|
	int timeout = 10;
 | 
						|
	struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
 | 
						|
						(CONFIG_SYS_SEC_MON_ADDR);
 | 
						|
 | 
						|
	sts = get_sec_mon_state();
 | 
						|
 | 
						|
	switch (sts) {
 | 
						|
	/*
 | 
						|
	 * If initial state is check or Non-Secure, then set the Software
 | 
						|
	 * Security Violation Bit and transition to Non-Secure State.
 | 
						|
	 */
 | 
						|
	case HPSR_SSM_ST_CHECK:
 | 
						|
		printf("SEC_MON state transitioning to Non Secure.\n");
 | 
						|
		sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_SV);
 | 
						|
 | 
						|
		/* polling loop till SEC_MON is in Non Secure state */
 | 
						|
		while (timeout) {
 | 
						|
			sts = get_sec_mon_state();
 | 
						|
 | 
						|
			if ((sts & HPSR_SSM_ST_MASK) ==
 | 
						|
				HPSR_SSM_ST_NON_SECURE)
 | 
						|
				break;
 | 
						|
 | 
						|
			udelay(10);
 | 
						|
			timeout--;
 | 
						|
		}
 | 
						|
 | 
						|
		if (timeout == 0) {
 | 
						|
			printf("SEC_MON state transition timeout.\n");
 | 
						|
			return -1;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	/*
 | 
						|
	 * If initial state is Trusted, Secure or Soft-Fail, then first set
 | 
						|
	 * the Software Security Violation Bit and transition to Soft-Fail
 | 
						|
	 * State.
 | 
						|
	 */
 | 
						|
	case HPSR_SSM_ST_TRUST:
 | 
						|
	case HPSR_SSM_ST_SECURE:
 | 
						|
	case HPSR_SSM_ST_SOFT_FAIL:
 | 
						|
		printf("SEC_MON state transitioning to Soft Fail.\n");
 | 
						|
		sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_SV);
 | 
						|
 | 
						|
		/* polling loop till SEC_MON is in Soft-Fail state */
 | 
						|
		while (timeout) {
 | 
						|
			sts = get_sec_mon_state();
 | 
						|
 | 
						|
			if ((sts & HPSR_SSM_ST_MASK) ==
 | 
						|
				HPSR_SSM_ST_SOFT_FAIL)
 | 
						|
				break;
 | 
						|
 | 
						|
			udelay(10);
 | 
						|
			timeout--;
 | 
						|
		}
 | 
						|
 | 
						|
		if (timeout == 0) {
 | 
						|
			printf("SEC_MON state transition timeout.\n");
 | 
						|
			return -1;
 | 
						|
		}
 | 
						|
 | 
						|
		timeout = 10;
 | 
						|
 | 
						|
		/*
 | 
						|
		 * If SSM Soft Fail to Non-Secure State Transition
 | 
						|
		 * disable is not set, then set SSM_ST bit and
 | 
						|
		 * transition to Non-Secure State.
 | 
						|
		 */
 | 
						|
		if ((sec_mon_in32(&sec_mon_regs->hp_com) &
 | 
						|
			HPCOMR_SSM_SFNS_DIS) == 0) {
 | 
						|
			printf("SEC_MON state transitioning to Non Secure.\n");
 | 
						|
			sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SSM_ST);
 | 
						|
 | 
						|
			/* polling loop till SEC_MON is in Non Secure*/
 | 
						|
			while (timeout) {
 | 
						|
				sts = get_sec_mon_state();
 | 
						|
 | 
						|
				if ((sts & HPSR_SSM_ST_MASK) ==
 | 
						|
					HPSR_SSM_ST_NON_SECURE)
 | 
						|
					break;
 | 
						|
 | 
						|
				udelay(10);
 | 
						|
				timeout--;
 | 
						|
			}
 | 
						|
 | 
						|
			if (timeout == 0) {
 | 
						|
				printf("SEC_MON state transition timeout.\n");
 | 
						|
				return -1;
 | 
						|
			}
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	default:
 | 
						|
		printf("SEC_MON already in Non Secure state.\n");
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int set_sec_mon_state_soft_fail(void)
 | 
						|
{
 | 
						|
	u32 sts;
 | 
						|
	int timeout = 10;
 | 
						|
	struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
 | 
						|
						(CONFIG_SYS_SEC_MON_ADDR);
 | 
						|
 | 
						|
	printf("SEC_MON state transitioning to Soft Fail.\n");
 | 
						|
	sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_FSV);
 | 
						|
 | 
						|
	/* polling loop till SEC_MON is in Soft-Fail state */
 | 
						|
	while (timeout) {
 | 
						|
		sts = get_sec_mon_state();
 | 
						|
 | 
						|
		if ((sts & HPSR_SSM_ST_MASK) ==
 | 
						|
			HPSR_SSM_ST_SOFT_FAIL)
 | 
						|
			break;
 | 
						|
 | 
						|
		udelay(10);
 | 
						|
		timeout--;
 | 
						|
	}
 | 
						|
 | 
						|
	if (timeout == 0) {
 | 
						|
		printf("SEC_MON state transition timeout.\n");
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
int set_sec_mon_state(u32 state)
 | 
						|
{
 | 
						|
	int ret = -1;
 | 
						|
 | 
						|
	switch (state) {
 | 
						|
	case HPSR_SSM_ST_NON_SECURE:
 | 
						|
		ret = set_sec_mon_state_non_sec();
 | 
						|
		break;
 | 
						|
	case HPSR_SSM_ST_SOFT_FAIL:
 | 
						|
		ret = set_sec_mon_state_soft_fail();
 | 
						|
		break;
 | 
						|
	default:
 | 
						|
		printf("SEC_MON state transition not supported.\n");
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
 | 
						|
	return ret;
 | 
						|
}
 |