refactor(mm): add `arch_mm_pte_type`
Add an `mm_pte_type` enum, and rewrite the
`arch_mm_pte_is_{absent,present,valid,block}` functions in terms of the
`arch_mm_pte_type` function.
In future commits, chains of if-else blocks can be replaced by a
`switch` on the enum.
Change-Id: I7434b3571cbc4303f13e54dae7fad1608c990b2a
Signed-off-by: Karl Meakin <karl.meakin@arm.com>
diff --git a/inc/hf/arch/mm.h b/inc/hf/arch/mm.h
index aff344a..d871bf6 100644
--- a/inc/hf/arch/mm.h
+++ b/inc/hf/arch/mm.h
@@ -16,15 +16,6 @@
#include "vmapi/hf/ffa.h"
-/*
- * A page table entry (PTE) will take one of the following forms:
- *
- * 1. absent : There is no mapping.
- * 2. invalid block : Represents a block that is not in the address space.
- * 3. valid block : Represents a block that is in the address space.
- * 4. table : Represents a reference to a table of PTEs.
- */
-
/**
* Creates an absent PTE.
*/
@@ -40,34 +31,67 @@
*/
pte_t arch_mm_block_pte(mm_level_t level, paddr_t pa, mm_attr_t attrs);
+enum mm_pte_type arch_mm_pte_type(pte_t pte, mm_level_t level);
+
/**
* Checks whether a block is allowed at the given level of the page table.
*/
bool arch_mm_is_block_allowed(mm_level_t level);
+static inline bool arch_mm_pte_is_absent(pte_t pte, mm_level_t level)
+{
+ return arch_mm_pte_type(pte, level) == PTE_TYPE_ABSENT;
+}
+
/**
* Determines if a PTE is present i.e. it contains information and therefore
* needs to exist in the page table. Any non-absent PTE is present.
*/
-bool arch_mm_pte_is_present(pte_t pte, mm_level_t level);
+static inline bool arch_mm_pte_is_present(pte_t pte, mm_level_t level)
+{
+ return !arch_mm_pte_is_absent(pte, level);
+}
/**
* Determines if a PTE is valid i.e. it can affect the address space. Tables and
* valid blocks fall into this category. Invalid blocks do not as they hold
* information about blocks that are not in the address space.
*/
-bool arch_mm_pte_is_valid(pte_t pte, mm_level_t level);
+static inline bool arch_mm_pte_is_valid(pte_t pte, mm_level_t level)
+{
+ switch (arch_mm_pte_type(pte, level)) {
+ case PTE_TYPE_ABSENT:
+ case PTE_TYPE_INVALID_BLOCK:
+ return false;
+ case PTE_TYPE_VALID_BLOCK:
+ case PTE_TYPE_TABLE:
+ return true;
+ }
+}
/**
* Determines if a PTE is a block and represents an address range, valid or
* invalid.
*/
-bool arch_mm_pte_is_block(pte_t pte, mm_level_t level);
+static inline bool arch_mm_pte_is_block(pte_t pte, mm_level_t level)
+{
+ switch (arch_mm_pte_type(pte, level)) {
+ case PTE_TYPE_ABSENT:
+ case PTE_TYPE_TABLE:
+ return false;
+ case PTE_TYPE_INVALID_BLOCK:
+ case PTE_TYPE_VALID_BLOCK:
+ return true;
+ }
+}
/**
* Determines if a PTE represents a reference to a table of PTEs.
*/
-bool arch_mm_pte_is_table(pte_t pte, mm_level_t level);
+static inline bool arch_mm_pte_is_table(pte_t pte, mm_level_t level)
+{
+ return arch_mm_pte_type(pte, level) == PTE_TYPE_TABLE;
+}
/**
* Clears the bits of an address that are ignored by the page table. In effect,
@@ -91,7 +115,7 @@
mm_attr_t arch_mm_pte_attrs(pte_t pte, mm_level_t level);
/**
- * Merges the attributes of a block into those of its containing table.
+ * Merges the attributes of a block into those of its parent table.
*/
mm_attr_t arch_mm_combine_table_entry_attrs(mm_attr_t table_attrs,
mm_attr_t block_attrs);
diff --git a/inc/hf/mm.h b/inc/hf/mm.h
index 6023817..a307d5a 100644
--- a/inc/hf/mm.h
+++ b/inc/hf/mm.h
@@ -22,6 +22,22 @@
typedef uint8_t mm_level_t;
typedef uint16_t mm_asid_t;
+/*
+ * A page table entry (PTE) will take one of the following forms:
+ *
+ * 1. absent : There is no mapping.
+ * 2. invalid block : Represents a block that is not in the address space.
+ * 3. valid block : Represents a block that is in the address space.
+ * 4. table : Represents a reference to a table of PTEs.
+ * See Arm ARM, D8.3 (Translation table descriptor formats).
+ */
+enum mm_pte_type {
+ PTE_TYPE_ABSENT,
+ PTE_TYPE_INVALID_BLOCK,
+ PTE_TYPE_VALID_BLOCK,
+ PTE_TYPE_TABLE,
+};
+
/* Keep macro alignment */
/* clang-format off */