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 */