A test with the mock arch

Change-Id: I9af804df9cf1019f0b9c5535d7d79aca28229f88
diff --git a/src/BUILD.gn b/src/BUILD.gn
index acac35f..82b12c8 100644
--- a/src/BUILD.gn
+++ b/src/BUILD.gn
@@ -46,6 +46,11 @@
   sources = [
     "fdt.c",
   ]
+
+  deps = [
+    ":common",
+    ":common_debug",
+  ]
 }
 
 source_set("memiter") {
@@ -53,3 +58,16 @@
     "memiter.c",
   ]
 }
+
+executable("unit_tests") {
+  testonly = true
+
+  sources = [
+    "fdt_test.cc",
+  ]
+
+  deps = [
+    ":fdt",
+    "//third_party:gtest_main",
+  ]
+}
diff --git a/src/arch/aarch64/inc/hf/arch/cpu.h b/src/arch/aarch64/inc/hf/arch/cpu.h
index f2fb4c8..b4d9614 100644
--- a/src/arch/aarch64/inc/hf/arch/cpu.h
+++ b/src/arch/aarch64/inc/hf/arch/cpu.h
@@ -1,6 +1,5 @@
 #pragma once
 
-#include <stdalign.h>
 #include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
diff --git a/src/arch/mock/BUILD.gn b/src/arch/mock/BUILD.gn
new file mode 100644
index 0000000..60c3428
--- /dev/null
+++ b/src/arch/mock/BUILD.gn
@@ -0,0 +1,6 @@
+# Mock implementation of putchar logs to the console.
+source_set("putchar") {
+  sources = [
+    "putchar.c",
+  ]
+}
diff --git a/src/arch/mock/inc/hf/arch/addr.h b/src/arch/mock/inc/hf/arch/addr.h
new file mode 100644
index 0000000..d8ba79d
--- /dev/null
+++ b/src/arch/mock/inc/hf/arch/addr.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <stdint.h>
+
+#define PAGE_BITS 12
+
+/* Integer type large enough to hold a physical address. */
+typedef uintptr_t uintpaddr_t;
+
+/* Integer type large enough to hold a virtual address. */
+typedef uintptr_t uintvaddr_t;
diff --git a/src/arch/mock/inc/hf/arch/cpu.h b/src/arch/mock/inc/hf/arch/cpu.h
new file mode 100644
index 0000000..9fbd041
--- /dev/null
+++ b/src/arch/mock/inc/hf/arch/cpu.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <stdint.h>
+
+struct arch_regs {
+	uint32_t r[5];
+};
+
+static inline struct cpu *cpu(void)
+{
+	/* TODO: */
+	return NULL;
+}
+
+static inline void arch_irq_disable(void)
+{
+	/* TODO */
+}
+
+static inline void arch_irq_enable(void)
+{
+	/* TODO */
+}
diff --git a/src/arch/mock/putchar.c b/src/arch/mock/putchar.c
new file mode 100644
index 0000000..3452b37
--- /dev/null
+++ b/src/arch/mock/putchar.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+#include "hf/dlog.h"
+
+void arch_putchar(char c)
+{
+	putchar(c);
+}
diff --git a/src/cpu.c b/src/cpu.c
index 217baea..cec490e 100644
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -1,5 +1,7 @@
 #include "hf/cpu.h"
 
+#include <stdalign.h>
+
 #include "hf/arch/cpu.h"
 
 #include "hf/api.h"
diff --git a/src/fdt_test.cc b/src/fdt_test.cc
new file mode 100644
index 0000000..cb0d14c
--- /dev/null
+++ b/src/fdt_test.cc
@@ -0,0 +1,68 @@
+extern "C" {
+
+#include "hf/fdt.h"
+}
+
+#include <gmock/gmock.h>
+
+using ::testing::Eq;
+
+/*
+ * /dts-v1/;
+ *
+ * / {
+ *       model = "SomeModel";
+ *       compatible = "Nothing";
+ *       #address-cells = <2>;
+ *       #size-cells = <2>;
+ *
+ *       memory@0 {
+ *           device_type = "memory";
+ *           reg = <0x00000000 0x00000000 0x00000000 0x20000000>;
+ *       };
+ *
+ *       cpus {
+ *           #address-cells = <1>;
+ *           #size-cells = <0>;
+ *       };
+ *
+ * };
+ *
+ * $ dtc --boot-cpu 0 --in-format dts --out-format dtb --out-version 17 test.dts
+ * | xxd
+ */
+
+static const uint8_t test_dtb[] = {
+	0xd0, 0x0d, 0xfe, 0xed, 0x00, 0x00, 0x01, 0x44, 0x00, 0x00, 0x00, 0x38,
+	0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x11,
+	0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+	0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0a,
+	0x00, 0x00, 0x00, 0x00, 0x53, 0x6f, 0x6d, 0x65, 0x4d, 0x6f, 0x64, 0x65,
+	0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x06, 0x4e, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x00,
+	0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11,
+	0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+	0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
+	0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x40, 0x30, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2c,
+	0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+	0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x63, 0x70, 0x75, 0x73,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+	0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
+	0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09,
+	0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x00, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74,
+	0x69, 0x62, 0x6c, 0x65, 0x00, 0x23, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73,
+	0x73, 0x2d, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x00, 0x23, 0x73, 0x69, 0x7a,
+	0x65, 0x2d, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x00, 0x64, 0x65, 0x76, 0x69,
+	0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x00, 0x72, 0x65, 0x67, 0x00};
+
+TEST(fdt, total_size)
+{
+	EXPECT_THAT(fdt_total_size((struct fdt_header *)&test_dtb[0]),
+		    Eq(sizeof(test_dtb)));
+}