/* arm.h - ARM CPU flags etc */ /* * Copyright (c) 1996-2006, 2008-2014 Wind River Systems, Inc. * * The right to copy, distribute, modify or otherwise make use * of this software may be licensed only pursuant to the terms * of an applicable Wind River license agreement. */ /* modification history -------------------- 17apr14,c_l add the write protection of L2 page table. (VXW6-73478) 02l,16mar13,yjw Update for ARMv7M 02k,08oct12,jdw Update FAST MATH for ARMARCH7 02j,14sep12,j_b fix whitespace issues 02i,28jun12,j_b add Cortex-A15 cache support 02h,09feb12,jdw Update definitions for __ieee_status(), WIND00332894 02g,01feb12,rec WIND00329076 - cleanup assembly macros to be consistent 02f,11aug11,jdw Add support for ARMv7 core optimizations 02e,23aug11,rec WIND00292261 - transition to common power management API 02d,15apr11,jdw Enable cached page tables 02c,13jan11,m_h Define _CACHE_ALIGN_SIZE as cacheArchAlignSize for ARMARCH7 02b,09jul10,fao add endianness state bit define 02a,21may10,m_h Thumb-2 Support 01z,02feb10,j_b add _WRS_ARM_HAS_ASID macro, defined for ARMv6+ 01y,23sep09,j_b add LDREX/STREX support for ARMARCH7 01x,06jun09,mdo Don't check IEEE status for FAST_MATH 01w,25feb09,j_b merge ARM SMP: 11jul07,j_b add ARMMMU_11MPCORE support 11jul07,to added ARM_HAS_LDREX_STREX feature macro 02jul07,m_h Adding types for MPCore varient 01v,27feb09,m_h ARMARCH7 Support 01u,12jun08,j_b add Cortex-A MMU and Cortex-A/-R cache support 01t,28apr08,m_h Create macro for NOP after LDM^ and STM^ 01s,13jul06,m_h MPU support 01r,25jan06,m_h Manzano support 01o,10oct05,scm correct SPR 111664 01n,04apr05,jb Adding ARMARCH6 and 1136 support 01m,21mar05,mdo Add define for ansiMath testing 01l,02mar05,mdo Add prototype for __ieee_status() and definitions for exception flags 01k,10aug04,scm remove MPU support... 01j,25nov03,sn Avoid gcc 3.3.2 preprocessor token pasting error 01i,26aug03,rec remove SYS_PWR_MGMT conditional 01h,07jul03,rec revert to non-portable kernel 01g,01jul03,rec code review comments 01f,28may03,rec Power Management 01f,17dec02,jb Adding ARM10 and 926E support 01e,15jan02,m_h ARMARCH5 thumb problem 01d,05nov01,t_m remove leading underscores via FUNC/VAR macros 01c,05nov01,t_m Undo underscores 01b,19jul01,ed Fixing to be compatible with Diab compiler. 01d,17oct01,t_m Merge in DIAB 01c,10oct01,jb Enabling removal of pre-pended underscores for new compilers (Diab/Gnu elf) 01b,23jul01,scm change XScale name to conform to coding standards... 01a,11dec00,scm replace references to ARMSA2 with XScale 01g,16oct00,scm reverse back I & F bits for SA2 01f,01sep00,scm add sa2 support... 01e,08feb99,jpd added further MMU/CACHE types. 01d,20jan99,cdp removed support for old ARM libraries. 01c,24aug98,cdp added MMU/cache types, ARM_HAS_MPU/ARM_THUMB, ARMST16/ARMST32. 01b,21aug97,cdp added _?_FUNCTION macros and HAS_HALFWORD_ 01a,08may96,cdp written */ #ifndef __INCarmh #define __INCarmh #ifdef __cplusplus extern "C" { #endif #if (CPU == ARMARCH7M) #include "arch/arm/arm-m/arm-m.h" #else /* (CPU == ARMARCH7M) */ /* Make sure excArmLib.h also has same settings */ /* bits in the PSR */ #define V_BIT (1<<28) #define C_BIT (1<<29) #define Z_BIT (1<<30) #define N_BIT (1<<31) #define E_BIT (1<<9) #define I_BIT (1<<7) #define F_BIT (1<<6) #define T_BIT (1<<5) /* mode bits */ #define MODE_SYSTEM32 0x1F #define MODE_UNDEF32 0x1B #define MODE_ABORT32 0x17 #define MODE_SVC32 0x13 #define MODE_IRQ32 0x12 #define MODE_FIQ32 0x11 #define MODE_USER32 0x10 #define MODE_MONITOR 0x16 /* masks for getting bits from PSR */ #ifdef ARM_INTERWORKINGSUPPORT #define MASK_MODE 0x0000003F #else /*ARM_INTERWORKINGSUPPORT*/ #define MASK_MODE 0x0000001F #endif /*ARM_INTERWORKINGSUPPORT*/ #define MASK_32MODE 0x0000001F #define MASK_SUBMODE 0x0000000F #define MASK_INT 0x000000C0 #define MASK_CC 0xF0000000 /* shifts to access bits in the PSR */ #define INT_MASK_SHIFT 6 /* The coprocessor number of the MMU System Control Processor */ #define CP_MMU 15 /* ARM MMU types */ #define ARMMMU_NONE 0 #define ARMMMU_710A 1 #define ARMMMU_810 2 #define ARMMMU_SA110 3 #define ARMMMU_940T 4 #define ARMMMU_740T 5 #define ARMMMU_SA1100 6 #define ARMMMU_SA1500 7 #define ARMMMU_720T 8 #define ARMMMU_920T 9 #define ARMMMU_946E 10 #define ARMMMU_XSCALE 11 #define ARMMMU_926E 12 #define ARMMMU_1020E 13 #define ARMMMU_1022E 14 #define ARMMMU_1136JF 15 #define ARMMMU_MANZANO 16 #define ARMMMU_CORTEXA8 17 #define ARMMMU_11MPCORE 18 #define ARMMPU_940T ARMMMU_940T #define ARMMPU_740T ARMMMU_740T #define ARMMPU_946E ARMMMU_946E /* ARM cache types */ #define ARMCACHE_NONE 0 #define ARMCACHE_710A 1 #define ARMCACHE_810 2 #define ARMCACHE_SA110 3 #define ARMCACHE_940T 4 #define ARMCACHE_740T 5 #define ARMCACHE_SA1100 6 #define ARMCACHE_SA1500 7 #define ARMCACHE_720T 8 #define ARMCACHE_920T 9 #define ARMCACHE_946E 10 #define ARMCACHE_XSCALE 11 #define ARMCACHE_926E 12 #define ARMCACHE_1020E 13 #define ARMCACHE_1022E 14 #define ARMCACHE_1136JF 15 #define ARMCACHE_MANZANO 16 #define ARMCACHE_CORTEXA8 17 #define ARMCACHE_11MPCORE 18 #define ARMCACHE_CORTEXA15 19 /* check CPU/cache/MMU features */ /* Cache Line sizes */ #if defined (_WRS_CONFIG_ARMV7_CORE_CTX_A8) || \ defined (_WRS_CONFIG_ARMV7_CORE_CTX_A15) #define _CPU_CACHE_ALIGN_SIZE 64 /* Cortex-A8 and Cortex-A15 use 64 bytes */ #else /* _WRS_CONFIG_ARMV7_CORE_CTX_A8 || _WRS_CONFIG_ARMV7_CORE_CTX_A15 */ /* * Most ARM cores have a cache line size of 32 bytes. * * This can be overridden through use of the global variable * cacheArchAlignSize. See below. */ #define _CPU_CACHE_ALIGN_SIZE 32 #endif /* _WRS_CONFIG_ARMV7_CORE_CTX_A8 || _WRS_CONFIG_ARMV7_CORE_CTX_A15 */ /* * The way in which _CACHE_ALIGN_SIZE is defined has been changed * somewhat and is no longer strictly related to the CPU type defined, * but is instead related to the cache type selected. Therefore, it would * be better if drivers that need to know the cache line size, use this * variable, rather than the constant. The variable will be initialized * to the appropriate cache-type-dependent value by the variant of the * cache library initialisation code. */ #ifndef _ASMLANGUAGE extern int cacheArchAlignSize; #endif /* _ASMLANGUAGE */ /* * Cached page tables are supported by ARM v6 and ARM v7 processors by * default. Turn them on here for default builds (e.g. builds not * configured by vxprj / VSBs). */ #if (!defined(_WRS_CONFIG_ARM_PRJ_BUILD) && \ ((CPU == ARMARCH6) || (CPU == ARMARCH7) || (CPU == ARMARCH7_T2))) #define _WRS_CONFIG_ENABLE_CACHED_PAGE_TBL #endif /* * Cached page tables are not supported for ARMv6 MPCore BSPs, so * disable this feature here for default & VSB builds */ #if ((defined (_WRS_CONFIG_SMP) && (CPU == ARMARCH6)) && \ defined (_WRS_CONFIG_ENABLE_CACHED_PAGE_TBL)) #undef _WRS_CONFIG_ENABLE_CACHED_PAGE_TBL #endif /* * Cached page tables are not supported for ARM v4 and ARM v5 processors, so * disable this feature here for default & VSB builds */ #if (((CPU == ARMARCH4) || (CPU == ARMARCH5) || (CPU == XSCALE)) && \ defined (_WRS_CONFIG_ENABLE_CACHED_PAGE_TBL)) #undef _WRS_CONFIG_ENABLE_CACHED_PAGE_TBL #endif #if ((CPU == ARMARCH7) || (CPU == ARMARCH7_T2)) /* * By default cache alignment for ARMv7 is 32 bytes. This is accomplished by * assigning cacheArchAlignSize as _CPU_CACHE_ALIGN_SIZE where it is declared * in cacheArchVars.c. But some cores can have a cache alignment that is not * 32 bytes. These cores will adjust the global variable cacheAlignSize * during runtime initialization. See cacheAimCortexA8LibInit for an example * of this. */ #undef _CACHE_ALIGN_SIZE #define _CACHE_ALIGN_SIZE cacheArchAlignSize /* this cpu family supports power management framework */ #define _WRS_ARCH_HAS_CPU_PWR_MGMT #else /* ((CPU == ARMARCH7) || (CPU == ARMARCH7_T2)) */ /* Cache alignment is 32 bytes */ #undef _CACHE_ALIGN_SIZE #define _CACHE_ALIGN_SIZE _CPU_CACHE_ALIGN_SIZE #endif /* ((CPU == ARMARCH7) || (CPU == ARMARCH7_T2)) */ #if (CPU == ARMARCH3) #define ARM_HAS_HALFWORD_INSTRUCTIONS FALSE #else #define ARM_HAS_HALFWORD_INSTRUCTIONS TRUE #endif #define ARM_HAS_MPU FALSE #if defined(ARMMMU) && (ARMMMU == ARMMMU_NONE) #define ARM_HAS_NO_MMU TRUE #else #define ARM_HAS_NO_MMU FALSE #endif #if (CPU == ARMARCH4_T) || (CPU == ARMARCH5_T) #define ARM_THUMB TRUE #else #define ARM_THUMB FALSE #endif #if (CPU == ARMARCH7_T2) #define ARM_THUMB2 TRUE #else /* (CPU == ARMARCH7_T2) */ #define ARM_THUMB2 FALSE #endif /* (CPU == ARMARCH7_T2) */ #if (ARM_THUMB2) #define PORTABLE #endif /* ARM_THUMB2 */ /* * For ARMv5 and earlier, STM(2) and LDM(2) instructions * must not be immediately followed by an * instruction that accesses a banked register. * Banked registers are: R8-R14. STM(2) and LDM(2) are * the variations of the OP codes that end with "^" * (load or store registers from a different mode -- user mode) * and do not load the PC (do not branch). * * One possible solution to this (suggested by the * ARM Architecture Reference Manual) is to insert * a NOP between the STM or LDM call and the access * to a banked register. * * Here is an example of where a NOP would be required * because sp is one of the banked registers: * * LDMIA r1, {sp, lr}^ * NOP * LDR r1, [sp, #SC_SAVE_USERSR] * * The asm macro ARM_NOP_AFTER_USER_LDM_STM is used for * inserting the NOP only if the version of the architecture * requires it. */ #if (CPU == ARMARCH4) || (CPU == ARMARCH5) || (CPU == XSCALE) #define ARM_NOP_AFTER_USER_LDM_STM NOP #else #define ARM_NOP_AFTER_USER_LDM_STM #endif #if (CPU == ARMARCH6) || (CPU==ARMARCH7) || (CPU==ARMARCH7_T2) #define ARM_HAS_LDREX_STREX TRUE #define _WRS_ARM_HAS_ASID TRUE #else /* (CPU == ARMARCH6) || (CPU==ARMARCH7) || (CPU==ARMARCH7_T2) */ #define ARM_HAS_LDREX_STREX FALSE #define _WRS_ARM_HAS_ASID FALSE #endif /* (CPU == ARMARCH6) || (CPU==ARMARCH7) || (CPU==ARMARCH7_T2) */ /** Power management for XSCALE **/ #if (CPU==XSCALE) /* The coprocessor number of the Power Mode Register */ #define CP_CCLKCFG 14 /* OPCODE for idle */ #define PWRMODE_IDLE 1 #endif /* Power management for XSCALE */ /** Power management for ARM **/ #if (CPU==ARMARCH5) || (CPU==ARMARCH5_T) || (CPU==ARMARCH6) \ || (CPU==ARMARCH7) || (CPU==ARMARCH7_T2) /* The coprocessor number of the Power Mode Register */ #define CP_CORECTL 15 /* OPCODE for idle */ #define PWRMODE_IDLE 1 #endif /* CPU==ARMARCH5 ... ARMARCH7_T2 */ #if !defined(_WRS_CONFG_FAST_MATH) || (VFPVARIANT != VFPV3) /* Define __ieee_status exception flags */ #define FE_IEEE_FLUSHZERO (0x01000000) #define FE_IEEE_ROUND_TONEAREST (0x00000000) #define FE_IEEE_ROUND_UPWARD (0x00400000) #define FE_IEEE_ROUND_DOWNWARD (0x00800000) #define FE_IEEE_ROUND_TOWARDZERO (0x00C00000) #define FE_IEEE_ROUND_MASK (0x00C00000) #define FE_IEEE_MASK_INVALID (0x00000100) #define FE_IEEE_MASK_DIVBYZERO (0x00000200) #define FE_IEEE_MASK_OVERFLOW (0x00000400) #define FE_IEEE_MASK_UNDERFLOW (0x00000800) #define FE_IEEE_MASK_INEXACT (0x00001000) #define FE_IEEE_MASK_ALL_EXCEPT (0x00001F00) #define FE_IEEE_INVALID (0x00000001) #define FE_IEEE_DIVBYZERO (0x00000002) #define FE_IEEE_OVERFLOW (0x00000004) #define FE_IEEE_UNDERFLOW (0x00000008) #define FE_IEEE_INEXACT (0x00000010) #define FE_IEEE_ALL_EXCEPT (0x0000001F) /* Define which of the IEEE status bits are reserved */ #define IEEE_RESERVED_MASK (0xF63FE0E0) #ifndef _ASMLANGUAGE extern unsigned int __ieee_status (unsigned int mask, unsigned int flags); #endif /* Define for ansiMath Testing */ #define _WRS_ARM_IEEE_STATUS #endif /* * The default for ARMARCH7 and ARMARCH7_T2 is to use _WRS_CONFIG_FAST_MATH to * optimize builds created with VFP enabled. The flag to enable this behavior * is from the make fragments for a CPU/TOOL pair. * * Builds that use a SW FP tool chain should not use FAST MATH to get best * performance. * * Override VSB options here because VSB configuration does not detect the * tool chain / floating point configuration properly. */ #if defined(ARM_USE_VFP) /* Vector floating point builds use FAST MATH */ #undef _WRS_CONFIG_FAST_MATH #define _WRS_CONFIG_FAST_MATH 1 #else /* Software floating point build does NOT use FAST MATH */ #undef _WRS_CONFIG_FAST_MATH #endif /* defined(USE_ARM_FP) ... */ /* * The default for ARMARCH7 and ARMARCH7_T2 is to use _WRS_CONFIG_FAST_MATH to * optimize builds created with VFP enabled. The flag to enable this behavior * is from the make fragments for a CPU/TOOL pair. * * Builds that use a SW FP tool chain should not use FAST MATH to get best * performance. * * Override VSB options here because VSB configuration does not detect the * tool chain / floating point configuration properly. */ #if defined(ARM_USE_VFP) /* Vector floating point builds use FAST MATH */ #undef _WRS_CONFIG_FAST_MATH #define _WRS_CONFIG_FAST_MATH 1 #else /* Software floating point build does NOT use FAST MATH */ #undef _WRS_CONFIG_FAST_MATH #endif /* defined(USE_ARM_FP) ... */ #ifdef _ASMLANGUAGE /* * File below inclusion must be after ARCH specific defines such as ARM_THUMB2. */ #include /** I80310 (coyanosa) specific helper macros **/ #if ((CPU==XSCALE) || (CPU==ARMSA110)) /* * The following macro should be used when software needs to be assured that a * CP15 update has taken effect. It may only used while in a privileged mode, * because it accesses CP15. Ref. Coyanosa EAS 2.3.4 Additions to CP15 * functionality */ #define CPWAIT(a) \ mrc p15, 0, a, c2, c0, 0 /* arbitrary read of CP15 */ ;\ mov a, a /* wait for it */ ;\ sub pc, pc, IMMED4 /* branch to next instruction */ ; #define IMMED4 #4 /* * at this point, any previous CP15 writes are guaranteed * to have taken effect */ /* * The following macro should be used when software needs to be assure that * BCU has finish all outstanding operations. */ /* * CAUTION: This macro should be used only from the cacheable region, or it may * keep the BCU eternally busy fetching the code. */ #define BCUWAIT(a) \ mrc p13, 0, a, c0, c1, 0; /* Read BCUCTL,updates conditon code */ \ submi pc, pc, IMMED12 ; /* If BCU busy (bit 31 set) try again */ #define IMMED12 #12 #endif /* if CPU=XSCALE */ #endif /* _ASMLANGUAGE */ #endif /* (CPU == ARMARCH7M) */ #ifdef __cplusplus } #endif #endif /* __INCarmh */