khypervisor  v1
lpae.h
Go to the documentation of this file.
00001 #ifndef __LPAE_H__
00002 #define __LPAE_H__
00003 #include <arch_types.h>
00004 
00005 #define LPAE_PAGE_SHIFT    12
00006 #define LPAE_PAGE_SIZE      (1<<LPAE_PAGE_SHIFT)
00007 #define LPAE_PAGE_MASK      (0xFFF)
00008 
00009 #define LPAE_BLOCK_L2_SHIFT 21
00010 #define LPAE_BLOCK_L2_SIZE  (1<<LPAE_BLOCK_L2_SHIFT)
00011 #define LPAE_BLOCK_L2_MASK  (0x1FFFFF)
00012 
00013 /*
00014  * Attribute Indexes.
00015  *
00016  * These are valid in the AttrIndx[2:0] field of an LPAE stage 1 page
00017  * table entry. They are indexes into the bytes of the MAIR*
00018  * registers, as defined above.
00019  *
00020  */
00021 #define ATTR_IDX_UNCACHED      0x0
00022 #define ATTR_IDX_BUFFERABLE    0x1
00023 #define ATTR_IDX_WRITETHROUGH  0x2
00024 #define ATTR_IDX_WRITEBACK     0x3
00025 #define ATTR_IDX_DEV_SHARED    0x4
00026 #define ATTR_IDX_WRITEALLOC    0x7
00027 #define ATTR_IDX_DEV_NONSHARED DEV_SHARED
00028 #define ATTR_IDX_DEV_WC        BUFFERABLE
00029 #define ATTR_IDX_DEV_CACHED    WRITEBACK
00030 
00031 /******************************************************************************
00032  * ARMv7-A LPAE pagetables: 3-level trie, mapping 40-bit input to
00033  * 40-bit output addresses.  Tables at all levels have 512 64-bit entries
00034  * (i.e. are 4Kb long).
00035  *
00036  * The bit-shuffling that has the permission bits in branch nodes in a
00037  * different place from those in leaf nodes seems to be to allow linear
00038  * pagetable tricks.  If we're not doing that then the set of permission
00039  * bits that's not in use in a given node type can be used as
00040  * extra software-defined bits. */
00041 
00042 typedef struct {
00043     /* These are used in all kinds of entry. */
00044     unsigned long valid:1;      /* Valid mapping */
00045     unsigned long table:1;      /* == 1 in 4k map entries too */
00046 
00047     /* These ten bits are only used in Block entries and are ignored
00048      * in Table entries. */
00049     unsigned long ai:3;         /* Attribute Index */
00050     unsigned long ns:1;         /* Not-Secure */
00051     unsigned long user:1;       /* User-visible */
00052     unsigned long ro:1;         /* Read-Only */
00053     unsigned long sh:2;         /* Shareability */
00054     unsigned long af:1;         /* Access Flag */
00055     unsigned long ng:1;         /* Not-Global */
00056 
00057     /* The base address must be appropriately aligned for Block entries */
00058     unsigned long base:28;      /* Base address of block or next table */
00059     unsigned long sbz:12;       /* Must be zero */
00060 
00061     /* These seven bits are only used in Block entries and are ignored
00062      * in Table entries. */
00063     unsigned long hint:1;       /* In a block of 16 contiguous entries */
00064     unsigned long pxn:1;        /* Privileged-XN */
00065     unsigned long xn:1;         /* eXecute-Never */
00066     unsigned long avail:4;      /* Ignored by hardware */
00067 
00068     /* These 5 bits are only used in Table entries and are ignored in
00069      * Block entries */
00070     unsigned long pxnt:1;       /* Privileged-XN */
00071     unsigned long xnt:1;        /* eXecute-Never */
00072     unsigned long apt:2;        /* Access Permissions */
00073     unsigned long nst:1;        /* Not-Secure */
00074 } __attribute__((__packed__)) lpae_pt_t;
00075 
00076 /* The p2m tables have almost the same layout, but some of the permission
00077  * and cache-control bits are laid out differently (or missing) */
00078 typedef struct {
00079     /* These are used in all kinds of entry. */
00080     unsigned long valid:1;      /* Valid mapping */
00081     unsigned long table:1;      /* == 1 in 4k map entries too */
00082 
00083     /* These ten bits are only used in Block entries and are ignored
00084      * in Table entries. */
00085     unsigned long mattr:4;      /* Memory Attributes */
00086     unsigned long read:1;       /* Read access */
00087     unsigned long write:1;      /* Write access */
00088     unsigned long sh:2;         /* Shareability */
00089     unsigned long af:1;         /* Access Flag */
00090     unsigned long sbz4:1;
00091 
00092     /* The base address must be appropriately aligned for Block entries */
00093     unsigned long base:28;      /* Base address of block or next table */
00094     unsigned long sbz3:12;
00095 
00096     /* These seven bits are only used in Block entries and are ignored
00097      * in Table entries. */
00098     unsigned long hint:1;       /* In a block of 16 contiguous entries */
00099     unsigned long sbz2:1;
00100     unsigned long xn:1;         /* eXecute-Never */
00101     unsigned long avail:4;      /* Ignored by hardware */
00102 
00103     unsigned long sbz1:5;
00104 } __attribute__((__packed__)) lpae_p2m_t;
00105 
00106 
00107 /*
00108  * Walk is the common bits of p2m and pt entries which are needed to
00109  * simply walk the table (e.g. for debug).
00110  */
00111 typedef struct {
00112     /* These are used in all kinds of entry. */
00113     unsigned long valid:1;      /* Valid mapping */
00114     unsigned long table:1;      /* == 1 in 4k map entries too */
00115 
00116     unsigned long pad2:10;
00117 
00118     /* The base address must be appropriately aligned for Block entries */
00119     unsigned long base:28;      /* Base address of block or next table */
00120 
00121     unsigned long pad1:24;
00122 } __attribute__((__packed__)) lpae_walk_t;
00123 
00124 typedef union {
00125     uint64_t bits;
00126     lpae_pt_t pt;
00127     lpae_p2m_t p2m;
00128     lpae_walk_t walk;
00129 } lpaed_t;
00130 
00131 typedef enum {
00132     LPAED_STAGE2_MEMATTR_SO = 0x0,   /* Strongly Ordered */
00133     LPAED_STAGE2_MEMATTR_DM = 0x1,   /* Device memory */
00134     LPAED_STAGE2_MEMATTR_NORMAL_ONC = 0x4,  /* Outer Non-cacheable */
00135     LPAED_STAGE2_MEMATTR_NORMAL_OWT = 0x8,
00136     LPAED_STAGE2_MEMATTR_NORMAL_OWB = 0xC,
00137     LPAED_STAGE2_MEMATTR_NORMAL_INC = 0x1,
00138     LPAED_STAGE2_MEMATTR_NORMAL_IWT = 0x2,
00139     LPAED_STAGE2_MEMATTR_NORMAL_IWB = 0x3,
00140 } lpaed_stage2_memattr_t;
00141 
00142 lpaed_t hvmm_mm_lpaed_l1_block( uint64_t pa, uint8_t attr_idx );
00143 lpaed_t hvmm_mm_lpaed_l2_block( uint64_t pa, lpaed_stage2_memattr_t mattr );
00144 lpaed_t hvmm_mm_lpaed_l1_table( uint64_t pa);
00145 lpaed_t hvmm_mm_lpaed_l2_table( uint64_t pa);
00146 lpaed_t hvmm_mm_lpaed_l3_table( uint64_t pa, uint8_t attr_idx, uint8_t valid );
00147 void lpaed_stage1_conf_l3_table( lpaed_t *ttbl3, uint64_t baddr, uint8_t valid );
00148 void lpaed_stage1_disable_l3_table( lpaed_t *ttbl2 );
00149 void lpaed_stage2_map_page( lpaed_t *pte, uint64_t pa, lpaed_stage2_memattr_t mattr );
00150 void lpaed_stage2_conf_l1_table( lpaed_t *ttbl1, uint64_t baddr, uint8_t valid );
00151 void lpaed_stage2_conf_l2_table( lpaed_t *ttbl2, uint64_t baddr, uint8_t valid );
00152 void lpaed_stage2_enable_l2_table( lpaed_t *ttbl2 );
00153 void lpaed_stage2_disable_l2_table( lpaed_t *ttbl2 );
00154 
00155 #endif
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines