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/src/fdt.c b/src/fdt.c
index 0ba1177..d9cd71d 100644
--- a/src/fdt.c
+++ b/src/fdt.c
@@ -16,8 +16,10 @@
#include "hf/fdt.h"
+#include <stdalign.h>
#include <stdint.h>
+#include "hf/check.h"
#include "hf/dlog.h"
#include "hf/std.h"
@@ -56,6 +58,8 @@
#define FDT_VERSION 17
#define FDT_MAGIC 0xd00dfeed
+#define FDT_TOKEN_ALIGNMENT sizeof(uint32_t)
+
static void fdt_tokenizer_init(struct fdt_tokenizer *t, const char *strs,
const char *begin, const char *end)
{
@@ -66,7 +70,7 @@
static void fdt_tokenizer_align(struct fdt_tokenizer *t)
{
- t->cur = (char *)align_up(t->cur, 4);
+ t->cur = (char *)align_up(t->cur, FDT_TOKEN_ALIGNMENT);
}
static bool fdt_tokenizer_uint32(struct fdt_tokenizer *t, uint32_t *res)
@@ -276,6 +280,43 @@
return false;
}
+/**
+ * Helper method for parsing 32/64-bit uints from FDT data.
+ */
+bool fdt_parse_number(const char *data, uint32_t size, uint64_t *value)
+{
+ union {
+ volatile uint64_t v;
+ char a[8];
+ } t;
+
+ /* FDT values should be aligned to 32-bit boundary. */
+ CHECK(is_aligned(data, FDT_TOKEN_ALIGNMENT));
+
+ switch (size) {
+ case sizeof(uint32_t):
+ /*
+ * Assert that `data` is already sufficiently aligned to
+ * dereference as uint32_t. We cannot use static_assert()
+ * because alignof() is not an expression under ISO C11.
+ */
+ CHECK(alignof(uint32_t) <= FDT_TOKEN_ALIGNMENT);
+ *value = be32toh(*(uint32_t *)data);
+ return true;
+ case sizeof(uint64_t):
+ /*
+ * ARMv8 requires `data` to be realigned to 64-bit boundary
+ * to dereference as uint64_t. May not be needed on other
+ * architectures.
+ */
+ memcpy_s(t.a, sizeof(t.a), data, sizeof(uint64_t));
+ *value = be64toh(t.v);
+ return true;
+ default:
+ return false;
+ }
+}
+
bool fdt_first_child(struct fdt_node *node, const char **child_name)
{
struct fdt_tokenizer t;
@@ -333,7 +374,7 @@
return false;
}
-void fdt_dump(struct fdt_header *hdr)
+void fdt_dump(const struct fdt_header *hdr)
{
uint32_t token;
size_t depth = 0;