blob: 8c9fc37eee226dbade495d0656788d8abf692fa4 [file] [log] [blame]
/*
* Copyright (c) 2013 TRUSTONIC LIMITED
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _MC_ARM_H_
#define _MC_ARM_H_
#include "debug.h"
#ifdef CONFIG_ARM64
inline bool has_security_extensions(void)
{
return true;
}
inline bool is_secure_mode(void)
{
return false;
}
#else
/*
* ARM Trustzone specific masks and modes
* Vanilla Linux is unaware of TrustZone extension.
* I.e. arch/arm/include/asm/ptrace.h does not define monitor mode.
* Also TZ bits in cpuid are not defined, ARM port uses magic numbers,
* see arch/arm/kernel/setup.c
*/
#define ARM_MONITOR_MODE (0x16) /*(0b10110)*/
#define ARM_SECURITY_EXTENSION_MASK (0x30)
/* check if CPU supports the ARM TrustZone Security Extensions */
inline bool has_security_extensions(void)
{
u32 fea = 0;
asm volatile(
"mrc p15, 0, %[fea], cr0, cr1, 0" :
[fea]"=r" (fea));
MCDRV_DBG_VERBOSE(mcd, "CPU Features: 0x%X", fea);
/*
* If the CPU features ID has 0 for security features then the CPU
* doesn't support TrustZone at all!
*/
if ((fea & ARM_SECURITY_EXTENSION_MASK) == 0)
return false;
return true;
}
/* check if running in secure mode */
inline bool is_secure_mode(void)
{
u32 cpsr = 0;
u32 nsacr = 0;
asm volatile(
"mrc p15, 0, %[nsacr], cr1, cr1, 2\n"
"mrs %[cpsr], cpsr\n" :
[nsacr]"=r" (nsacr),
[cpsr]"=r"(cpsr));
MCDRV_DBG_VERBOSE(mcd, "CPRS.M = set to 0x%X\n", cpsr & MODE_MASK);
MCDRV_DBG_VERBOSE(mcd, "SCR.NS = set to 0x%X\n", nsacr);
/*
* If the NSACR contains the reset value(=0) then most likely we are
* running in Secure MODE.
* If the cpsr mode is set to monitor mode then we cannot load!
*/
if (nsacr == 0 || ((cpsr & MODE_MASK) == ARM_MONITOR_MODE))
return true;
return false;
}
#endif
#endif /* _MC_ARM_H_ */