Introduce assert() macro.

Change-Id: Id087824aaa1ab6203842384f935091b145508c3c
diff --git a/inc/hf/assert.h b/inc/hf/assert.h
index 12d1ed7..e3ac758 100644
--- a/inc/hf/assert.h
+++ b/inc/hf/assert.h
@@ -17,5 +17,21 @@
 #pragma once
 
 #if !defined(__cplusplus)
+
+#include "hf/panic.h"
+
+/**
+ * Only use for exceptional cases and never if the condition could be true e.g.
+ * when processing external inputs.
+ */
+#define assert(x)                                                             \
+	do {                                                                  \
+		if (!(x)) {                                                   \
+			panic("assertion failed (%s) at %s:%d", #x, __FILE__, \
+			      __LINE__);                                      \
+		}                                                             \
+	} while (0)
+
 #define static_assert _Static_assert
+
 #endif
diff --git a/src/abort.c b/src/abort.c
index f16d2f7..8d9d723 100644
--- a/src/abort.c
+++ b/src/abort.c
@@ -16,6 +16,8 @@
 
 #include "hf/abort.h"
 
+#include "hf/dlog.h"
+
 /**
  * Causes execution to halt and prevent progress of the current and less
  * privileged software components. This should be triggered when a
@@ -28,5 +30,7 @@
 {
 	/* TODO: Block all CPUs. */
 	for (;;) {
+		/* Prevent loop being optimized away. */
+		__asm__ volatile("nop");
 	}
 }
diff --git a/src/mm.c b/src/mm.c
index 813e1b9..6de6bc6 100644
--- a/src/mm.c
+++ b/src/mm.c
@@ -495,13 +495,10 @@
 	ptable_addr_t begin = pa_addr(arch_mm_clear_pa(pa_begin));
 
 	/*
-	 * TODO: replace with assertions that the max level will be greater than
-	 * 0 and less than 255 so wrapping will not be a problem and will not
-	 * lead to subsequent overflows.
+	 * Assert condition to communicate the API constraint of mm_max_level(),
+	 * that isn't encoded in the types, to the static analyzer.
 	 */
-	if (root_level == 0 || root_level == 1) {
-		return false;
-	}
+	assert(root_level >= 2);
 
 	/* Cap end to stay within the bounds of the page table. */
 	if (end > ptable_end) {