Files
m241Neelima/vxworks-6.9/target/h/arch/arm/mmuArmLpaeLib.h
T
2026-07-30 11:19:44 +05:30

480 lines
16 KiB
C

/* mmuArmLpaeLib.h - ARM LPAE MMU library header file */
/*
* Copyright (c) 2013-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)
01a,01jun13,zgl written
*/
#ifndef __INCmmuArmLpaeLibh
#define __INCmmuArmLpaeLibh
#ifndef _ASMLANGUAGE
/* includes */
#include <memLib.h>
#include <semLib.h>
#ifdef __cplusplus
extern "C" {
#endif
#endif /* _ASMLANGUAGE */
/* defines */
/* make mask, h = end bit, l = start bit */
#define MAKE_MASK_64(h,l) (((1ULL << (h + 1)) - 1) & ~((1ULL << l) - 1))
#define MAKE_MASK_32(h,l) (((1UL << (h + 1)) - 1) & ~((1UL << l) - 1))
/*
* The page size we will use. Ignore the sub-page, Large Page and Tiny
* Page features.
*/
#define MMU_PAGE_SIZE 4096
#define PAGE_SIZE MMU_PAGE_SIZE
#define MMU_ADRS_TO_L1D_INDEX_SHIFT 30
#define MMU_ADRS_TO_L2D_INDEX_SHIFT 21
#define MMU_PAGE_SIZE_SHIFT 12
#define MMU_LPAE_NO_BITS_PHYS_ADDR 40
/* get Level 2 index */
#define MMU_L2PD_INDEX_GET(vaddr) \
((vaddr >> MMU_ADRS_TO_L2D_INDEX_SHIFT) & (MMU_NUM_L2_DESCS - 1))
#define MMU_PTE_INDEX_MASK MAKE_MASK_32(20,12) /* extract PTE index from */
/* Virt Addr */
#define MMU_PTE_BA_MASK MAKE_MASK_64(39,12) /* extract phys base address */
#define MMU_PTE_INDEX_SHIFT 12 /* shift to make that into PTE index */
#define MMU_ADDR_PI_MASK 0x00000FFF /* extract page offset from Virt Addr */
/* extract phys L2 page table base addr from L1PD */
#define MMU_L1PD_L2TBL_MASK MAKE_MASK_64(39,12)
/* extract phys L3 page table base addr from L2PD */
#define MMU_L2PD_L3TBL_MASK MMU_L1PD_L2TBL_MASK
/* Level 1/2 Descriptor types */
#define MMU_DESC_TYPE_FAULT 0x0 /* any access will cause a fault */
#define MMU_DESC_TYPE_BLOCK 0x1 /* block descriptor */
#define MMU_DESC_TYPE_TABLE 0x3 /* page table descriptor */
/* defalt Descriptor types for Level 1/2 */
#define MMU_DEF_L1_PAGE MMU_DESC_TYPE_TABLE
#define MMU_DEF_L2_PAGE MMU_DEF_L1_PAGE
/* Level 3 Descriptor or Page Table Entry (PTE) types */
#define MMU_PTE_TYPE_FAULT 0x0 /* any access will cause a fault */
#define MMU_PTE_TYPE_PAGE 0x3 /* page descriptor */
#define MMU_PTE_AF (1 << 10) /* access flag bit */
/* No. of Descriptor for each page table level */
#define MMU_NUM_L1_DESCS 4
#define MMU_NUM_L2_DESCS 512
#define MMU_NUM_L3_DESCS 512
#define MMU_L1_TABLE_SIZE MMU_PAGE_SIZE
/* No. of pages a Level 1 Descriptor table takes up */
#define MMU_L1_DESC_PAGES (MMU_L1_TABLE_SIZE / MMU_PAGE_SIZE)
/* The amount described by a L1 Descriptor */
#define MMU_L1_DESC_RANGE (MMU_NUM_L2_DESCS * MMU_NUM_L3_DESCS * MMU_PAGE_SIZE)
/* Size of a Page Table */
#define MMU_PAGE_TABLE_SIZE MMU_PAGE_SIZE
/*
* The amount described by a L2 Descriptor, which equals the smallest
* amount of VM allocatable in VxWorks.
*/
#define MMU_L2_DESC_RANGE (MMU_NUM_L3_DESCS * MMU_PAGE_SIZE) /* 2 MBytes */
#define MMU_PAGE_BLOCK_SIZE MMU_L2_DESC_RANGE
/* Number of possible ASIDs */
#define MMU_NUM_ASIDS 256
#define VXWORKS_KERNEL_ASID 0 /* reserved ASID for VxWorks kernel */
/*
* Architecture-dependent MMU states. These are states settable for pages and
* here they correspond to settings in the Page Table Entries (PTEs).
*/
#define MMU_STATE_INVALID_STATE 0xFFFFFFFF
#define MMU_STATE_MASK_VALID 0x00000003 /* bits[1:0] for PTE state */
#define MMU_STATE_MASK_WRITABLE 0x000000C0 /* AP[2:1], bits[7:6] */
#define MMU_STATE_MASK_CACHEABLE 0x0000031C /* SH[1:0], AttrIndex[2:0], */
/* bits[9:8] and bits[4:2] */
#define MMU_STATE_VALID 0x3 /* 0b11 means valid */
#define MMU_STATE_VALID_NOT 0x0 /* 0b00 means NOT valid */
#define MMU_STATE_MASK_PROTECTION 0x000000C0 /* AP[2:1], bits[7:6] */
#define MMU_STATE_SUP_RO 0x00000080 /* AP: 10 */
#define MMU_STATE_SUP_RW 0x00000000 /* AP: 00 */
#define MMU_STATE_SUP_RO_USR_RO 0x000000C0 /* AP: 11 */
#define MMU_STATE_SUP_RW_USR_RO 0x00000040 /* AP: 01, not support, */
/* here we set same as RW */
#define MMU_STATE_SUP_RW_USR_RW 0x00000040 /* AP: 01 */
/* XN not support */
#define MMU_STATE_SUP_RO_XN MMU_STATE_SUP_RO
#define MMU_STATE_SUP_RW_XN MMU_STATE_SUP_RW
#define MMU_STATE_SUP_RO_USR_RO_XN MMU_STATE_SUP_RO_USR_RO
#define MMU_STATE_SUP_RW_USR_RO_XN MMU_STATE_SUP_RW_USR_RO
#define MMU_STATE_SUP_RW_USR_RW_XN MMU_STATE_SUP_RW_USR_RW
#define MMU_STATE_WRITABLE MMU_STATE_SUP_RW
#define MMU_STATE_WRITABLE_NOT MMU_STATE_SUP_RO
#define MMU_STATE_AP_SUP_RO 0x2 /* AP field: 10 */
#define MMU_STATE_AP_SUP_RW 0x0 /* AP field: 00 */
#define MMU_STATE_AP_SUP_RO_USR_RO 0x3 /* AP field: 11 */
#define MMU_STATE_AP_SUP_RW_USR_RO 0x1 /* AP field: 01, arm not support */
#define MMU_STATE_AP_SUP_RW_USR_RW 0x1 /* AP field: 01 */
#define MMU_STATE_AP_USR_RO_SUP_RO MMU_STATE_AP_SUP_RO_USR_RO
#define MMU_STATE_AP_USR_RO_SUP_RW MMU_STATE_AP_SUP_RW_USR_RO
#define MMU_STATE_AP_USR_RW_SUP_RW MMU_STATE_AP_SUP_RW_USR_RW
/*
* Memory Region Attributes -
* cache access, write buffer access, coherency control
*/
/*
* Memory Region Attributes - for LPAE
*
* n = AttrIndex[2:0]
*
* n MAIR
* 000 00000000 Strongly-ordered
* 001 01000100 Normal memory, Inner & Outer Non-cacheable
* 010 10101010 Normal memory, Write-Through, Read-Allocate
* 011 11101110 Normal memory, Write-Back, Read-Allocate
* 100 00000100 Device memory
*/
#define MMU_MAIR0_VALUE 0xEEAA4400
#define MMU_MAIR1_VALUE 0x00000004
#define MMU_STATE_AI_STRONGLY_ORDERED 0x0 /* n = 0b000, strongly ordered */
#define MMU_STATE_STRONGLY_ORDERED ((MMU_STATE_AI_STRONGLY_ORDERED << 2) | \
MMU_STATE_SHARED_OUTER)
#define MMU_STATE_CACHEABLE_NOT MMU_STATE_STRONGLY_ORDERED
#define MMU_STATE_AI_DEVICE 0x4 /* n = 0b100 */
#define MMU_STATE_DEVICE_SHARED ((MMU_STATE_AI_DEVICE << 2) | \
MMU_STATE_SHARED_OUTER)
/* device always shared in LPAE */
#define MMU_STATE_DEVICE_NONSHARED MMU_STATE_DEVICE_SHARED
/* outer & inner write-thru cachable, write alloc */
#define MMU_STATE_AI_NORMAL_WRITETHROUGH 0x2 /* n = 0b010, Write-Through */
#define MMU_STATE_NORMAL_WRITETHROUGH (MMU_STATE_AI_NORMAL_WRITETHROUGH << 2)
#define MMU_STATE_CACHEABLE_WRITETHROUGH MMU_STATE_NORMAL_WRITETHROUGH
/* outer & inner write-back cachable, write alloc */
#define MMU_STATE_AI_NORMAL_WRITEBACK 0x3 /* n = 0b011, Write-Back */
#define MMU_STATE_NORMAL_WRITEBACK (MMU_STATE_AI_NORMAL_WRITEBACK << 2)
#define MMU_STATE_CACHEABLE_COPYBACK MMU_STATE_NORMAL_WRITEBACK
#define MMU_STATE_COPYBACK_ALLOC MMU_STATE_NORMAL_WRITEBACK
/* outer & inner Non-cachable */
#define MMU_STATE_AI_NORMAL_NONCACHEABLE 0x1 /* n = 0b001, Non-cacheable */
#define MMU_STATE_NORMAL_NONCACHEABLE (MMU_STATE_AI_NORMAL_NONCACHEABLE << 2)
/*
* Set the default state to be copyback.
*/
#define MMU_STATE_CACHEABLE MMU_STATE_CACHEABLE_COPYBACK
/*
* Shared memory attribute -
* accessible by multiple processors or bus masters and must be kept coherent
*/
#define MMU_STATE_SHARED_OUTER (0x2 << 8) /* Outer Shareable */
#define MMU_STATE_SHARED_INNER (0x3 << 8) /* Inner Shareable */
#define MMU_STATE_SHARED MMU_STATE_SHARED_INNER
#define MMU_STATE_WRITETHROUGH_SHARED \
(MMU_STATE_CACHEABLE_WRITETHROUGH | MMU_STATE_SHARED)
#define MMU_STATE_COPYBACK_SHARED \
(MMU_STATE_CACHEABLE_COPYBACK | MMU_STATE_SHARED)
/*
* A memory region with a resultant memory type attribute of Normal, and a
* resultant cacheability attribute of Inner Non-cacheable, Outer Non-cacheable,
* must have a resultant shareability attribute of Outer Shareable, otherwise
* shareability is UNPREDICTABLE.
*/
#define MMU_STATE_NONCACHEABLE_SHARED \
(MMU_STATE_NORMAL_NONCACHEABLE | \
MMU_STATE_SHARED_OUTER)
/*
* Global memory attribute -
* not-Global causes ASID to be associated with address translation
*/
#define MMU_STATE_NOT_GLOBAL 0x00000800 /* not-Global, bit[11] */
/*
* Architecture-specific attributes
*
* The following ARMv7-specific aliases are provided for ease of use.
*
* NOTE: MMU_ATTR_CACHE_GUARDED is used as MMU_ATTR_CACHE_IO (its former name).
*/
/* Strongly Ordered - same as MMU_ATTR_CACHE_OFF for backward compatibility */
#define MMU_ATTR_STRONGLY_ORDERED (MMU_ATTR_CACHE_OFF)
/* Shared Device */
#define MMU_ATTR_DEVICE_SHARED_MSK (MMU_ATTR_CACHE_MSK)
#define MMU_ATTR_DEVICE_SHARED (MMU_ATTR_CACHE_GUARDED | MMU_ATTR_CACHE_OFF | \
MMU_ATTR_CACHE_COHERENCY)
#define MMU_ATTR_BUFFERABLE MMU_ATTR_DEVICE_SHARED /* backward compatible */
/* Normal, Noncacheable memory */
#define MMU_ATTR_NORMAL_NONCACHEABLE_MSK (MMU_ATTR_CACHE_MSK)
#define MMU_ATTR_NORMAL_NONCACHEABLE (MMU_ATTR_CACHE_OFF)
#define MMU_ATTR_NORMAL_NONCACHEABLE_SHARED (MMU_ATTR_NORMAL_NONCACHEABLE | \
MMU_ATTR_CACHE_COHERENCY)
/* Normal, Inner Cache Write-Back, Write Allocate */
#define MMU_ATTR_WRITEALLOCATE_MSK MMU_ATTR_CACHE_MSK
#define MMU_ATTR_WRITEALLOCATE MMU_ATTR_CACHE_COPYBACK
#define MMU_ATTR_WRITEALLOCATE_SHARED (MMU_ATTR_WRITEALLOCATE | \
MMU_ATTR_CACHE_COHERENCY)
/* MMU Control Register bit allocations */
#define MMUCR_M_ENABLE (1<<0) /* MMU enable */
#define MMUCR_A_ENABLE (1<<1) /* Address alignment fault enable */
#define MMUCR_C_ENABLE (1<<2) /* (data) cache enable */
#define MMUCR_W_ENABLE (1<<3) /* write buffer enable */
#define MMUCR_PROG32 (1<<4) /* PROG32 */
#define MMUCR_DATA32 (1<<5) /* DATA32 */
#define MMUCR_L_ENABLE (1<<6) /* Late abort on earlier CPUs */
#define MMUCR_BIGEND (1<<7) /* Big-endian (=1), little-endian (=0) */
#define MMUCR_SYSTEM (1<<8) /* System bit, modifies MMU protections */
#define MMUCR_ROM (1<<9) /* ROM bit, modifies MMU protections */
#define MMUCR_F (1<<10) /* Should Be Zero */
#define MMUCR_Z_ENABLE (1<<11) /* Branch prediction enable on 810 */
#define MMUCR_I_ENABLE (1<<12) /* Instruction cache enable */
#define MMUCR_V_ENABLE (1<<13) /* Exception vectors remap to 0xFFFF0000 */
#define MMUCR_ALTVECT MMUCR_V_ENABLE /* alternate vector select */
#define MMUCR_RR_ENABLE (1<<14) /* Round robin cache replacement enable */
#define MMUCR_ROUND_ROBIN MMUCR_RR_ENABLE /* round-robin placement */
#define MMUCR_DISABLE_TBIT (1<<15) /* disable TBIT */
#define MMUCR_ENABLE_DTCM (1<<16) /* Enable Data TCM */
#define MMUCR_HA_ENABLE (1<<17) /* Hardware Access flag enable */
#define MMUCR_ENABLE_ITCM (1<<18) /* Enable Instruction TCM */
#define MMUCR_UNALIGNED_ENABLE (1<<22) /* Enable unaligned access */
#define MMUCR_EXTENDED_PAGE (1<<23) /* Use extended PTE format */
#define MMUCR_VECTORED_INTERRUPT (1<<24) /* Enable VIC Interface */
#define MMUCR_EE (1<<25) /* Exception Endianness bit */
#define MMUCR_THUMB_EXCEPTIONS (1<<30) /* Exceptions are Thumb */
/* MMU TTBR 64 bit register fields for LPAE */
#define MMU_TTBR64_BA_MASK MAKE_MASK_64(39, 12)
#define MMU_TTBR64_ASID_SHIFT 48
/* MMU TTBCR register fields for LPAE */
#define MMU_TTBCR_IRGN_NC (0 << 8)
#define MMU_TTBCR_IRGN_WBWA (1 << 8)
#define MMU_TTBCR_IRGN_WT (2 << 8)
#define MMU_TTBCR_IRGN_WB (3 << 8)
#define MMU_TTBCR_ORGN_NC (0 << 10)
#define MMU_TTBCR_ORGN_OC_WBWA (1 << 10)
#define MMU_TTBCR_ORGN_OC_WT (2 << 10)
#define MMU_TTBCR_ORGN_OC_WB (3 << 10)
#define MMU_TTBCR_S (3 << 12)
#define MMU_TTBCR_S_OUTER (2 << 12)
#define MMU_TTBCR_EAE (1 << 31)
#ifdef _WRS_CONFIG_ENABLE_CACHED_PAGE_TBL
/* PTWs cacheable, inner WBWA not shareable, outer WBWA not shareable */
#define MMU_TTBCR_FLAGS_UP (MMU_TTBCR_IRGN_WBWA | MMU_TTBCR_ORGN_OC_WBWA)
/* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */
#define MMU_TTBCR_FLAGS_SMP (MMU_TTBCR_IRGN_WBWA | MMU_TTBCR_S | \
MMU_TTBCR_ORGN_OC_WBWA)
#else /* !_WRS_CONFIG_ENABLE_CACHED_PAGE_TBL */
/* PTWs not cacheable, inner not shareable, outer not shareable */
#define MMU_TTBCR_FLAGS_UP (MMU_TTBCR_IRGN_NC | MMU_TTBCR_ORGN_NC)
/* PTWs not cacheable, inner shareable, outer not shareable */
#define MMU_TTBCR_FLAGS_SMP (MMU_TTBCR_ORGN_NC | MMU_TTBCR_S | \
MMU_TTBCR_ORGN_NC)
#endif /* _WRS_CONFIG_ENABLE_CACHED_PAGE_TBL */
/* typedefs */
#ifndef _ASMLANGUAGE
#if (_BYTE_ORDER == _LITTLE_ENDIAN)
/* little-endian */
/* Level 1/2 page descriptors */
typedef struct
{
UINT type : 2; /* descriptor type, 0b11 => page table */
UINT pad1 : 10; /* Ignored */
UINT addr : 20; /* base address of page table */
UINT addr40 : 8; /* base address of page table */
UINT pad2 : 12; /* UNK/SBZP */
UINT pad3 : 7; /* Ignored */
UINT pxn : 1; /* PXNTable */
UINT xn : 1; /* XNTable */
UINT ap : 2; /* APTable */
UINT ns : 1; /* NSTable */
} PAGE_DESC_FIELD;
/* Layout of Page Table Entries (PTEs) */
typedef struct
{
UINT type : 2; /* page type, 0b11 => page */
UINT ai : 3; /* AttrIndx[2:0] */
UINT ns : 1; /* non-secure bit */
UINT ap : 2; /* AP[2:1], access permission */
UINT sh : 2; /* SH[1:0], shareability field */
UINT af : 1; /* access flag */
UINT ng : 1; /* not global bit */
UINT addr : 20; /* phys address */
UINT addr40 : 8; /* phys address */
UINT pad1 : 12; /* UNK/SBZP */
UINT ch : 1; /* contiguous hint */
UINT pxn : 1; /* privileged execute-never bit */
UINT xn : 1; /* execute-never bit */
UINT pad2 : 9; /* ignored */
} PTE_FIELD;
#else /* (_BYTE_ORDER == _LITTLE_ENDIAN) */
/* big-endian */
#error "LPAE for big-endian not support yet."
#endif /* (_BYTE_ORDER == _LITTLE_ENDIAN) */
/* First/second level descriptor access */
typedef union
{
PAGE_DESC_FIELD fields;
UINT bits[2];
UINT64 bits64;
} MMU_LEVEL_1_DESC, MMU_LEVEL_2_DESC;
/* Third level descriptor access */
typedef union
{
PTE_FIELD fields;
UINT bits[2];
UINT64 bits64;
} PTE;
/*
* Structure for MMU translation table access - normally used to get a pointer
* to the first-level translation table.
*/
typedef struct mmuTransTblStruct
{
MMU_LEVEL_1_DESC *pLevel1Table; /* active MMU table */
VX_MUTEX_SEMAPHORE(mmuTransTblSem); /* MMU tables' semaphore */
UINT32 lockCnt; /* lock count */
atomic_t lockOwner; /* lock owner */
UINT8 asid; /* ASID/context id */
} MMU_TRANS_TBL;
/* function declarations */
/* Externally visible mmuLib, mmuMapLib and mmuALib2 routines */
IMPORT UINT32 mmuReadId (void);
IMPORT PHYS_ADDR mmuVirtToPhys (VIRT_ADDR addr);
IMPORT VIRT_ADDR mmuPhysToVirt (PHYS_ADDR addr);
IMPORT UINT32 (* mmuCrGet) (void);
IMPORT void (* mmuModifyCr) (UINT32 value, UINT32 mask);
IMPORT UINT32 mmuHardCrGet (void);
IMPORT void mmuModifyHardCr (UINT32 value, UINT32 mask);
IMPORT UINT32 (* _func_mmuFaultAddrGet) (void);
IMPORT UINT32 (* _func_mmuFaultStatusGet) (void);
IMPORT UINT32 (* _func_mmuIFaultStatusGet) (void);
IMPORT UINT32 mmuIFsrGet (void);
IMPORT UINT32 mmuFarGet (void);
IMPORT UINT32 mmuFsrGet (void);
#endif /* _ASMLANGUAGE */
#ifdef __cplusplus
}
#endif
#endif /* __INCmmuArmLpaeLibh */