Commit a34f3bf2 authored by danh-arm's avatar danh-arm
Browse files

Merge pull request #538 from sandrine-bailleux-arm/sb/extend-memory-types

Extend memory attributes to map non-cacheable memory
parents b6fc25e0 5f654975
...@@ -419,11 +419,11 @@ ...@@ -419,11 +419,11 @@
#define AP_RW (0x0 << 5) #define AP_RW (0x0 << 5)
#define NS (0x1 << 3) #define NS (0x1 << 3)
#define ATTR_SO_INDEX 0x2 #define ATTR_NON_CACHEABLE_INDEX 0x2
#define ATTR_DEVICE_INDEX 0x1 #define ATTR_DEVICE_INDEX 0x1
#define ATTR_IWBWA_OWBWA_NTR_INDEX 0x0 #define ATTR_IWBWA_OWBWA_NTR_INDEX 0x0
#define LOWER_ATTRS(x) (((x) & 0xfff) << 2) #define LOWER_ATTRS(x) (((x) & 0xfff) << 2)
#define ATTR_SO (0x0) #define ATTR_NON_CACHEABLE (0x44)
#define ATTR_DEVICE (0x4) #define ATTR_DEVICE (0x4)
#define ATTR_IWBWA_OWBWA_NTR (0xff) #define ATTR_IWBWA_OWBWA_NTR (0xff)
#define MAIR_ATTR_SET(attr, index) (attr << (index << 3)) #define MAIR_ATTR_SET(attr, index) (attr << (index << 3))
......
...@@ -52,21 +52,41 @@ ...@@ -52,21 +52,41 @@
#define MAP_REGION(pa, va, sz, attr) {(pa), (va), (sz), (attr)} #define MAP_REGION(pa, va, sz, attr) {(pa), (va), (sz), (attr)}
/* /*
* Flags for building up memory mapping attributes. * Shifts and masks to access fields of an mmap_attr_t
* 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 #define MT_TYPE_MASK 0x7
* an attribute which has greater access rights that any of the original #define MT_TYPE(_attr) ((_attr) & MT_TYPE_MASK)
* attributes. /* Access permissions (RO/RW) */
#define MT_PERM_SHIFT 3
/* Security state (SECURE/NS) */
#define MT_SEC_SHIFT 4
/*
* Memory mapping attributes
*/ */
typedef enum { 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_SECURE = 0 << MT_SEC_SHIFT,
MT_NS = 1 << 2 MT_NS = 1 << MT_SEC_SHIFT,
} mmap_attr_t; } mmap_attr_t;
/* /*
......
...@@ -138,6 +138,7 @@ static unsigned long mmap_desc(unsigned attr, unsigned long addr_pa, ...@@ -138,6 +138,7 @@ static unsigned long mmap_desc(unsigned attr, unsigned long addr_pa,
unsigned level) unsigned level)
{ {
unsigned long desc = addr_pa; unsigned long desc = addr_pa;
int mem_type;
desc |= level == 3 ? TABLE_DESC : BLOCK_DESC; desc |= level == 3 ? TABLE_DESC : BLOCK_DESC;
...@@ -147,16 +148,23 @@ static unsigned long mmap_desc(unsigned attr, unsigned long addr_pa, ...@@ -147,16 +148,23 @@ static unsigned long mmap_desc(unsigned attr, unsigned long addr_pa,
desc |= LOWER_ATTRS(ACCESS_FLAG); 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); desc |= LOWER_ATTRS(ATTR_IWBWA_OWBWA_NTR_INDEX | ISH);
if (attr & MT_RW) if (attr & MT_RW)
desc |= UPPER_ATTRS(XN); 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 { } else {
assert(mem_type == MT_DEVICE);
desc |= LOWER_ATTRS(ATTR_DEVICE_INDEX | OSH); desc |= LOWER_ATTRS(ATTR_DEVICE_INDEX | OSH);
desc |= UPPER_ATTRS(XN); 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_RW ? "-RW" : "-RO");
debug_print(attr & MT_NS ? "-NS" : "-S"); debug_print(attr & MT_NS ? "-NS" : "-S");
...@@ -167,6 +175,7 @@ static int mmap_region_attr(mmap_region_t *mm, unsigned long base_va, ...@@ -167,6 +175,7 @@ static int mmap_region_attr(mmap_region_t *mm, unsigned long base_va,
unsigned long size) unsigned long size)
{ {
int attr = mm->attr; int attr = mm->attr;
int old_mem_type, new_mem_type;
for (;;) { for (;;) {
++mm; ++mm;
...@@ -183,7 +192,20 @@ static int mmap_region_attr(mmap_region_t *mm, unsigned long base_va, ...@@ -183,7 +192,20 @@ static int mmap_region_attr(mmap_region_t *mm, unsigned long base_va,
if ((mm->attr & attr) == attr) if ((mm->attr & attr) == attr)
continue; /* Region doesn't override attribs so skip */ 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; attr &= mm->attr;
if (new_mem_type < old_mem_type)
attr = (attr & ~MT_TYPE_MASK) | new_mem_type;
if (mm->base_va > base_va || if (mm->base_va > base_va ||
mm->base_va + mm->size < base_va + size) mm->base_va + mm->size < base_va + size)
...@@ -309,6 +331,8 @@ void init_xlat_tables(void) ...@@ -309,6 +331,8 @@ void init_xlat_tables(void)
mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX); \ mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX); \
mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, \ mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, \
ATTR_IWBWA_OWBWA_NTR_INDEX); \ ATTR_IWBWA_OWBWA_NTR_INDEX); \
mair |= MAIR_ATTR_SET(ATTR_NON_CACHEABLE, \
ATTR_NON_CACHEABLE_INDEX); \
write_mair_el##_el(mair); \ write_mair_el##_el(mair); \
\ \
/* Invalidate TLBs at the current exception level */ \ /* Invalidate TLBs at the current exception level */ \
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment