Merge pull request #538 from sandrine-bailleux-arm/sb/extend-memory-types
Extend memory attributes to map non-cacheable memory
This commit is contained in:
commit
a34f3bf213
|
@ -419,11 +419,11 @@
|
|||
#define AP_RW (0x0 << 5)
|
||||
|
||||
#define NS (0x1 << 3)
|
||||
#define ATTR_SO_INDEX 0x2
|
||||
#define ATTR_NON_CACHEABLE_INDEX 0x2
|
||||
#define ATTR_DEVICE_INDEX 0x1
|
||||
#define ATTR_IWBWA_OWBWA_NTR_INDEX 0x0
|
||||
#define LOWER_ATTRS(x) (((x) & 0xfff) << 2)
|
||||
#define ATTR_SO (0x0)
|
||||
#define ATTR_NON_CACHEABLE (0x44)
|
||||
#define ATTR_DEVICE (0x4)
|
||||
#define ATTR_IWBWA_OWBWA_NTR (0xff)
|
||||
#define MAIR_ATTR_SET(attr, index) (attr << (index << 3))
|
||||
|
|
|
@ -52,21 +52,41 @@
|
|||
#define MAP_REGION(pa, va, sz, attr) {(pa), (va), (sz), (attr)}
|
||||
|
||||
/*
|
||||
* Flags for building up memory mapping attributes.
|
||||
* These are organised so that a clear bit gives a more restrictive mapping
|
||||
* that a set bit, that way a bitwise-and two sets of attributes will never give
|
||||
* an attribute which has greater access rights that any of the original
|
||||
* attributes.
|
||||
* Shifts and masks to access fields of an mmap_attr_t
|
||||
*/
|
||||
#define MT_TYPE_MASK 0x7
|
||||
#define MT_TYPE(_attr) ((_attr) & MT_TYPE_MASK)
|
||||
/* Access permissions (RO/RW) */
|
||||
#define MT_PERM_SHIFT 3
|
||||
/* Security state (SECURE/NS) */
|
||||
#define MT_SEC_SHIFT 4
|
||||
|
||||
/*
|
||||
* Memory mapping attributes
|
||||
*/
|
||||
typedef enum {
|
||||
MT_DEVICE = 0 << 0,
|
||||
MT_MEMORY = 1 << 0,
|
||||
/*
|
||||
* Memory types supported.
|
||||
* These are organised so that, going down the list, the memory types
|
||||
* are getting weaker; conversely going up the list the memory types are
|
||||
* getting stronger.
|
||||
*/
|
||||
MT_DEVICE,
|
||||
MT_NON_CACHEABLE,
|
||||
MT_MEMORY,
|
||||
/* Values up to 7 are reserved to add new memory types in the future */
|
||||
|
||||
MT_RO = 0 << 1,
|
||||
MT_RW = 1 << 1,
|
||||
/*
|
||||
* The following values are organised so that a clear bit gives a more
|
||||
* restrictive mapping than a set bit, that way a bitwise-and of two
|
||||
* sets of attributes will never give an attribute which has greater
|
||||
* access rights than any of the original attributes.
|
||||
*/
|
||||
MT_RO = 0 << MT_PERM_SHIFT,
|
||||
MT_RW = 1 << MT_PERM_SHIFT,
|
||||
|
||||
MT_SECURE = 0 << 2,
|
||||
MT_NS = 1 << 2
|
||||
MT_SECURE = 0 << MT_SEC_SHIFT,
|
||||
MT_NS = 1 << MT_SEC_SHIFT,
|
||||
} mmap_attr_t;
|
||||
|
||||
/*
|
||||
|
|
|
@ -138,6 +138,7 @@ static unsigned long mmap_desc(unsigned attr, unsigned long addr_pa,
|
|||
unsigned level)
|
||||
{
|
||||
unsigned long desc = addr_pa;
|
||||
int mem_type;
|
||||
|
||||
desc |= level == 3 ? TABLE_DESC : BLOCK_DESC;
|
||||
|
||||
|
@ -147,16 +148,23 @@ static unsigned long mmap_desc(unsigned attr, unsigned long addr_pa,
|
|||
|
||||
desc |= LOWER_ATTRS(ACCESS_FLAG);
|
||||
|
||||
if (attr & MT_MEMORY) {
|
||||
mem_type = MT_TYPE(attr);
|
||||
if (mem_type == MT_MEMORY) {
|
||||
desc |= LOWER_ATTRS(ATTR_IWBWA_OWBWA_NTR_INDEX | ISH);
|
||||
if (attr & MT_RW)
|
||||
desc |= UPPER_ATTRS(XN);
|
||||
} else if (mem_type == MT_NON_CACHEABLE) {
|
||||
desc |= LOWER_ATTRS(ATTR_NON_CACHEABLE_INDEX | OSH);
|
||||
if (attr & MT_RW)
|
||||
desc |= UPPER_ATTRS(XN);
|
||||
} else {
|
||||
assert(mem_type == MT_DEVICE);
|
||||
desc |= LOWER_ATTRS(ATTR_DEVICE_INDEX | OSH);
|
||||
desc |= UPPER_ATTRS(XN);
|
||||
}
|
||||
|
||||
debug_print(attr & MT_MEMORY ? "MEM" : "DEV");
|
||||
debug_print((mem_type == MT_MEMORY) ? "MEM" :
|
||||
((mem_type == MT_NON_CACHEABLE) ? "NC" : "DEV"));
|
||||
debug_print(attr & MT_RW ? "-RW" : "-RO");
|
||||
debug_print(attr & MT_NS ? "-NS" : "-S");
|
||||
|
||||
|
@ -167,6 +175,7 @@ static int mmap_region_attr(mmap_region_t *mm, unsigned long base_va,
|
|||
unsigned long size)
|
||||
{
|
||||
int attr = mm->attr;
|
||||
int old_mem_type, new_mem_type;
|
||||
|
||||
for (;;) {
|
||||
++mm;
|
||||
|
@ -183,7 +192,20 @@ static int mmap_region_attr(mmap_region_t *mm, unsigned long base_va,
|
|||
if ((mm->attr & attr) == attr)
|
||||
continue; /* Region doesn't override attribs so skip */
|
||||
|
||||
/*
|
||||
* Update memory mapping attributes in 2 steps:
|
||||
* 1) Update access permissions and security state flags
|
||||
* 2) Update memory type.
|
||||
*
|
||||
* See xlat_tables.h for details about the attributes priority
|
||||
* system and the rules dictating whether attributes should be
|
||||
* updated.
|
||||
*/
|
||||
old_mem_type = MT_TYPE(attr);
|
||||
new_mem_type = MT_TYPE(mm->attr);
|
||||
attr &= mm->attr;
|
||||
if (new_mem_type < old_mem_type)
|
||||
attr = (attr & ~MT_TYPE_MASK) | new_mem_type;
|
||||
|
||||
if (mm->base_va > base_va ||
|
||||
mm->base_va + mm->size < base_va + size)
|
||||
|
@ -309,6 +331,8 @@ void init_xlat_tables(void)
|
|||
mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX); \
|
||||
mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, \
|
||||
ATTR_IWBWA_OWBWA_NTR_INDEX); \
|
||||
mair |= MAIR_ATTR_SET(ATTR_NON_CACHEABLE, \
|
||||
ATTR_NON_CACHEABLE_INDEX); \
|
||||
write_mair_el##_el(mair); \
|
||||
\
|
||||
/* Invalidate TLBs at the current exception level */ \
|
||||
|
|
Loading…
Reference in New Issue