Files
2026-07-30 11:19:44 +05:30

467 lines
16 KiB
C

/* mmu405Lib.h - mmu library for PowerPc 405 series */
/* Copyright 1984-2003 Wind River Systems, Inc. */
/*
modification history
--------------------
01g,19may04,dtr Add additional support for AIM.
01f,09dec03,jtp Code inspection modifications
01e,01dec03,jtp Identify range of valid ASIDs
01d,14nov03,jtp Support variable minimum page size in miss handler & page
tables
01c,12nov03,jtp Parameterize REGION and PAGE table size and offset;
move miss handler parameter support here.
01b,28oct03,jtp Support Base 6 AIM MMU
01a,18jul00,sm written.
*/
/*
DESCRIPTION
This header contains the public interface to the PowerPC 405 Core Memory
Management Library. It also defines private (internal) structures and
macros used to manipulate the 405 MMU.
Theory: the vmBaseLib and vmLib provide an application programmer
interface to the memory management and protection features of the 405
MMU. With the help of the aimMmuLib and mmu405Lib layers, a data
structure is maintained which stores per-page attributes: validity,
protection, cacheability, and address translation. This data structure
represents each page as a page table entry (PTE).
The 405 MMU hardware maintains a cache of 64 Unified Translation
Lookaside Buffer (TLB) Entry registers. When the processor accesses a
memory location and fails to find matching TLB entry, it calls an
interrupt handler to establish a mapping. That miss handler walks the
data structure and copies a PTE into a TLB Entry register.
This file provides data needed to coordinate the mmu405Lib layer with
the aimMmuLib and vmLib/vmBaseLib layers.
See also:
VxWorks PowerPC Architecture Supplement, WindRiver
IBM PowerPC 405GP User's Manual, IBM
IBM PowerPC 405CR User's Manual, IBM
IBM PowerPC Npe405H/L User's Manual, IBM
*/
#ifndef __INCmmuPpc405Libh
#define __INCmmuPpc405Libh
#ifdef __cplusplus
extern "C" {
#endif
/* defines */
/*
* Number of TLB Entry registers, expressed both as a power of two
* as well as an integer.
*/
#define N_TLB_ENTRIES_BITS 6
#define N_TLB_ENTRIES (1 << N_TLB_ENTRIES_BITS)
/*
* MMU_I_ADDR_TRANS and MMU_D_ADDR_TRANS are used in the mmu405Lib /
* mmuPpcALib & cacheALib call interface. They are not useful at the
* application programming level.
*/
#define MMU_I_ADDR_TRANS 0
#define MMU_D_ADDR_TRANS 1
/*
* MMU_INST and MMU_DATA are used at the usrMmuInit / mmu405Lib call
* interface. They are not useful at the application programming
* level.
*/
#define MMU_INST 0x01
#define MMU_DATA 0x02
/*
* MMU_STATE attributes cover, at a minumum, validity, cacheability, and
* protection. In PowerPC the attributes also include guarded (forbids
* speculative access) and memory coherency tagging.
*
* The PowerPC 405GP does not support memory coherency, so setting this
* bit is irrelevant. However, other versions of the 405 core may choose
* to add support. The 405 hardware also supports U0 and E bits but the
* 405 MMU library does not utilize them.
*
* Note: the GLOBAL bit is used for the miss handler and is not used by the
* hardware.
*/
#define MMU_STATE_VALID 0x00000400
#define MMU_STATE_VALID_NOT 0x00000000
#define MMU_STATE_GLOBAL 0x00000800
#define MMU_STATE_GLOBAL_NOT 0x00000000
#define MMU_STATE_CACHEABLE 0x00000000
#define MMU_STATE_CACHEABLE_NOT 0x00000004
#define MMU_STATE_CACHEABLE_WRITETHROUGH 0x00000008
#define MMU_STATE_CACHEABLE_COPYBACK 0x00000000
#define MMU_STATE_MEM_COHERENCY 0x00000002
#define MMU_STATE_MEM_COHERENCY_NOT 0x00000000
#define MMU_STATE_GUARDED 0x00000001
#define MMU_STATE_GUARDED_NOT 0x00000000
#define MMU_STATE_ENDIAN_LITTLE 0x00001000
#define MMU_STATE_ISR_CALLABLE 0x00080000
#define MMU_STATE_MASK_VALID 0x00000400
#define MMU_STATE_MASK_GLOBAL 0x00000800
#define MMU_STATE_MASK_CACHEABLE 0x0000000c
#define MMU_STATE_MASK_MEM_COHERENCY 0x00000002
#define MMU_STATE_MASK_GUARDED 0x00000001
#define MMU_STATE_MASK_PROTECTION 0x000003f0
#define MMU_STATE_MASK_ISR_CALLABLE 0x00080000
/*
* Protection Bits
*
* Each TLB entry controls access to one page of memory. The
* protection mode is controlled by 6 bits in the TLB word, split
* into 3 fields. These fields are:
*
* EX - Executable. 1 bit. if 1, page may be executable
* WR - Writable. 1 bit. if 1, page is writable
* ZSEL - Zone Select. 4 bits. Indexes into the Zone Protection Regsiter
*
* The Zone Protection Register (ZPR) is a 32 bit register consisting of
* 16 2-bit fields. It is indexed by a TLB entry's ZSEL field. The value
* of each 2-bit field may be:
*
* 0 - access is Supervisor only, controlled by the EX and WR bits.
* 1 - access is both Supervisor and User, controlled by the EX and WR
* bits.
* 2 - acess is Supervisor RWX, and User controlled by the EX and WR
* bits.
* 3 - access is Supervisor RWX, User RWX. The EX and WR bits are
* ignored.
*
* The 405 MMU also allows any valid page to be read in supervisor mode.
*
* The VxWorks mmu405Lib implementation applies the above TLB entry
* fields and the ZPR register to support page protection.
*
* The ZPR is initialized to have four valid zones, indexed by ZSEL
* values 0, 1, 2, and 3, and containing values of 0, 1, 2, and 3.
*
* The Selected Zone Protection Register bitfields (looked up via the
* TLB ZSEL field) in cooperation with the TLB EX and WR bits,
* implement the following (and only the following) page protections:
*
* EX WR ZPR SupUsr
* 0 0 00 r-----
* 0 1 00 rw----
* 1 0 00 r-x---
* 1 1 00 rwx---
* 0 0 01 r--r--
* 0 1 01 rw-rw-
* 1 0 01 r-xr-x
* 1 1 01 rwxrwx
* 0 0 10 rwxr--
* 0 1 10 rwxrw-
* 1 0 10 rwxr-x
* 1 1 10 rwxrwx
* - - 11 rwxrwx
*
* Note that some page protection settings cannot be supported with the
* 405 MMU, in general, the supervisor mode always has more access
* rights than the user mode.
*
* These protection bits (EX, WR, ZSEL 0-3 mapping to ZPR fields 0-3)
* are mapped directly into MMU_STATE_* macros, defined below:
*/
/* MMU_STATE_* protection mode sub-fields, mapping 1:1 with hardware */
#define _MMU_EX 0x00000200 /* executable, modified by ZSEL */
#define _MMU_WR 0x00000100 /* writable, modified by ZSEL */
#define _MMU_ZSEL_0 0x00000000 /* SUP (only) R + EX + WR */
#define _MMU_ZSEL_1 0x00000010 /* SUP & USR both R + EX + WR */
#define _MMU_ZSEL_2 0x00000020 /* SUP RWX. USR R + EX + WR */
#define _MMU_ZSEL_3 0x00000030 /* SUP RWX. USR RWX. */
#define _MMU_ZSEL_MASK 0x000000f0 /* mask for ZSEL field */
/* MMU_STATE_* protection modes macros */
#define MMU_STATE_SUP_R (_MMU_ZSEL_0 )
#define MMU_STATE_SUP_RW (_MMU_ZSEL_0 | _MMU_WR )
#define MMU_STATE_SUP_RX (_MMU_ZSEL_0 | _MMU_EX)
#define MMU_STATE_SUP_RWX (_MMU_ZSEL_0 | _MMU_WR | _MMU_EX)
#define MMU_STATE_SUP_R_USR_R (_MMU_ZSEL_1 )
/* #define MMU_STATE_SUP_RW_USR_R /@ mode not supported */
/* #define MMU_STATE_SUP_RX_USR_R /@ mode not supported */
#define MMU_STATE_SUP_RWX_USR_R (_MMU_ZSEL_2 )
/* #define MMU_STATE_SUP_R_USR_W /@ mode not supported */
/* #define MMU_STATE_SUP_RW_USR_W /@ mode not supported */
/* #define MMU_STATE_SUP_RX_USR_W /@ mode not supported */
/* #define MMU_STATE_SUP_RWX_USR_W /@ mode not supported */
/* #define MMU_STATE_SUP_R_USR_RW /@ mode not supported */
#define MMU_STATE_SUP_RW_USR_RW (_MMU_ZSEL_1 | _MMU_WR )
/* #define MMU_STATE_SUP_RX_USR_RW /@ mode not supported */
#define MMU_STATE_SUP_RWX_USR_RW (_MMU_ZSEL_2 | _MMU_WR )
/* #define MMU_STATE_SUP_R_USR_X /@ mode not supported */
/* #define MMU_STATE_SUP_RW_USR_X /@ mode not supported */
/* #define MMU_STATE_SUP_RX_USR_X /@ mode not supported */
/* #define MMU_STATE_SUP_RWX_USR_X /@ mode not supported */
/* #define MMU_STATE_SUP_R_USR_RX /@ mode not supported */
/* #define MMU_STATE_SUP_RW_USR_RX /@ mode not supported */
#define MMU_STATE_SUP_RX_USR_RX (_MMU_ZSEL_1 | _MMU_EX)
#define MMU_STATE_SUP_RWX_USR_RX (_MMU_ZSEL_2 | _MMU_EX)
/* #define MMU_STATE_SUP_R_USR_WX /@ mode not supported */
/* #define MMU_STATE_SUP_RW_USR_WX /@ mode not supported */
/* #define MMU_STATE_SUP_RX_USR_WX /@ mode not supported */
/* #define MMU_STATE_SUP_RWX_USR_WX /@ mode not supported */
/* #define MMU_STATE_SUP_R_USR_RWX /@ mode not supported */
/* #define MMU_STATE_SUP_RW_USR_RWX /@ mode not supported */
/* #define MMU_STATE_SUP_RX_USR_RWX /@ mode not supported */
#define MMU_STATE_SUP_RWX_USR_RWX (_MMU_ZSEL_3 )
/*
* Initial value of the ZPR.
*
* The ZPR, in collusion with the EX and WR bits, is used to set
* MMU page protection attributes.
*
* - Zone 0 is SUP only, controlled by the EX and WR bits.
* - Zone 1 is SUP and USR, controlled by the EX and WR bits.
* - Zone 2 is SUP RWX, and USR controlled by the EX and WR bits.
* - Zone 3 is SUP RWX, USR RWX.
* - Zone 4..15 is SUP only, controlled by the EX and WR bits.
*/
#define MMU_ZPR_INIT_VAL \
(0 << 30) | (1 << 28) | (2 << 26) | (3 << 24) | \
(0 << 22) | (0 << 20) | (0 << 18) | (0 << 16) | \
(0 << 14) | (0 << 12) | (0 << 10) | (0 << 8) | \
(0 << 6) | (0 << 4) | (0 << 2) | (0 << 0)
/*
* MMU_RPN_SHIFT. The 405 TLB entry contains Real Page Number (RPN) and
* Effective Page Number (EPN) fields which store the physical and
* virtual page bits. These fields always begin at the most significant
* bit of the TLB word they are stored in, and the number of significant
* bits depends on the TLB Page Size field. The 405 MMU code only
* supports page sizes that are a multiple of MMU_PAGE_SIZE_4XX_MIN
* bytes. The bit offset to convert a Real or Effective Page Number
* field into a page base address is MMU_RPN_SHIFT. It must also match
* the size of the rpn and epn bitfields in the MMU405_PTE structure,
* below.
*/
#define MMU_RPN_SHIFT MMU_PAGE_BITS_MIN
/*
* Each context's MMU pages are mapped using a two-level page table
* scheme. The level 1 table is called the REGION table and the level
* 2 table is called a PAGE table.
*
* The most significant MMU_REGION_INDEX_BITS bits of the virtual
* address are used as an index into the Region Table. Each entry is of
* size 2 ^ MMU_REGION_ENTRY_BITS, typically a pointer to a PAGE table.
*/
#define MMU_REGION_INDEX_BITS 10 /* number of bits in index */
#define MMU_REGION_TBL_ENTRIES (0x1 << MMU_REGION_INDEX_BITS)
/* number of regions in table */
#define MMU_REGION_ENTRY_BITS 2 /* size in bytes as pwr of 2 */
/*
* The next most significant bits of the virtual address are used as an
* index into the Page Table. Note that MMU_PAGE_INDEX_BITS_MAX
* describes the maximum number of bits to be used as a index to look up
* an entry in the page table. Fewer bits may be used if the
* mmu405PageSizeMin is set to a larger hardware-TLB-supported page
* size.
*
* Each entry is of size 2 ^ MMU_PAGE_ENTRY_BITS, which is the size of
* an MMU405_PTE.
*/
#define MMU_PAGE_INDEX_BITS_MAX 10 /* number of bits in index */
#define MMU_PAGE_TBL_ENTRIES_MAX (0x1 << MMU_PAGE_INDEX_BITS_MAX)
/* max number of page table entries */
#define MMU_PAGE_ENTRY_BITS 3 /* MMU405_PTE size in bytes as pwr of 2 */
/*
* The remaining bits are the "offset" portion of a virtual address. All
* the most significant bits have been translated as part of the
* virtual->real page number lookup.
*
* The page size is at least MMU_PAGE_SIZE_4XX_MIN, but may be larger if
* mmu405PageSizeMin is set to a larger hardware-TLB-supported page
* size.
*/
#define MMU_PAGE_BITS_MIN (32 - (MMU_REGION_INDEX_BITS + \
MMU_PAGE_INDEX_BITS_MAX ))
#define MMU_PAGE_SIZE_4XX_MIN (0x1 << MMU_PAGE_BITS_MIN)
/* Range of hardware context numbers (PID register & TLB TID field) */
#define MMU_ASID_MIN 1
#define MMU_ASID_MAX 255
#define MMU_ASID_GLOBAL MMU_ASID_MIN
/* TLB Miss Handler information */
/* Support for miss handler */
#define TLB_V_BIT 25 /* valid bit is at bit 25 of word 0 */
#define TLB_GLOBAL_BIT 28 /* global page map bit is at bit 28 of word 0 */
#define TLB_LOCK_BIT 29 /* lock page map bit is at bit 29 of word 0 */
#define TLB_ISR_CALL_BIT 30 /* isr callable bit is at bit 30 of word 0 */
#define TLB_N_WORDS 2 /* two TLB words, hi (0) and lo (1) */
#define TLB_MIN_SUPPORT /* use TLB indexes from 0 to max */
#undef CACHE_STATE_VAR /* no mod to W, I bits in miss handler */
#define TID_SOURCE PID /* PID is source of TLB Entry TID field */
#define MMU405_NUM_LOCKED_ENTRIES 0x6
/* page sizes */
#define _MMU_TLB_SZ_1K 0x00000000 /* 1KB page size */
#define _MMU_TLB_SZ_4K 0x00000080 /* 4KB page size */
#define _MMU_TLB_SZ_16K 0x00000100 /* 16KB page size */
#define _MMU_TLB_SZ_64K 0x00000180 /* 64KB page size */
#define _MMU_TLB_SZ_256K 0x00000200 /* 256KB page size */
#define _MMU_TLB_SZ_1M 0x00000280 /* 1MB page size */
#define _MMU_TLB_SZ_4M 0x00000300 /* 4MB page size */
#define _MMU_TLB_SZ_16M 0x00000380 /* 16MB page size */
#define _MMU_TLB_SZ_MASK 0x00000380 /* mask for page size field */
#define _MMU_TLB_SZ_SHIFT 7 /* offset of page size field */
/******************************************************************************
*
* Page Table Entry descriptor definition
*
* This PTE stores most of the fields needed to update a TLB entry. Note
* that we store only the 20 most significant bits of the EPN and RPN,
* since we support a minimum page size of 4K.
*
* TLB fields are from ch. 6. PPC405GP Embedded Processor User's Manual,
* Sixth Preliminary Edition (June 2000)
*
* TLB Word 0 (aka TLBHI):
*
* 0 8 16 21 24 26 28 31
* +---------------.---------------.-----------+---.-+-+-+-+-+-----+
* | EPN |SIZE |V|E|U|G|-----|
* | | | | |0|L|-----|
* +---------------'---------------'-----------+---'-+-+-+-+-+-----+
*
* EPN - Effective (Virtual) address Page Number
* SIZE - Page Size - mmu405Lib maps pages of size MMU_PAGE_SIZE. Larger
* sized pages are set up in static TLB mappings in the BSP,
* or may be automatically managed by the AIM MMU for optimized
* mappings.
* V - Valid page bit
* E,U0 - Unused by mmu405Lib and set to zero
* GL - global bit, set to 1 in a page table entry to inform the TLB
* Miss handler that this page is global; i.e. mapped in all
* contexts, that is, a TID=0. This bit is set to 0 before
* writing to the hardware TLB Entry
*
* TLB Word 1 (aka TLBLO):
*
* 0 8 16 21 24 28 31
* +---------------.---------------.-----------+-+-+-------+-+-+-+-+
* | RPN |E|W| ZSEL |W|I|M|G|
* | |X|R| | | | | |
* +---------------'---------------'-----------+-+-+-------+-+-+-+-+
*
* RPN - Real (Physical) address Page Number
* EX - EXecutable, unless altered by zone protection
* WR - WRitable bit, unless altered by zone protection
* ZSEL - Zone SELect - select protection zone bit pairs from ZPR register
* W - Write-Through
* I - Caching Inhibited
* M - Unused by mmu405Lib and 405 hardware, and set to zero
* G - Guarded (Avoid speculative access)
*
*/
#ifndef _ASMLANGUAGE
typedef union mmu405_pte /* Page Table Entry format */
{
struct /* Bit field desciption */
{
/* hi word */
UINT32 epn:20; /* effective page number */
UINT32 rsvd1:2; /* reserved */
UINT32 size:3; /* page size (min 4k) */
UINT32 v:1; /* valid bit */
UINT32 e:1; /* little endian bit */
UINT32 u0:1; /* user attribute */
UINT32 global:1; /* miss hdlr will map page in all contexts */
UINT32 lock:1;
UINT32 isr:1;
UINT32 rsvd2:1; /* reserved */
/* lo word */
UINT32 rpn:20; /* real page number */
UINT32 rsvd3:2; /* reserved */
UINT32 ex:1; /* execute protection */
UINT32 wr:1; /* write protection */
UINT32 zsel:4; /* zone protection */
UINT32 w:1; /* write thru/back */
UINT32 i:1; /* cache inhibited */
UINT32 m:1; /* memory coherent */
UINT32 g:1; /* memory guarded */
} field;
struct
{
UINT32 word0; /* hi word */
UINT32 word1; /* lo word */
} words;
} MMU405_PTE;
#if defined(__STDC__) || defined(__cplusplus)
extern STATUS mmu405LibInit (int mmuType, UINT minPageSize);
#else /* __STDC__ */
extern STATUS mmu405LibInit ();
#endif /* __STDC__ */
#endif /* _ASMLANGUAGE */
#ifdef __cplusplus
}
#endif
#endif /* __INCmmuPpc405Libh */