feat(rmm): rename and separate primitives
This patch describes the encodings of s2tte types, renames
"invalid_ns" to "unassigned_ns" and "valid_ns" to "assigned_ns"
to follow the naming pattern of other types of s2ttes.
The encoding of unassigned_ns (former invalid_ns) now differs from
the encoding of unassigned_empty so RMI_REALM_CREATE must do
the proper initialization of the starting level S2 TTs. So far the
corectness of the code was based on the assumption that the
encodings for unassigned hipas and empty ripas were zero.
Signed-off-by: AlexeiFedorov <Alexei.Fedorov@arm.com>
Change-Id: Iea282baa4f367c88664406c86ad6b1569d4e89e6
diff --git a/lib/realm/include/table.h b/lib/realm/include/table.h
index 7a8f367..ae3cc51 100644
--- a/lib/realm/include/table.h
+++ b/lib/realm/include/table.h
@@ -35,10 +35,10 @@
unsigned long s2tte_create_ripas(enum ripas ripas);
unsigned long s2tte_create_unassigned(enum ripas ripas);
+unsigned long s2tte_create_unassigned_ns(void);
unsigned long s2tte_create_destroyed(void);
unsigned long s2tte_create_assigned_empty(unsigned long pa, long level);
unsigned long s2tte_create_valid(unsigned long pa, long level);
-unsigned long s2tte_create_invalid_ns(void);
unsigned long s2tte_create_valid_ns(unsigned long s2tte, long level);
unsigned long s2tte_create_table(unsigned long pa, long level);
@@ -46,6 +46,7 @@
unsigned long host_ns_s2tte(unsigned long s2tte, long level);
bool s2tte_is_unassigned(unsigned long s2tte);
+bool s2tte_is_unassigned_ns(unsigned long s2tte);
bool s2tte_is_destroyed(unsigned long s2tte);
bool s2tte_is_assigned(unsigned long s2tte, long level);
bool s2tte_is_valid(unsigned long s2tte, long level);
@@ -55,6 +56,7 @@
enum ripas s2tte_get_ripas(unsigned long s2tte);
void s2tt_init_unassigned(unsigned long *s2tt, enum ripas ripas);
+void s2tt_init_unassigned_ns(unsigned long *s2tt);
void s2tt_init_destroyed(unsigned long *s2tt);
void s2tt_init_assigned_empty(unsigned long *s2tt, unsigned long pa, long level);
void s2tt_init_valid(unsigned long *s2tt, unsigned long pa, long level);
@@ -72,6 +74,7 @@
void invalidate_pages_in_block(const struct realm_s2_context *ctx, unsigned long addr);
bool table_is_unassigned_block(unsigned long *table, enum ripas *ripas);
+bool table_is_unassigned_ns_block(unsigned long *table);
bool table_is_destroyed_block(unsigned long *table);
bool table_maps_assigned_block(unsigned long *table, long level);
diff --git a/lib/realm/src/s2tt.c b/lib/realm/src/s2tt.c
index 2082716..c73f57b 100644
--- a/lib/realm/src/s2tt.c
+++ b/lib/realm/src/s2tt.c
@@ -74,38 +74,32 @@
#define S2TTE_INVALID 0
/*
- * The type of an S2TTE is one of the following:
+ * The type of stage 2 translation table entry (s2tte) is defined by:
+ * 1. Table level where it resides
+ * 2. DESC_TYPE field[1:0]
+ * 4. HIPAS field [5:2]
+ * 4. RIPAS field [6]
+ * 5. NS field [55]
*
- * - Invalid
- * - Valid page
- * - Valid block
- * - Table
- *
- * Within an invalid S2TTE for a Protected IPA, architecturally RES0 bits are
- * used to encode the HIPAS and RIPAS.
- *
- * A valid S2TTE for a Protected IPA implies HIPAS=ASSIGNED and RIPAS=RAM.
- *
- * An invalid S2TTE for an Unprotected IPA implies HIPAS=INVALID_NS.
- * A valid S2TTE for an Unprotected IPA implies HIPAS=VALID_NS.
- *
- * The following table defines the mapping from a (HIPAS, RIPAS) tuple to the
- * value of the S2TTE.
- *
- * ------------------------------------------------------------------------------
- * IPA HIPAS RIPAS S2TTE value
- * ==============================================================================
- * Protected UNASSIGNED EMPTY (S2TTE_INVALID_HIPAS_UNASSIGNED |
- * S2TTE_INVALID_RIPAS_EMPTY)
- * Protected UNASSIGNED RAM (S2TTE_INVALID_HIPAS_UNASSIGNED |
- * S2TTE_INVALID_RIPAS_RAM)
- * Protected ASSIGNED EMPTY (S2TTE_INVALID_HIPAS_ASSIGNED |
- * S2TTE_INVALID_RIPAS_EMPTY)
- * Protected ASSIGNED RAM Valid page / block with NS=0
- * Protected DESTROYED * S2TTE_INVALID_DESTROYED
- * Unprotected INVALID_NS N/A S2TTE_INVALID_UNPROTECTED
- * Unprotected VALID_NS N/A Valid page / block with NS=1
- * ------------------------------------------------------------------------------
+ * s2tte type level DESC_TYPE[1:0] HIPAS[5:2] RIPAS[6] NS OA alignment
+ * =============================================================================
+ * unassigned_empty any invalid[0] unassigned[0] empty[0] 0 n/a
+ * -----------------------------------------------------------------------------
+ * unassigned_ram any invalid[0] unassigned[0] ram[1] 0 n/a
+ * -----------------------------------------------------------------------------
+ * assigned_empty 2,3 invalid[0] assigned[1] empty[0] 0 to level
+ * -----------------------------------------------------------------------------
+ * assigned_ram 3 page[1] n/a n/a 0 to level
+ * 2 block[3] n/a n/a 0 to level
+ * -----------------------------------------------------------------------------
+ * destroyed any invalid[0] destroyed[2] n/a 0 n/a
+ * =============================================================================
+ * unassigned_ns any invalid[0] unassigned[0] n/a 1 n/a
+ * -----------------------------------------------------------------------------
+ * assigned_ns 3 page[1] n/a n/a 1 to level
+ * 2 block[3] n/a n/a 1 to level
+ * =============================================================================
+ * table <=2 table[1] n/a n/a n/a to 4K
*/
#define S2TTE_INVALID_HIPAS_SHIFT 2
@@ -440,11 +434,12 @@
}
/*
- * Creates an invalid s2tte with HIPAS=INVALID_NS.
+ * Creates an unassigned_ns s2tte.
*/
-unsigned long s2tte_create_invalid_ns(void)
+unsigned long s2tte_create_unassigned_ns(void)
{
- return S2TTE_INVALID_UNPROTECTED;
+ return S2TTE_NS | S2TTE_INVALID_HIPAS_UNASSIGNED |
+ S2TTE_INVALID_UNPROTECTED;
}
/*
@@ -542,10 +537,26 @@
}
/*
- * Returns true if @s2tte has HIPAS=UNASSIGNED or HIPAS=INVALID_NS.
+ * Returns true if @s2tte has HIPAS=UNASSIGNED.
*/
bool s2tte_is_unassigned(unsigned long s2tte)
{
+ if ((s2tte & S2TTE_NS) != 0UL) {
+ return false;
+ }
+
+ return s2tte_has_hipas(s2tte, S2TTE_INVALID_HIPAS_UNASSIGNED);
+}
+
+/*
+ * Returns true if @s2tte is unassigned_ns.
+ */
+bool s2tte_is_unassigned_ns(unsigned long s2tte)
+{
+ if ((s2tte & S2TTE_NS) == 0UL) {
+ return false;
+ }
+
return s2tte_has_hipas(s2tte, S2TTE_INVALID_HIPAS_UNASSIGNED);
}
@@ -659,6 +670,21 @@
}
/*
+ * Populates @s2tt with unassigned_ns s2ttes.
+ *
+ * The granule is populated before it is made a table,
+ * hence, don't use s2tte_write for access.
+ */
+void s2tt_init_unassigned_ns(unsigned long *s2tt)
+{
+ for (unsigned int i = 0U; i < S2TTES_PER_S2TT; i++) {
+ s2tt[i] = s2tte_create_unassigned_ns();
+ }
+
+ dsb(ish);
+}
+
+/*
* Populates @s2tt with s2ttes which have HIPAS=DESTROYED.
*
* The granule is populated before it is made a table,
@@ -813,6 +839,14 @@
}
/*
+ * Returns true if all s2ttes in @table are unassigned_ns
+ */
+bool table_is_unassigned_ns_block(unsigned long *table)
+{
+ return __table_is_uniform_block(table, s2tte_is_unassigned_ns, NULL);
+}
+
+/*
* Returns true if all s2ttes in @table have HIPAS=DESTROYED.
*/
bool table_is_destroyed_block(unsigned long *table)