/*************************************************************************
*
*             Copyright Mentor Graphics Corporation 2013
*                         All Rights Reserved.
*
* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS
* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS
* SUBJECT TO LICENSE TERMS.
*
*************************************************************************

*************************************************************************
*
* FILE NAME
*
*       arm_proc_tlb.h
*
* DESCRIPTION
*
*       This file contains target specific MMU constants and macros.
*
* DATA STRUCTURES
*
*       PROC_AR_L1_DESC
*       PROC_AR_L2_DESC
*
* DEPENDENCIES
*
*      None
*
*************************************************************************/
#ifndef _ARM_PROC_TLB_H
#define _ARM_PROC_TLB_H

/* MMU typedefs and symbols for Level 1 page tables */
typedef UNSIGNED PROC_AR_L1_DESC;

/* Specify alignment for Level 1 Descriptors. */
#define PROC_AR_L1_ALLOC_ALIGN              0x00004000UL

/* In this example, this will map out 8MB of memory, 4096 maps out all 4GB of memory. */
#define PROC_AR_L1_DESCS                    4096
#define PROC_AR_L1_INDEX_MASK               0xFFF00000UL
#define PROC_AR_TTBR_MASK                   0xFFFFC000UL
#define PROC_AR_L1_INDEX_SHIFT              18
#define PROC_AR_L1_SHIFT                    20

#define PROC_AR_L1_TABLE_SIZE               (sizeof(PROC_AR_L1_DESC) * (PROC_AR_L1_DESCS))
#define PROC_AR_L1_MEM_SIZE                 0x00100000UL

#if (CFG_NU_OS_ARCH_ARM_COM_MMU_VARIANT == 1)

/* Level 1 attributes for v6/v7 MMU variant */
#define PROC_AR_L1_AP_NO_ACCESS             0x00000000UL
#define PROC_AR_L1_AP_PRIVILEGED_RW         0x00000400UL
#define PROC_AR_L1_AP_PRIVILEGED_RO         0x00008400UL
#define PROC_AR_L1_AP_MASK                  0x00008C00UL

/* Execute-Never bit.  This is only relevant for sections, this
   field should always be zero for page entries */
#define PROC_AR_L1_XN_BIT                   0x00000010UL

/* not-Global bit.  This is only relevant for sections, this
   field should always be zero for page entries */
#define PROC_AR_L1_NG_BIT                   0x00020000UL

/* Sharable bit.  This is only relevant for sections, this
   field should always be zero for page entries */
#define PROC_AR_L1_S_BIT                    0x00010000UL

#define PROC_AR_L1_PAGE_SBZ_BITS            0x00000014UL
#define PROC_AR_L1_PAGE_NS_BIT              0x00000008UL
#define PROC_AR_L1_SECTION_NS_BIT           0x00080000UL

#else

/* Level 1 attributes for v4/v5 MMU variant */
#define PROC_AR_L1_AP_NO_ACCESS             0x00000400UL
#define PROC_AR_L1_AP_MASK                  0x00000C00UL

/* TTBit always must be 1 */
#define PROC_AR_L1_TT_BIT                   0x00000010UL

#endif

#define PROC_AR_L1_AP_READ_ONLY             0x00000800UL
#define PROC_AR_L1_AP_READ_WRITE            0x00000C00UL

#define PROC_AR_L1_CACHEABLE                0x00000008UL
#define PROC_AR_L1_BUFFERABLE               0x00000004UL
#define PROC_AR_L1_NO_CACHE                 0x00000000UL
#define PROC_AR_L1_CACHE_MASK               (PROC_AR_L1_CACHEABLE | PROC_AR_L1_BUFFERABLE)

/* First level descriptors */
#define PROC_AR_L1_FAULT                    0x00000000UL
#define PROC_AR_L1_PAGE_TABLE               0x00000001UL
#define PROC_AR_L1_SECTION                  0x00000002UL

/* The following defines for L2 descriptors are specific to processors which have
   level 2 descriptors. */
/* MMU typedefs and symbols for Level 2 page tables */
typedef UNSIGNED PROC_AR_L2_DESC;

/* Specify alignment for Level 2 Descriptors. */
#define PROC_AR_L2_ALLOC_ALIGN              0x00000400UL

#define PROC_AR_L2_DESCS                    256
#define PROC_AR_L2_INDEX_MASK               0x000FF000UL
#define PROC_AR_L2_BASE_MASK                0xFFFFFC00UL
#define PROC_AR_L2_ADDRESS_MASK             0xFFFFF000UL
#define PROC_AR_L2_INDEX_SHIFT              10
#define PROC_AR_L2_SHIFT                    12

/* Define size of Level 2 table */
#define PROC_AR_L2_TABLE_SIZE               (sizeof(PROC_AR_L2_DESC) * (PROC_AR_L2_DESCS))

/* Level 2 Access permissions */

#if (CFG_NU_OS_ARCH_ARM_COM_MMU_VARIANT == 1)

