refactor(mm): replace max level with root level
The name `mm_max_level()` is misleading, since it is not actually the
maximum value that the level can be (since the root level is the "max"
level plus 1).
The use of `mm_max_level()` in `mm.c` was also inconsistent: sometimes
they call `mm_max_level() + 1` to calculate the root level, sometimes
they just pass `mm_max_level()` to recursive subcalls to process the
next level down. This made it hard to know when a plus or minus one was
needed and so ended up introducing off-by-one errors. Now, you always
start at `mm_root_level()` and pass `root_level - 1` to recursive
subcalls.
Also add explanatory comments explaining the level-related arithmetic.
Change-Id: I7b701d6d2c908db03c2853a008565126890e7959
Signed-off-by: Karl Meakin <karl.meakin@arm.com>
diff --git a/inc/hf/mm.h b/inc/hf/mm.h
index a307d5a..fa47f15 100644
--- a/inc/hf/mm.h
+++ b/inc/hf/mm.h
@@ -19,6 +19,23 @@
typedef uint32_t mm_mode_t;
typedef uint64_t mm_attr_t;
+
+/**
+ * The level of a page table entry (i.e. how deep into the recursive tree
+ * structure it is). See also Arm ARM, table D8-14.
+ *
+ * - `level == 4`: table entries (root)
+ * - `level == 3`: table or block entries
+ * - `level == 2`: table or block entries
+ * - `level == 1`: table or block entries
+ * - `level == 0`: page entries
+ *
+ * NOTE: The Arm ARM uses levels in the opposite order to our code: in the Arm
+ * ARM, levels start at 0 (or -1 if 52 bits of PA are used, but that is not
+ * supported by Hafnium) and page entries are at level 3. We go in the opposite
+ * direction: levels start at 3 or 4 and page entries are at level 0. This is
+ * because it makes the arithmetic and bit manipulation easier.
+ */
typedef uint8_t mm_level_t;
typedef uint16_t mm_asid_t;