Introduce a DT-based manifest

These are first steps towards a new manifest format. A new "device_tree"
build target is introduced to compile DTS files to DTB, and
`generate_initrd.py` now does not produce a "vms.txt" file. Instead
"initrd" targets are expected to provide a path to a DTS manifest in the
format:

    /dts-v1/;

    / {
      hypervisor {
        vm1 {
	  debug_name = "primary";
	};

	vm2 {
	  debug_name = "secondary1";
	  kernel_filename = "filename";
	  vcpu_count = <N>;
          mem_size = <M>;
	};

	...
      };
    };

The information provided in the manifest matches "vms.txt".

Bug: 117551352
Test: manifest_test.cc
Test: used by hftest
Change-Id: I6b70bd44d2b110c4f7a6b971018c834084b6d8c4
diff --git a/inc/hf/fdt.h b/inc/hf/fdt.h
index 2f55306..8f72856 100644
--- a/inc/hf/fdt.h
+++ b/inc/hf/fdt.h
@@ -29,13 +29,14 @@
 
 size_t fdt_header_size(void);
 uint32_t fdt_total_size(struct fdt_header *hdr);
-void fdt_dump(struct fdt_header *hdr);
+void fdt_dump(const struct fdt_header *hdr);
 bool fdt_root_node(struct fdt_node *node, const struct fdt_header *hdr);
 bool fdt_find_child(struct fdt_node *node, const char *child);
 bool fdt_first_child(struct fdt_node *node, const char **child_name);
 bool fdt_next_sibling(struct fdt_node *node, const char **sibling_name);
 bool fdt_read_property(const struct fdt_node *node, const char *name,
 		       const char **buf, uint32_t *size);
+bool fdt_parse_number(const char *data, uint32_t size, uint64_t *value);
 
 void fdt_add_mem_reservation(struct fdt_header *hdr, uint64_t addr,
 			     uint64_t len);
diff --git a/inc/hf/manifest.h b/inc/hf/manifest.h
new file mode 100644
index 0000000..37f26f3
--- /dev/null
+++ b/inc/hf/manifest.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2019 The Hafnium Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "hf/memiter.h"
+#include "hf/spci.h"
+
+/**
+ * Holds information about one of the VMs described in the manifest.
+ */
+struct manifest_vm {
+	/* Properties defined for both primary and secondary VMs. */
+	struct memiter debug_name;
+
+	/* Properties specific to secondary VMs. */
+	struct {
+		struct memiter kernel_filename;
+		uint64_t mem_size;
+		spci_vcpu_count_t vcpu_count;
+	} secondary;
+};
+
+/**
+ * Hafnium manifest parsed from FDT.
+ */
+struct manifest {
+	spci_vm_count_t num_vms;
+	struct manifest_vm vm[MAX_VMS];
+};
+
+enum manifest_return_code {
+	MANIFEST_SUCCESS = 0,
+	MANIFEST_ERROR_CORRUPTED_FDT,
+	MANIFEST_ERROR_NO_ROOT_FDT_NODE,
+	MANIFEST_ERROR_NO_HYPERVISOR_FDT_NODE,
+	MANIFEST_ERROR_RESERVED_VM_ID,
+	MANIFEST_ERROR_NO_PRIMARY_VM,
+	MANIFEST_ERROR_TOO_MANY_VMS,
+	MANIFEST_ERROR_PROPERTY_NOT_FOUND,
+	MANIFEST_ERROR_MALFORMED_STRING,
+	MANIFEST_ERROR_MALFORMED_INTEGER,
+	MANIFEST_ERROR_INTEGER_OVERFLOW,
+};
+
+enum manifest_return_code manifest_init(struct manifest *manifest,
+					struct memiter *fdt);
+
+const char *manifest_strerror(enum manifest_return_code ret_code);
diff --git a/inc/hf/memiter.h b/inc/hf/memiter.h
index d5dbf33..a44ffef 100644
--- a/inc/hf/memiter.h
+++ b/inc/hf/memiter.h
@@ -29,4 +29,8 @@
 bool memiter_parse_uint(struct memiter *it, uint64_t *value);
 bool memiter_parse_str(struct memiter *it, struct memiter *str);
 bool memiter_iseq(const struct memiter *it, const char *str);
+void memiter_dlog_str(struct memiter *it);
 bool memiter_advance(struct memiter *it, size_t v);
+
+const void *memiter_base(struct memiter *it);
+size_t memiter_size(struct memiter *it);