/* Level 2 attributes for v6/v7 MMU variant */
#define PROC_AR_L2_AP_NO_ACCESS             0x00000000UL
#define PROC_AR_L2_AP_PRIVILEGED_RW         0x00000010UL
#define PROC_AR_L2_AP_PRIVILEGED_RO         0x00000210UL
#define PROC_AR_L2_AP_READ_ONLY             0x00000020UL
#define PROC_AR_L2_AP_READ_WRITE            0x00000030UL
#define PROC_AR_L2_AP_MASK                  0x00000230UL

#define PROC_AR_L2_LARGE_PAGE_XN            0x00008000UL
#define PROC_AR_L2_SMALL_PAGE_XN            0x00000001UL

#define PROC_AR_L2_LARGE_PAGE_SBZ           0x000001C0UL

#define PROC_AR_L2_NG_BIT                   0x00000800UL
#define PROC_AR_L2_S_BIT                    0x00000400UL

#else

/* Level 2 attributes for v4/v5 MMU variant */
#define PROC_AR_L2_AP3_NO_ACCESS            0x00000400UL
#define PROC_AR_L2_AP3_READ_ONLY            0x00000800UL
#define PROC_AR_L2_AP3_READ_WRITE           0x00000C00UL
#define PROC_AR_L2_AP3_MASK                 0x00000C00UL

#define PROC_AR_L2_AP2_NO_ACCESS            0x00000100UL
#define PROC_AR_L2_AP2_READ_ONLY            0x00000200UL
#define PROC_AR_L2_AP2_READ_WRITE           0x00000300UL
#define PROC_AR_L2_AP2_MASK                 0x00000300UL

#define PROC_AR_L2_AP1_NO_ACCESS            0x00000040UL
#define PROC_AR_L2_AP1_READ_ONLY            0x00000080UL
#define PROC_AR_L2_AP1_READ_WRITE           0x000000C0UL
#define PROC_AR_L2_AP1_MASK                 0x000000C0UL

#define PROC_AR_L2_AP0_NO_ACCESS            0x00000010UL
#define PROC_AR_L2_AP0_READ_ONLY            0x00000020UL
#define PROC_AR_L2_AP0_READ_WRITE           0x00000030UL
#define PROC_AR_L2_AP0_MASK                 0x00000030UL

#define PROC_AR_L2_AP_NO_ACCESS             (PROC_AR_L2_AP3_NO_ACCESS | \
                                             PROC_AR_L2_AP2_NO_ACCESS | \
                                             PROC_AR_L2_AP1_NO_ACCESS | \
                                             PROC_AR_L2_AP0_NO_ACCESS)

#define PROC_AR_L2_AP_READ_ONLY             (PROC_AR_L2_AP3_READ_ONLY | \
                                             PROC_AR_L2_AP2_READ_ONLY | \
                                             PROC_AR_L2_AP1_READ_ONLY | \
                                             PROC_AR_L2_AP0_READ_ONLY)

#define PROC_AR_L2_AP_READ_WRITE            (PROC_AR_L2_AP3_READ_WRITE | \
                                             PROC_AR_L2_AP2_READ_WRITE | \
                                             PROC_AR_L2_AP1_READ_WRITE | \
                                             PROC_AR_L2_AP0_READ_WRITE)

#endif

#define PROC_AR_L2_CACHEABLE                0x00000008UL
#define PROC_AR_L2_BUFFERABLE               0x00000004UL

/* Second Level descriptors */
#define PROC_AR_L2_FAULT                    0x00000000UL
#define PROC_AR_L2_LARGE_PAGE               0x00000001UL
#define PROC_AR_L2_SMALL_PAGE               0x00000002UL

/* Page sizes Large is 64k and small is 4k */
#define PROC_AR_L2_LARGE_PAGE_SIZE          0x00010000UL
#define PROC_AR_L2_SMALL_PAGE_SIZE          0x00001000UL
#define PROC_AR_L2_PAGE_SIZE                PROC_AR_L2_SMALL_PAGE_SIZE

/* Domain 15 is the only domain we are using at this time */
#define PROC_AR_DOMAIN                      0x000001E0UL

/* The maximum number of L2 tables available in the system */
#define PROC_AR_L2_TOTAL                    (CFG_NU_OS_ARCH_ARM_PROCESS_MEM_MGMT_AVG_L2_COUNT * CFG_NU_OS_KERN_PROCESS_CORE_MAX_PROCESSES)

#if (CFG_NU_OS_ARCH_ARM_COM_MMU_VARIANT == 1)
#define PROC_AR_DEFAULT_L1_ATTR             (PROC_AR_L1_AP_PRIVILEGED_RW | PROC_AR_L1_XN_BIT)
#else
#define PROC_AR_DEFAULT_L1_ATTR             (PROC_AR_L1_AP_NO_ACCESS | PROC_AR_L1_TT_BIT)
#endif

#endif /* _ARM_PROC_TLB_H */
