/**
 *  \file   cp15.h
 *
 *  \brief  CP15 related function prototypes
 *
 *  This file contains the API prototypes for configuring CP15
*/

/*
* Copyright (C) 2010-2014 Texas Instruments Incorporated - http://www.ti.com/
*/
/*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*    Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
*    Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the
*    distribution.
*
*    Neither the name of Texas Instruments Incorporated nor the names of
*    its contributors may be used to endorse or promote products derived
*    from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
 Updated by Brighton Feng for Cortex A15 on June 18, 2014
*/


#ifndef __CP15_H
#define __CP15_H

#ifdef __cplusplus
extern "C" {
#endif
#include <tistdtypes.h>
/*****************************************************************************/
/*
** Macros which can be passed to CP15XXXXConfigBitField or CP15XXXXConfig APIs 
** as 'feature', 'value', and 'mask'. Any, or an OR combination of the below macros can be
** passed to disable/enable the corresponding feature.
*/

/* CP15 SCTLR Bit fields definition */
#define CP15_SCTLR_THUMB_EXCPT_DISABLE                 (0x00000000<<30)
#define CP15_SCTLR_THUMB_EXCPT_ENABLE                  (0x00000001<<30)
#define CP15_SCTLR_THUMB_EXCPT_MASK                    (0x00000001<<30)

#define CP15_SCTLR_ACCESS_FLAG_DISABLE                 (0x00000000<<29)
#define CP15_SCTLR_ACCESS_FLAG_ENABLE                  (0x00000001<<29)
#define CP15_SCTLR_ACCESS_FLAG_MASK                    (0x00000001<<29)

#define CP15_SCTLR_TXE_REMAP_DISABLE                   (0x00000000<<28)
#define CP15_SCTLR_TXE_REMAP_ENABLE                    (0x00000001<<28)
#define CP15_SCTLR_TXE_REMAP_MASK                      (0x00000001<<28)

#define CP15_SCTLR_EXCEPT_ENDIAN_LE                    (0x00000000<<25)
#define CP15_SCTLR_EXCEPT_ENDIAN_BE                    (0x00000001<<25)
#define CP15_SCTLR_EXCEPT_MASK                         (0x00000001<<25)

#define CP15_SCTLR_UNPRI_WR_EXE_NEVER_DISABLE          (0x00000000<<20)
#define CP15_SCTLR_UNPRI_WR_EXE_NEVER_ENABLE           (0x00000001<<20)
#define CP15_SCTLR_UNPRI_WR_EXE_NEVER_MASK             (0x00000001<<20)

#define CP15_SCTLR_PRI_WR_EXE_NEVER_DISABLE            (0x00000000<<19)
#define CP15_SCTLR_PRI_WR_EXE_NEVER_ENABLE             (0x00000001<<19)
#define CP15_SCTLR_PRI_WR_EXE_NEVER_MASK               (0x00000001<<19)

#define CP15_SCTLR_EXCEPTION_VECTOR_NORMAL             (0x00000000<<13)
#define CP15_SCTLR_EXCEPTION_VECTOR_HIGH               (0x00000001<<13)
#define CP15_SCTLR_EXCEPTION_VECTOR_MASK               (0x00000001<<13)

#define CP15_SCTLR_INSTRUCT_CACHE_DISABLE              (0x00000000<<12)
#define CP15_SCTLR_INSTRUCT_CACHE_ENABLE               (0x00000001<<12)
#define CP15_SCTLR_INSTRUCT_CACHE_MASK                 (0x00000001<<12)

#define CP15_SCTLR_BRANCH_PREDICT_DISABLE              (0x00000000<<11)
#define CP15_SCTLR_BRANCH_PREDICT_ENABLE               (0x00000001<<11)
#define CP15_SCTLR_BRANCH_PREDICT_MASK                 (0x00000001<<11)

#define CP15_SCTLR_SWP_SWPB_DISABLE                    (0x00000000<<10)
#define CP15_SCTLR_SWP_SWPB_ENABLE                     (0x00000001<<10)
#define CP15_SCTLR_SWP_SWPB_MASK                       (0x00000001<<10)

#define CP15_SCTLR_CACHE_DISABLE                       (0x00000000<<2)
#define CP15_SCTLR_CACHE_ENABLE                        (0x00000001<<2)
#define CP15_SCTLR_CACHE_MASK                          (0x00000001<<2)

#define CP15_SCTLR_ALIGN_CHECK_DISABLE                 (0x00000000<<1)
#define CP15_SCTLR_ALIGN_CHECK_ENABLE                  (0x00000001<<1)
#define CP15_SCTLR_ALIGN_CHECK_MASK                    (0x00000001<<1)

#define CP15_SCTLR_MMU_DISABLE                         (0x00000000)
#define CP15_SCTLR_MMU_ENABLE                          (0x00000001)
#define CP15_SCTLR_MMU_MASK                            (0x00000001)

#define CP15_SCTLR_THUMB_EXCPT_SHIFT                    (30)
#define CP15_SCTLR_ACCESS_FLAG_SHIFT                    (29)
#define CP15_SCTLR_TXE_REMAP_SHIFT                      (28)
#define CP15_SCTLR_EXCEPT_SHIFT                         (25)
#define CP15_SCTLR_UNPRI_WR_EXE_NEVER_SHIFT             (20)
#define CP15_SCTLR_PRI_WR_EXE_NEVER_SHIFT               (19)
#define CP15_SCTLR_EXCEPTION_VECTOR_SHIFT               (13)
#define CP15_SCTLR_INSTRUCT_CACHE_SHIFT                 (12)
#define CP15_SCTLR_BRANCH_PREDICT_SHIFT                 (11)
#define CP15_SCTLR_SWP_SWPB_SHIFT                       (10)
#define CP15_SCTLR_CACHE_SHIFT                          (2)
#define CP15_SCTLR_ALIGN_CHECK_SHIFT                    (1)
#define CP15_SCTLR_MMU_SHIFT                            (0)


/* CP15 ACTLR Bit fields definition */
#define CP15_ACTLR_ENABLE_INVALIDATES_BTB_MASK          (1<<0 )
#define CP15_ACTLR_DISABLE_LOOP_BUFFER_MASK             (1<<1 )
#define CP15_ACTLR_ONE_LOOP_BUFFER_MASK                 (1<<2 )
#define CP15_ACTLR_DISABLE_MICRO_BTB_MASK               (1<<3 )
#define CP15_ACTLR_DISABLE_INDIRECT_PREDICTOR_MASK      (1<<4 )
#define CP15_ACTLR_PLD_NOP_MASK                         (1<<5 )
#define CP15_ACTLR_SMP_MASK                             (1<<6 )
#define CP15_ACTLR_WFE_NOP_MASK                         (1<<7 )
#define CP15_ACTLR_WFI_NOP_MASK                         (1<<8 )
#define CP15_ACTLR_DISABLE_FLAG_RENAMING_MASK           (1<<9 )
#define CP15_ACTLR_FORCE_SERIALIZATION_MASK             (1<<10)
#define CP15_ACTLR_ONE_INSTRUCTION_GROUP_MASK           (1<<11)
#define CP15_ACTLR_PUSH_CP_WRITES_MASK                  (1<<12)
#define CP15_ACTLR_FLUSH_CP_WRITES_MASK                 (1<<13)
#define CP15_ACTLR_ONE_COMMIT_DEALLOCATE_MASK           (1<<14)
#define CP15_ACTLR_IN_ORDER_BRANCH_MASK                 (1<<15)
#define CP15_ACTLR_LOAD_REPLAY_MASK                     (1<<16)
#define CP15_ACTLR_DISABLE_L2_TLB_OPT_MASK              (1<<17)
#define CP15_ACTLR_DISABLE_TTB_WALK_L2_PA_CACHE_MASK    (1<<18)
#define CP15_ACTLR_DISABLE_TTB_WALK_CACHE_MASK          (1<<19)
#define CP15_ACTLR_DISABLE_TTB_WALK_IPA_PA_CACHE_MASK   (1<<20)
#define CP15_ACTLR_DISABLE_L2_TLB_PREFETCHING_MASK      (1<<21)
#define CP15_ACTLR_IN_ORDER_LOAD_ISSUE_MASK             (1<<22)
#define CP15_ACTLR_IN_ORDER_REQUESTS_MASK               (1<<23)
#define CP15_ACTLR_NON_CACH_STREAMING_ENHANCE_MASK      (1<<24)
#define CP15_ACTLR_WRITE_NO_L1_ALLOCATE_THRESHOLD_MASK  (3<<25)
#define CP15_ACTLR_WRITE_NO_ALLOCATE_THRESHOLD_MASK     (3<<27)
#define CP15_ACTLR_NEON_VFP_CLOCK_ACTIVE_MASK           (1<<29)
#define CP15_ACTLR_MAIN_CLOCK_ACTIVE_MASK               (1<<30)
#define CP15_ACTLR_SNOOP_DELAYED_HANDLING_MASK          (1<<31)

#define CP15_ACTLR_ENABLE_INVALIDATES_BTB_SHIFT          (0 )
#define CP15_ACTLR_DISABLE_LOOP_BUFFER_SHIFT             (1 )
#define CP15_ACTLR_ONE_LOOP_BUFFER_SHIFT                 (2 )
#define CP15_ACTLR_DISABLE_MICRO_BTB_SHIFT               (3 )
#define CP15_ACTLR_DISABLE_INDIRECT_PREDICTOR_SHIFT      (4 )
#define CP15_ACTLR_PLD_NOP_SHIFT                         (5 )
#define CP15_ACTLR_SMP_SHIFT                             (6 )
#define CP15_ACTLR_WFE_NOP_SHIFT                         (7 )
#define CP15_ACTLR_WFI_NOP_SHIFT                         (8 )
#define CP15_ACTLR_DISABLE_FLAG_RENAMING_SHIFT           (9 )
#define CP15_ACTLR_FORCE_SERIALIZATION_SHIFT             (10)
#define CP15_ACTLR_ONE_INSTRUCTION_GROUP_SHIFT           (11)
#define CP15_ACTLR_PUSH_CP_WRITES_SHIFT                  (12)
#define CP15_ACTLR_FLUSH_CP_WRITES_SHIFT                 (13)
#define CP15_ACTLR_ONE_COMMIT_DEALLOCATE_SHIFT           (14)
#define CP15_ACTLR_IN_ORDER_BRANCH_SHIFT                 (15)
#define CP15_ACTLR_LOAD_REPLAY_SHIFT                     (16)
#define CP15_ACTLR_DISABLE_L2_TLB_OPT_SHIFT              (17)
#define CP15_ACTLR_DISABLE_TTB_WALK_L2_PA_CACHE_SHIFT    (18)
#define CP15_ACTLR_DISABLE_TTB_WALK_CACHE_SHIFT          (19)
#define CP15_ACTLR_DISABLE_TTB_WALK_IPA_PA_CACHE_SHIFT   (20)
#define CP15_ACTLR_DISABLE_L2_TLB_PREFETCHING_SHIFT      (21)
#define CP15_ACTLR_IN_ORDER_LOAD_ISSUE_SHIFT             (22)
#define CP15_ACTLR_IN_ORDER_REQUESTS_SHIFT               (23)
#define CP15_ACTLR_NON_CACH_STREAMING_ENHANCE_SHIFT      (24)
#define CP15_ACTLR_WRITE_NO_L1_ALLOCATE_THRESHOLD_SHIFT  (25)
#define CP15_ACTLR_WRITE_NO_ALLOCATE_THRESHOLD_SHIFT     (27)
#define CP15_ACTLR_NEON_VFP_CLOCK_ACTIVE_SHIFT           (29)
#define CP15_ACTLR_MAIN_CLOCK_ACTIVE_SHIFT               (30)
#define CP15_ACTLR_SNOOP_DELAYED_HANDLING_SHIFT          (31)

#define CP15_ISR_A_SHIFT     (8)
#define CP15_ISR_I_SHIFT     (7)
#define CP15_ISR_F_SHIFT     (6)
#define CP15_ISR_A_MASK     (1<<8)
#define CP15_ISR_I_MASK     (1<<7)
#define CP15_ISR_F_MASK     (1<<6)

/* CP15 TTBCR Bit fields definition for Short Descriptor with Security implementation */
#define CP15_TTBCR_SHORT_EAE_NO_LPAE                        (0x00000000<<31)
//#define CP15_TTBCR_SHORT_EAE_LPAE                           (0x1<<31)

#define CP15_TTBCR_SHORT_PD1_USE_TTBR1                      (0x00000000<<5)
#define CP15_TTBCR_SHORT_PD1_GEN_TRANS_FAULT_TTBR1          (0x00000001<<5)

#define CP15_TTBCR_SHORT_PD0_USE_TTBR0                      (0x00000000<<4)
#define CP15_TTBCR_SHORT_PD0_GEN_TRANS_FAULT_TTBR0          (0x00000001<<4)

#define CP15_TTBCR_SHORT_N_TTBR0_ONLY                       (0x00000000)
#define CP15_TTBCR_SHORT_N_TTBR0_VA_30_20                   (0x00000001)
#define CP15_TTBCR_SHORT_N_TTBR0_VA_29_20                   (0x00000002)
#define CP15_TTBCR_SHORT_N_TTBR0_VA_28_20                   (0x00000003)
#define CP15_TTBCR_SHORT_N_TTBR0_VA_27_20                   (0x00000004)
#define CP15_TTBCR_SHORT_N_TTBR0_VA_26_20                   (0x00000005)
#define CP15_TTBCR_SHORT_N_TTBR0_VA_25_20                   (0x00000006)
#define CP15_TTBCR_SHORT_N_TTBR0_VA_24_20                   (0x00000007)


/* CP15 TTBCR Bit fields definition for Long Descriptor with Security implementation */
//#define CP15_TTBCR_LONG_EAE_NO_LPAE                         (0x0<<31)
#define CP15_TTBCR_LONG_EAE_LPAE                    (0x00000001<<31)

#define CP15_TTBCR_LONG_SH1_NON_SHARE               (0x00000000<<28)
#define CP15_TTBCR_LONG_SH1_OUTER_SHARE             (0x00000002<<28)
#define CP15_TTBCR_LONG_SH1_INNER_SHARE             (0x00000003<<28)

#define CP15_TTBCR_LONG_ORGN1_NON_CACHE             (0x00000000<<26)
#define CP15_TTBCR_LONG_ORGN1_WB_WA_CACHE           (0x00000001<<26)
#define CP15_TTBCR_LONG_ORGN1_WT_CACHE              (0x00000002<<26)
#define CP15_TTBCR_LONG_ORGN1_WB_NO_WA_CACHE        (0x00000003<<26)

#define CP15_TTBCR_LONG_IRGN1_NON_CACHE             (0x00000000<<24)
#define CP15_TTBCR_LONG_IRGN1_WB_WA_CACHE           (0x00000001<<24)
#define CP15_TTBCR_LONG_IRGN1_WT_CACHE              (0x00000002<<24)
#define CP15_TTBCR_LONG_IRGN1_WB_NO_WA_CACHE        (0x00000003<<24)

#define CP15_TTBCR_LONG_EPD1_USE_TTBR1              (0x00000000<<23)
#define CP15_TTBCR_LONG_EPD1_GEN_TRANS_FAULT_TTBR1  (0x00000001<<23)

#define CP15_TTBCR_LONG_A1_ASID_TTBR0               (0x00000000<<22)
#define CP15_TTBCR_LONG_A1_ASID_TTBR1               (0x00000001<<22)

#define CP15_TTBCR_LONG_T1SZ_ALL_ZERO               (0x00000000)

#define CP15_TTBCR_LONG_SH0_NON_SHARE               (0x00000000<<12)
#define CP15_TTBCR_LONG_SH0_OUTER_SHARE             (0x00000002<<12)
#define CP15_TTBCR_LONG_SH0_INNER_SHARE             (0x00000003<<12)

#define CP15_TTBCR_LONG_ORGN0_NON_CACHE             (0x00000000<<10)
#define CP15_TTBCR_LONG_ORGN0_WB_WA_CACHE           (0x00000001<<10)
#define CP15_TTBCR_LONG_ORGN0_WT_CACHE              (0x00000002<<10)
#define CP15_TTBCR_LONG_ORGN0_WB_NO_WA_CACHE        (0x00000003<<10)

#define CP15_TTBCR_LONG_IRGN0_NON_CACHE             (0x00000000<<8)
#define CP15_TTBCR_LONG_IRGN0_WB_WA_CACHE           (0x00000001<<8)
#define CP15_TTBCR_LONG_IRGN0_WT_CACHE              (0x00000002<<8)
#define CP15_TTBCR_LONG_IRGN0_WB_NO_WA_CACHE        (0x00000003<<8)

#define CP15_TTBCR_LONG_EPD0_USE_TTBR0              (0x00000000<<7)
#define CP15_TTBCR_LONG_EPD0_GEN_TRANS_FAULT_TTBR0  (0x00000001<<7)

#define CP15_TTBCR_LONG_T0SZ_ALL_ZERO               (0x00000000)

#define CP15_TTBCR_LONG_EAE_SHIFT                   (31)
#define CP15_TTBCR_LONG_SH1_SHIFT                   (28)
#define CP15_TTBCR_LONG_ORGN1_SHIFT                 (26)
#define CP15_TTBCR_LONG_IRGN1_SHIFT                 (24)
#define CP15_TTBCR_LONG_EPD1_SHIFT                  (23)
#define CP15_TTBCR_LONG_A1_SHIFT                    (22)
#define CP15_TTBCR_LONG_T1SZ_SHIFT                  (16)
#define CP15_TTBCR_LONG_SH0_SHIFT                   (12)
#define CP15_TTBCR_LONG_ORGN0_SHIFT                 (10)
#define CP15_TTBCR_LONG_IRGN0_SHIFT                 (8 )
#define CP15_TTBCR_LONG_EPD0_SHIFT                  (7 )
#define CP15_TTBCR_LONG_T0SZ_SHIFT                  (0 )
                                                   
#define CP15_TTBCR_LONG_EAE_MASK                   (1<<31)
#define CP15_TTBCR_LONG_SH1_MASK                   (3<<28)
#define CP15_TTBCR_LONG_ORGN1_MASK                 (3<<26)
#define CP15_TTBCR_LONG_IRGN1_MASK                 (3<<24)
#define CP15_TTBCR_LONG_EPD1_MASK                  (1<<23)
#define CP15_TTBCR_LONG_A1_MASK                    (1<<22)
#define CP15_TTBCR_LONG_T1SZ_MASK                  (7<<16)
#define CP15_TTBCR_LONG_SH0_MASK                   (3<<12)
#define CP15_TTBCR_LONG_ORGN0_MASK                 (3<<10)
#define CP15_TTBCR_LONG_IRGN0_MASK                 (3<<8 )
#define CP15_TTBCR_LONG_EPD0_MASK                  (1<<7 )
#define CP15_TTBCR_LONG_T0SZ_MASK                  (7<<0 )

/* CP15 MAIR0/1 Bit fields definition with LPAE implementation */
#define CP15_MAIR_ATTR_STRONGLY_ORDERED                     (0x00000000)
#define CP15_MAIR_ATTR_NORM_IN_WT_WA_NO_RA_TRANSIENT        (0x000000F1)
#define CP15_MAIR_ATTR_NORM_IN_WT_RA_NO_WA_TRANSIENT        (0x000000F2)
#define CP15_MAIR_ATTR_NORM_IN_WT_RA_WA_TRANSIENT           (0x000000F3)
#define CP15_MAIR_ATTR_DEVICE                               (0x00000004)
#define CP15_MAIR_ATTR_NORM_IN_NON_CACHE                    (0x000000F4)
#define CP15_MAIR_ATTR_NORM_IN_WB_WA_NO_RA_TRANSIENT        (0x000000F5)
#define CP15_MAIR_ATTR_NORM_IN_WB_RA_NO_WA_TRANSIENT        (0x000000F6)
#define CP15_MAIR_ATTR_NORM_IN_WB_RA_WA_TRANSIENT           (0x000000F7)
#define CP15_MAIR_ATTR_NORM_IN_WT_WA_NO_RA_CACHE_NO_TRANS   (0x000000F9)
#define CP15_MAIR_ATTR_NORM_IN_WT_RA_NO_WA_CACHE_NO_TRANS   (0x000000FA)
#define CP15_MAIR_ATTR_NORM_IN_WT_RA_WA_CACHE_NO_TRANS      (0x000000FB)
#define CP15_MAIR_ATTR_NORM_IN_WB_WA_NO_RA_CACHE_NO_TRANS   (0x000000FD)
#define CP15_MAIR_ATTR_NORM_IN_WB_RA_NO_WA_CACHE_NO_TRANS   (0x000000FE)
#define CP15_MAIR_ATTR_NORM_IN_WB_RA_WA_CACHE_NO_TRANS      (0x000000FF)

#define CP15_MAIR0_ATTR0_SHIFT                              (0x00000000)
#define CP15_MAIR0_ATTR1_SHIFT                              (0x00000008)
#define CP15_MAIR0_ATTR2_SHIFT                              (0x00000010)
#define CP15_MAIR0_ATTR3_SHIFT                              (0x00000018)
#define CP15_MAIR1_ATTR4_SHIFT                              (0x00000000)
#define CP15_MAIR1_ATTR5_SHIFT                              (0x00000008)
#define CP15_MAIR1_ATTR6_SHIFT                              (0x00000010)
#define CP15_MAIR1_ATTR7_SHIFT                              (0x00000018)

/* CP15 DACR Vlaues definition */
#define CP15_DACR_ALL_NO_ACCESS                             (0x00000000)
#define CP15_DACR_ALL_CLIENT                                (0x55555555)
#define CP15_DACR_ALL_MANAGER                               (0xFFFFFFFF)

/* PMU Event Macros */
#define CP15_PMU_EVENT_SW_INCR                 0x00    /* Instruction architecturally executed, condition code check pass, software increment */
#define CP15_PMU_EVENT_L1I_CACHE_REFILL        0x01    /* Level 1 instruction cache refill */
#define CP15_PMU_EVENT_L1I_TLB_REFILL          0x02    /* Level 1 instruction TLB refill */
#define CP15_PMU_EVENT_L1D_CACHE_REFILL        0x03    /* Level 1 data cache refill */
#define CP15_PMU_EVENT_L1D_CACHE               0x04    /* Level 1 data cache access */
#define CP15_PMU_EVENT_L1D_TLB_REFILL          0x05    /* Level 1 data TLB refill */
#define CP15_PMU_EVENT_INST_RETIRED            0x08    /* Instruction architecturally executed */
#define CP15_PMU_EVENT_EXC_TAKEN               0x09    /* Exception taken */
#define CP15_PMU_EVENT_EXC_RETURN              0x0A    /* Instruction architecturally executed, condition code check pass, exception return */
#define CP15_PMU_EVENT_CID_WRITE_RETIRED       0x0B    /* Instruction architecturally executed, condition code check pass, write to CONTEXTIDR */
#define CP15_PMU_EVENT_BR_MIS_PRED             0x10    /* Mispredicted or not predicted branch speculatively executed */
#define CP15_PMU_EVENT_CPU_CYCLES              0x11    /* CPU Cycle */
#define CP15_PMU_EVENT_BR_PRED                 0x12    /* Predictable branch speculatively executed */
#define CP15_PMU_EVENT_MEM_ACCESS              0x13    /* Data memory access */
#define CP15_PMU_EVENT_L1I_CACHE               0x14    /* Level 1 instruction cache access */
#define CP15_PMU_EVENT_L1D_CACHE_WB            0x15    /* Level 1 data cache write-back */
#define CP15_PMU_EVENT_L2D_CACHE               0x16    /* Level 2 data cache access */
#define CP15_PMU_EVENT_L2D_CACHE_REFILL        0x17    /* Level 2 data cache refill */
#define CP15_PMU_EVENT_L2D_CACHE_WB            0x18    /* Level 2 data cache write-back */
#define CP15_PMU_EVENT_BUS_ACCESS              0x19    /* Bus access */
#define CP15_PMU_EVENT_MEMORY_ERROR            0x1A    /* Local memory error */
#define CP15_PMU_EVENT_INST_SPEC               0x1B    /* Instruction speculatively executed */
#define CP15_PMU_EVENT_TTBR_WRITE_RETIRED      0x1C    /* Instruction architecturally executed, condition code check pass, write to TTBR */
#define CP15_PMU_EVENT_BUS_CYCLES              0x1D    /* Bus cycle */
#define CP15_PMU_EVENT_L1D_CACHE_LD            0x40    /* Level 1 data cache access, read */
#define CP15_PMU_EVENT_L1D_CACHE_ST            0x41    /* Level 1 data cache access, write */
#define CP15_PMU_EVENT_L1D_CACHE_REFILL_LD     0x42    /* Level 1 data cache refill, read */
#define CP15_PMU_EVENT_L1D_CACHE_REFILL_ST     0x43    /* Level 1 data cache refill, write */
#define CP15_PMU_EVENT_L1D_CACHE_WB_VICTI      0x46    /* Level 1 data cache write-back, victim */
#define CP15_PMU_EVENT_L1D_CACHE_WB_CLEAN      0x47    /* Level 1 data cache write-back, cleaning and coherency */
#define CP15_PMU_EVENT_L1D_CACHE_INVAL         0x48    /* Level 1 data cache invalidate */
#define CP15_PMU_EVENT_L1D_TLB_REFILL_LD       0x4C    /* Level 1 data TLB refill, read */
#define CP15_PMU_EVENT_L1D_TLB_REFILL_ST       0x4D    /* Level 1 data TLB refill, write */
#define CP15_PMU_EVENT_L2D_CACHE_LD            0x50    /* Level 2 data cache access, read */
#define CP15_PMU_EVENT_L2D_CACHE_ST            0x51    /* Level 2 data cache access, write */
#define CP15_PMU_EVENT_L2D_CACHE_REFILL_LD     0x52    /* Level 2 data cache refill, read */
#define CP15_PMU_EVENT_L2D_CACHE_REFILL_ST     0x53    /* Level 2 data cache refill, write */
#define CP15_PMU_EVENT_L2D_CACHE_WB_VICTI      0x56    /* Level 2 data cache write-back, victim */
#define CP15_PMU_EVENT_L2D_CACHE_WB_CLEAN      0x57    /* Level 2 data cache write-back, cleaning and coherency */
#define CP15_PMU_EVENT_L2D_CACHE_INVAL         0x58    /* Level 2 data cache invalidate */
#define CP15_PMU_EVENT_BUS_ACCESS_LD           0x60    /* Bus access, read */
#define CP15_PMU_EVENT_BUS_ACCESS_ST           0x61    /* Bus access, write */
#define CP15_PMU_EVENT_BUS_ACCESS_SHARED       0x62    /* Bus access, Normal, Cacheable, Shareable */
#define CP15_PMU_EVENT_BUS_ACCESS_NOT_SHARED   0x63    /* Bus access, not Normal, Cacheable, Shareable */
#define CP15_PMU_EVENT_BUS_ACCESS_NORMAL       0x64    /* Bus access, normal */
#define CP15_PMU_EVENT_BUS_ACCESS_PERIPH       0x65    /* Bus access, peripheral */
#define CP15_PMU_EVENT_MEM_ACCESS_LD           0x66    /* Data memory access, read */
#define CP15_PMU_EVENT_MEM_ACCESS_ST           0x67    /* Data memory access, write */
#define CP15_PMU_EVENT_UNALIGNED_LD_SPEC       0x68    /* Unaligned access, read */
#define CP15_PMU_EVENT_UNALIGNED_ST_SPEC       0x69    /* Unaligned access, write */
#define CP15_PMU_EVENT_UNALIGNED_LDST_SPEC     0x6A    /* Unaligned access */
#define CP15_PMU_EVENT_LDREX_SPEC              0x6C    /* Exclusive instruction speculatively executed, LDREX */
#define CP15_PMU_EVENT_STREX_PASS_SPEC         0x6D    /* Exclusive instruction speculatively executed, STREXpass */
#define CP15_PMU_EVENT_STREX_FAIL_SPEC         0x6E    /* Exclusive instruction speculatively executed, STREXfail */
#define CP15_PMU_EVENT_LD_SPEC                 0x70    /* Instruction speculatively executed, load */
#define CP15_PMU_EVENT_ST_SPEC                 0x71    /* Instruction speculatively executed, store */
#define CP15_PMU_EVENT_LDST_SPEC               0x72    /* Instruction speculatively executed, load or store */
#define CP15_PMU_EVENT_DP_SPEC                 0x73    /* Instruction speculatively executed, integer data processing */
#define CP15_PMU_EVENT_ASE_SPEC                0x74    /* Instruction speculatively executed, Advanced SIMD Extension */
#define CP15_PMU_EVENT_VFP_SPEC                0x75    /* Instruction speculatively executed, Floating-point Extension */
#define CP15_PMU_EVENT_PC_WRITE_SPEC           0x76    /* Instruction speculatively executed, software change of the PC */
#define CP15_PMU_EVENT_BR_IMMED_SPEC           0x78    /* Branch speculatively executed, immediate branch */
#define CP15_PMU_EVENT_BR_RETURN_SPEC          0x79    /* Branch speculatively executed, procedure return */
#define CP15_PMU_EVENT_BR_INDIRECT_SPEC        0x7A    /* Branch speculatively executed, indirect branch */
#define CP15_PMU_EVENT_ISB_SPEC                0x7C    /* Barrier speculatively executed, ISB */
#define CP15_PMU_EVENT_DSB_SPEC                0x7D    /* Barrier speculatively executed, DSB */
#define CP15_PMU_EVENT_DMB_SPEC                0x7E    /* Barrier speculatively executed, DMB */

#define CP15_PMU_CCNT_MASK 			(1<<31)
#define CP15_PMU_CNT_MASK(x) 		(1<<x)

/*Memory Error Syndrome Register field definition*/
#define CP15_MEMORY_FATAL_ERROR_SHIFT 	    (31)
#define CP15_MEMORY_RANDOM_ERROR_CNT_SHIFT 	(8)
#define CP15_MEMORY_REPEAT_ERROR_CNT_SHIFT 	(0)
#define CP15_MEMORY_FATAL_ERROR_MASK 	    (1   <<31)
#define CP15_MEMORY_RANDOM_ERROR_CNT_MASK 	(0xFF<<8)
#define CP15_MEMORY_REPEAT_ERROR_CNT_MASK 	(0xFF<<0)

/*Fault Status Register format when using the Long-descriptor translation table format*/
#define CP15_FSR_CM_SHIFT      (13)
#define CP15_FSR_EXT_SHIFT     (12)
#define CP15_FSR_WnR_SHIFT     (11)
#define CP15_FSR_STATUS_SHIFT  (0 )

#define CP15_FSR_CM_MASKT      (   1<<CP15_FSR_CM_SHIFT    )
#define CP15_FSR_EXT_MASKT     (   1<<CP15_FSR_EXT_SHIFT   )
#define CP15_FSR_WnR_MASKT     (   1<<CP15_FSR_WnR_SHIFT   )
#define CP15_FSR_STATUS_MASKT  (0x3F<<CP15_FSR_STATUS_SHIFT)

/*------------Auxiliary Data Fault Status Register--------------*/
#define CP15_ADFSR_VALID_SHIFT     (31)
#define CP15_ADFSR_RAM_ID_SHIFT    (24)
#define CP15_ADFSR_L2_ERROR_SHIFT  (23)
#define CP15_ADFSR_BANK_WAY_SHIFT  (18)
#define CP15_ADFSR_INDEX_SHIFT     ( 0)

#define CP15_ADFSR_VALID_MASK     (      1<<CP15_ADFSR_VALID_SHIFT   )
#define CP15_ADFSR_RAM_ID_MASK    (   0x7F<<CP15_ADFSR_RAM_ID_SHIFT  )
#define CP15_ADFSR_L2_ERROR_MASK  (      1<<CP15_ADFSR_L2_ERROR_SHIFT)
#define CP15_ADFSR_BANK_WAY_MASK  (   0x1F<<CP15_ADFSR_BANK_WAY_SHIFT)
#define CP15_ADFSR_INDEX_MASK     (0x3FFFF<<CP15_ADFSR_INDEX_SHIFT   )

/*****************************************************************************/
/*
** API prototypes
*/
/*-----------------------------------------------------------------------------
Cache operations
-----------------------------------------------------------------------------*/
/*cleans/wirteback the D-cache/Unified  lines corresponding to the buffer 
pointer upto the specified length to PoC.*/
extern void CP15_DCacheCleanBuff(unsigned int bufPtr, unsigned int size);

/*cleans/writeback and invalidates the D-cache/Unified  lines corresponding to 
the buffer pointer upto the specified length to PoC.*/
extern void CP15_DCacheCleanInvalidateBuff(unsigned int bufPtr, unsigned int size);

/*invalidates the D-cache/Unified  lines corresponding to 
the buffer pointer upto the specified length to PoC.*/
extern void CP15_DCacheInvalidateBuff(unsigned int bufPtr, unsigned int size);

/*invlidates I-cache lines from the startaddress till the length   
specified to PoU.*/
extern void CP15_ICacheInvalidateBuff(unsigned int bufPtr, unsigned int size);

/*disable the InSTRuction cache.*/
extern void CP15_ICacheDisable(void);

/*disable the data cache.*/
extern void CP15_DCacheDisable(void);

/*enable the InSTRuction cache.*/
extern void CP15_ICacheEnable(void);

/*enable the data cache*/
extern void CP15_DCacheEnable(void);

/*cleans/writeback and invalidates the entire D Cache to PoC*/
extern void CP15_DCacheCleanInvalidate(void);

/*cleans/writeback the entire D Cache to PoC*/
extern void CP15_DCacheClean(void);

/*Invalidates the entire Data/Unified Cache*/
extern void CP15_DCacheInvalidate(void);

/*invalidates entire I Cache*/
extern void CP15_ICacheInvalidate(void);

/*is data and unified cache enabled*/
extern Bool CP15_IsDCacheEnabled(void);

/*is instruction cache enabled*/
extern Bool CP15_IsICacheEnabled(void);
/*-----------------------------------------------------------------------------
branch predictor operations
-----------------------------------------------------------------------------*/
/*invalidates the branch predictor */
extern void CP15_BranchPredictorInvalidate(void);

/*enable the branch predictor */
extern void CP15_BranchPredictionEnable(void);

/*disable the branch predictor */
extern void CP15_BranchPredictionDisable(void);

/*-----------------------------------------------------------------------------
MMU and Translation table operations
-----------------------------------------------------------------------------*/
/*Sets TTBR0 Register for short descriptor format*/
extern void CP15_Ttb0Set(unsigned int ttb);

/*Sets TTBR0 Register for long descriptor format*/
extern void CP15_64bitTtb0Set(unsigned long long ttb);

/*Invalidates All the TLB*/
extern void CP15_TLBInvalidateAll(void);

/*Disables MMU*/
extern void CP15_MMUDisable(void);

/*enable MMU*/
extern void CP15_MMUEnable(void);

/*sets the Domain Access Control Register (DACR) for short descriptor format*/
extern void CP15_DACRConfig(unsigned int value);

/*Configures the Translation Table Base Control Reg (TTBCR) for Short Descriptor*/
extern void CP15_TTBCRShortConfig(unsigned int value);

/*Configures the Translation Table Base Control Reg (TTBCR) for long Descriptor*/
extern void CP15_TTBCRLongConfig(unsigned int value);

/*sets the MAIR0 registers for long descriptor format
These are the settings to be programmed into MAIR0
31:24 - Attr3
23:16 - Attr2
15:8  - Attr1
7:0   - Attr0*/
extern void CP15_MAIR0Config(unsigned int value);

/*Set up MAIR1 for long descriptor format
These are the settings to be programmed into MAIR1
31:24 - Attr7
23:16 - Attr6
15:8  - Attr5
7:0   - Attr4*/
extern void CP15_MAIR1Config(unsigned int value);

/* ----------------------------------------------------------------------------
 Performance Monitor Block
 ----------------------------------------------------------------------------*/
// Returns the number of progammable counters
unsigned int CP15_get_PMU_N(void);

// Sets the event for a programmable counter to record
// counter = Which counter to program (e.g. 0 for PMN0, 1 for PMN1)
// event   = The event code (from appropriate TRM or ARM Architecture Reference Manual)
void CP15_PMN_config(unsigned int counter, unsigned int event);

// Enables/disables the divider (1/64) on CCNT
// divider = If FALSE disable divider, else enable divider
void CP15_CCNT_divider(Bool bDivider);

// Global PMU enable
// On ARM11 this enables the PMU, and the counters start immediately
// On Cortex this enables the PMU, there are individual enables for the counters
void CP15_enable_PMU(void);

// Global PMU disable
// On Cortex, this overrides the enable state of the individual counters
void CP15_disable_PMU(void);

// Enable the CCNT
void CP15_enable_CCNT(void);

// Disable the CCNT
void CP15_disable_CCNT(void);

// Enable PMN{n}
// counter = The counter to enable (e.g. 0 for PMN0, 1 for PMN1)
void CP15_enable_PMN(unsigned int counter);

// Enable PMN{n}
// counter = The counter to enable (e.g. 0 for PMN0, 1 for PMN1)
void CP15_disable_PMN(unsigned int counter);

// Returns the value of CCNT
unsigned int CP15_read_CCNT(void);

// Returns the value of PMN{n}
// counter = The counter to read (e.g. 0 for PMN0, 1 for PMN1)
unsigned int CP15_read_PMN(unsigned int counter);

// Returns the value of the overflow flags
unsigned int CP15_PMU_read_flags(void);

// Writes the overflow flags
void CP15_PMU_clear_flags(unsigned int flags);

// Enables interrupt generation on overflow of the CCNT
void CP15_enable_CCNT_irq(void);

// Disables interrupt generation on overflow of the CCNT
void CP15_disable_CCNT_irq(void);

// Enables interrupt generation on overflow of PMN{x}
// counter = The counter to enable the interrupt for (e.g. 0 for PMN0, 1 for PMN1)
void CP15_enable_PMN_irq(unsigned int counter);

// Disables interrupt generation on overflow of PMN{x}
// counter =  The counter to disable the interrupt for (e.g. 0 for PMN0, 1 for PMN1)
void CP15_disable_PMN_irq(unsigned int counter);

// Resets the programmable counters
void CP15_reset_PMN(void);

// Resets the CCNT
void CP15_reset_CCNT(void);

// Writes to software increment register
// counter = The counter to increment (e.g. 0 for PMN0, 1 for PMN1)
void CP15_PMU_software_increment(unsigned int counter);

// Enables User mode access to the PMU (must be called in a privileged mode)
void CP15_enable_PMU_user_access(void);

// Disables User mode access to the PMU (must be called in a privileged mode)
void CP15_disable_PMU_user_access(void);

/*-----------------------------------------------------------------------------
Other utility functions
-----------------------------------------------------------------------------*/
/*sets the interrupt vector table base address */
extern void CP15_VectorBaseAddrSet(unsigned int addr);

/*Configs 32-bit System Control Register*/
extern void CP15_SCTLRConfig(unsigned int value);

/*Configs specified features in System Control Register
feature - Feature for the bits to be set in System Control Register
mask - Bit Mask for the bits to be clear in System Control Register*/
extern void CP15_SCTLRConfigBitField(unsigned int feature, unsigned int mask);

/*Configs the specified fields in Auxiliary Control Register
feature - Feature for the bits to be set in Auxiliary Control Register
mask - Bit Mask for the bits to be clear in Auxiliary Control Register*/
extern void CP15_ACTLRConfigBitField(unsigned int feature, unsigned int mask);

/*get the primary part number in main ID register*/
extern unsigned int CP15_MainIdPrimPartNumGet(void);

/*get the CPU ID in Multiprocessor Affinity Register (MPIDR)*/
extern unsigned int CP15_get_CPU_ID(void);

/*clear L2 internal asynchronous error in  L2ECTLR register*/
extern void CP15_clear_L2_async_error(void);

/*clear AXI asynchronous error in  L2ECTLR register*/
extern void CP15_clear_AXI_bus_error(void);

/*get CPU memory (L1 cache and TLB) error count 
(higher 32-bit of CPU Memory Error Syndrome Register)*/
extern unsigned int CP15_get_CPU_memory_error_count(void);

/*get L2 memory error count (higher 32-bit of L2 Memory Error Syndrome Register)*/
extern unsigned int CP15_get_L2_memory_error_count(void);
/*get the Interrupt Status Register*/
extern unsigned int CP15_get_interrupt_status(void);
extern unsigned int CP14_get_DBGDSCR(void);
extern void CP14_set_DBGDSCR(unsigned int uiValue);

#ifdef __cplusplus
}
#endif
#endif /* __CP15_H__ */
