Move headers under the hf directory.

This helps distinguish local headers from the more official headers.

Change-Id: I535c1b44081b9d60ba63666cd1ad514aaaf2c68d
diff --git a/inc/hf/addr.h b/inc/hf/addr.h
new file mode 100644
index 0000000..1d4ec39
--- /dev/null
+++ b/inc/hf/addr.h
@@ -0,0 +1,122 @@
+#ifndef _ADDR_H
+#define _ADDR_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "hf/arch/addr.h"
+
+/* An opaque type for a physical address. */
+typedef struct {
+	uintpaddr_t pa;
+} paddr_t;
+
+/* An opaque type for an intermediate physical address. */
+typedef struct {
+	uintpaddr_t ipa;
+} ipaddr_t;
+
+/* An opaque type for a virtual address. */
+typedef struct {
+	uintvaddr_t va;
+} vaddr_t;
+
+/**
+ * Initializes a physical address.
+ */
+static inline paddr_t pa_init(uintpaddr_t p)
+{
+	return (paddr_t){.pa = p};
+}
+
+/**
+ * Extracts the absolute physical address.
+ */
+static inline uintpaddr_t pa_addr(paddr_t pa)
+{
+	return pa.pa;
+}
+
+/**
+ * Initializes an intermeditate physical address.
+ */
+static inline ipaddr_t ipa_init(uintvaddr_t v)
+{
+	return (ipaddr_t){.ipa = v};
+}
+
+/**
+ * Extracts the absolute intermediate physical address.
+ */
+static inline uintpaddr_t ipa_addr(ipaddr_t ipa)
+{
+	return ipa.ipa;
+}
+
+/**
+ * Initializes a virtual address.
+ */
+static inline vaddr_t va_init(uintvaddr_t v)
+{
+	return (vaddr_t){.va = v};
+}
+
+/**
+ * Extracts the absolute virtual address.
+ */
+static inline uintvaddr_t va_addr(vaddr_t va)
+{
+	return va.va;
+}
+
+/**
+ * Advances a physical address.
+ */
+static inline paddr_t pa_add(paddr_t pa, size_t n)
+{
+	return pa_init(pa_addr(pa) + n);
+}
+
+/**
+ * Casts a physical address to a virtual address.
+ */
+static inline vaddr_t va_from_pa(paddr_t pa)
+{
+	return va_init(pa_addr(pa));
+}
+
+/**
+ * Casts a physical address to an intermediate physical address.
+ */
+static inline ipaddr_t ipa_from_pa(paddr_t pa)
+{
+	return ipa_init(pa_addr(pa));
+}
+
+/**
+ * Casts a virtual address to a physical address.
+ */
+static inline paddr_t pa_from_va(vaddr_t va)
+{
+	return pa_init(va_addr(va));
+}
+
+/**
+ * Casts a pointer to a virtual address.
+ */
+static inline vaddr_t va_from_ptr(const void *p)
+{
+	return (vaddr_t){.va = (uintvaddr_t)p};
+}
+
+/**
+ * Casts a virtual address to a pointer. Only use when the virtual address is
+ * mapped for the calling context.
+ * TODO: check the mapping for a range and return a memiter?
+ */
+static inline void *ptr_from_va(vaddr_t va)
+{
+	return (void *)va_addr(va);
+}
+
+#endif /* _ADDR_H */
diff --git a/inc/hf/alloc.h b/inc/hf/alloc.h
new file mode 100644
index 0000000..4570b1a
--- /dev/null
+++ b/inc/hf/alloc.h
@@ -0,0 +1,12 @@
+#ifndef _ALLOC_H
+#define _ALLOC_H
+
+#include <stddef.h>
+
+void halloc_init(size_t base, size_t size);
+void *halloc(size_t size);
+void hfree(void *ptr);
+void *halloc_aligned(size_t size, size_t align);
+void *halloc_aligned_nosync(size_t size, size_t align);
+
+#endif /* _ALLOC_H */
diff --git a/inc/hf/api.h b/inc/hf/api.h
new file mode 100644
index 0000000..0009ac8
--- /dev/null
+++ b/inc/hf/api.h
@@ -0,0 +1,26 @@
+#ifndef _API_H
+#define _API_H
+
+#include "hf/cpu.h"
+#include "hf/vm.h"
+
+/* TODO: Can we hide these? */
+extern struct vm secondary_vm[MAX_VMS];
+extern uint32_t secondary_vm_count;
+extern struct vm primary_vm;
+
+struct vcpu *api_switch_to_primary(size_t primary_retval,
+				   enum vcpu_state secondary_state);
+
+int32_t api_vm_get_count(void);
+int32_t api_vcpu_get_count(uint32_t vm_idx);
+int32_t api_vcpu_run(uint32_t vm_idx, uint32_t vcpu_idx, struct vcpu **next);
+struct vcpu *api_wait_for_interrupt(void);
+int32_t api_vm_configure(ipaddr_t send, ipaddr_t recv);
+
+int32_t api_rpc_request(uint32_t vm_idx, size_t size);
+int32_t api_rpc_read_request(bool block, struct vcpu **next);
+int32_t api_rpc_reply(size_t size, bool ack, struct vcpu **next);
+int32_t api_rpc_ack(void);
+
+#endif /* _API_H */
diff --git a/inc/hf/arch.h b/inc/hf/arch.h
new file mode 100644
index 0000000..fcdead1
--- /dev/null
+++ b/inc/hf/arch.h
@@ -0,0 +1,8 @@
+#ifndef _ARCH_H
+#define _ARCH_H
+
+#include "hf/cpu.h"
+
+void arch_putchar(char c);
+
+#endif /* _ARCH_H */
diff --git a/inc/hf/boot_params.h b/inc/hf/boot_params.h
new file mode 100644
index 0000000..4841654
--- /dev/null
+++ b/inc/hf/boot_params.h
@@ -0,0 +1,26 @@
+#ifndef _BOOT_PARAMS_H
+#define _BOOT_PARAMS_H
+
+#include <stdbool.h>
+
+#include "hf/mm.h"
+
+struct boot_params {
+	paddr_t mem_begin;
+	paddr_t mem_end;
+	paddr_t initrd_begin;
+	paddr_t initrd_end;
+	size_t kernel_arg;
+};
+
+struct boot_params_update {
+	paddr_t reserved_begin;
+	paddr_t reserved_end;
+	paddr_t initrd_begin;
+	paddr_t initrd_end;
+};
+
+bool plat_get_boot_params(struct boot_params *p);
+bool plat_update_boot_params(struct boot_params_update *p);
+
+#endif /* _BOOT_PARAMS_H */
diff --git a/inc/hf/cpio.h b/inc/hf/cpio.h
new file mode 100644
index 0000000..de33ba6
--- /dev/null
+++ b/inc/hf/cpio.h
@@ -0,0 +1,12 @@
+#ifndef _CPIO_H
+#define _CPIO_H
+
+#include <stdbool.h>
+#include <stddef.h>
+
+#include "hf/memiter.h"
+
+bool cpio_next(struct memiter *iter, const char **name, const void **contents,
+	       size_t *size);
+
+#endif /* _CPIO_H */
diff --git a/inc/hf/cpu.h b/inc/hf/cpu.h
new file mode 100644
index 0000000..a779679
--- /dev/null
+++ b/inc/hf/cpu.h
@@ -0,0 +1,65 @@
+#ifndef _CPU_H
+#define _CPU_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "hf/arch/cpu.h"
+
+#include "hf/addr.h"
+#include "hf/spinlock.h"
+
+enum vcpu_state {
+	vcpu_state_off,
+	vcpu_state_ready,
+	vcpu_state_running,
+	vcpu_state_blocked_rpc,
+	vcpu_state_blocked_interrupt,
+};
+
+struct vcpu {
+	struct spinlock lock;
+	enum vcpu_state state;
+	struct vm *vm;
+	struct vcpu *rpc_next;
+	struct arch_regs regs;
+};
+
+/* TODO: Update alignment such that cpus are in different cache lines. */
+struct cpu {
+	/* CPU identifier. Doesn't have to be contiguous. */
+	size_t id;
+
+	struct vcpu *current;
+
+	/* Pointer to bottom of the stack. */
+	void *stack_bottom;
+
+	/*
+	 * Enabling/disabling irqs are counted per-cpu. They are enabled when
+	 * the count is zero, and disabled when it's non-zero.
+	 */
+	uint32_t irq_disable_count;
+
+	struct spinlock lock;
+
+	/* Determines whether or not the cpu is currently on. */
+	bool is_on;
+};
+
+void cpu_module_init(void);
+
+void cpu_init(struct cpu *c);
+size_t cpu_index(struct cpu *c);
+void cpu_irq_enable(struct cpu *c);
+void cpu_irq_disable(struct cpu *c);
+bool cpu_on(struct cpu *c, ipaddr_t entry, size_t arg);
+void cpu_off(struct cpu *c);
+struct cpu *cpu_find(size_t id);
+
+void vcpu_init(struct vcpu *vcpu, struct vm *vm);
+void vcpu_on(struct vcpu *vcpu);
+void vcpu_off(struct vcpu *vcpu);
+
+#endif /* _CPU_H */
diff --git a/inc/hf/decl_offsets.h b/inc/hf/decl_offsets.h
new file mode 100644
index 0000000..ede3ad7
--- /dev/null
+++ b/inc/hf/decl_offsets.h
@@ -0,0 +1,35 @@
+#ifndef _DECL_OFFSETS_H
+#define _DECL_OFFSETS_H
+
+#ifdef GEN_OFFSETS
+
+/* When generating offsets, create constants which can be extracted from the
+ * generated assembly. */
+
+#define DECL(name, type, field) \
+	const size_t DEFINE_OFFSET__##name = offsetof(type, field)
+
+#define DECL_SIZE(name, type) const size_t DEFINE_OFFSET__name = sizeof(type)
+
+#else /* GEN_OFFSETS */
+
+/* When not generating offsets, validate that the extracted values are as
+ * expected. */
+
+#include <assert.h>
+
+#define DECL(name, type, field) DECL_1(#name, name, offsetof(type, field))
+#define DECL_1(name, actual, expected)                       \
+	static_assert((actual) == (expected),                \
+		      "Offset " name " should be " #expected \
+		      " and not " #actual)
+
+#define DECL_SIZE(name, type) DECL_SIZE_1(#name, name, sizeof(type))
+#define DECL_SIZE_1(name, actual, expected)                 \
+	static_assert((actual) == (expected),               \
+		      "Size " #name " should be " #expected \
+		      " and not" #actual)
+
+#endif /* GEN_OFFSETS */
+
+#endif /* _DECL_OFFSETS_H */
diff --git a/inc/hf/dlog.h b/inc/hf/dlog.h
new file mode 100644
index 0000000..1d514a3
--- /dev/null
+++ b/inc/hf/dlog.h
@@ -0,0 +1,14 @@
+#ifndef _DLOG_H
+#define _DLOG_H
+
+#include <stdarg.h>
+
+#if DEBUG
+void dlog(const char *fmt, ...);
+void vdlog(const char *fmt, va_list args);
+#else
+#define dlog(...)
+#define vdlog(fmt, args)
+#endif
+
+#endif /* _DLOG_H */
diff --git a/inc/hf/fdt.h b/inc/hf/fdt.h
new file mode 100644
index 0000000..147c0dc
--- /dev/null
+++ b/inc/hf/fdt.h
@@ -0,0 +1,28 @@
+#ifndef _FDT_H
+#define _FDT_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+struct fdt_node {
+	const struct fdt_header *hdr;
+	const char *begin;
+	const char *end;
+	const char *strs;
+};
+
+size_t fdt_header_size(void);
+size_t fdt_total_size(struct fdt_header *hdr);
+void fdt_dump(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);
+
+void fdt_add_mem_reservation(struct fdt_header *hdr, uint64_t addr,
+			     uint64_t len);
+
+#endif /* _FDT_H */
diff --git a/inc/hf/fdt_handler.h b/inc/hf/fdt_handler.h
new file mode 100644
index 0000000..4d3fa8f
--- /dev/null
+++ b/inc/hf/fdt_handler.h
@@ -0,0 +1,11 @@
+#ifndef _FDT_HANDLER_H
+#define _FDT_HANDLER_H
+
+#include "hf/boot_params.h"
+#include "hf/fdt.h"
+#include "hf/mm.h"
+
+bool fdt_get_boot_params(paddr_t fdt_addr, struct boot_params *p);
+bool fdt_patch(paddr_t fdt_addr, struct boot_params_update *p);
+
+#endif /* _FDT_HANDLER_H */
diff --git a/inc/hf/load.h b/inc/hf/load.h
new file mode 100644
index 0000000..ba67f38
--- /dev/null
+++ b/inc/hf/load.h
@@ -0,0 +1,16 @@
+#ifndef _LOAD_H
+#define _LOAD_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "hf/cpio.h"
+#include "hf/memiter.h"
+#include "hf/mm.h"
+
+bool load_primary(const struct memiter *cpio, size_t kernel_arg,
+		  struct memiter *initrd);
+bool load_secondary(const struct memiter *cpio, paddr_t mem_begin,
+		    paddr_t *mem_end);
+
+#endif /* _LOAD_H */
diff --git a/inc/hf/memiter.h b/inc/hf/memiter.h
new file mode 100644
index 0000000..9e066da
--- /dev/null
+++ b/inc/hf/memiter.h
@@ -0,0 +1,19 @@
+#ifndef _MEMITER_H
+#define _MEMITER_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+struct memiter {
+	const char *next;
+	const char *limit;
+};
+
+void memiter_init(struct memiter *it, const void *data, size_t size);
+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);
+bool memiter_advance(struct memiter *it, size_t v);
+
+#endif /* _MEMITER_H */
diff --git a/inc/hf/mm.h b/inc/hf/mm.h
new file mode 100644
index 0000000..b62133c
--- /dev/null
+++ b/inc/hf/mm.h
@@ -0,0 +1,63 @@
+#ifndef _MM_H
+#define _MM_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "hf/arch/mm.h"
+
+#include "hf/addr.h"
+
+struct mm_ptable {
+	paddr_t table;
+	uint32_t id;
+};
+
+#define PAGE_SIZE (1 << PAGE_BITS)
+
+/* The following are arch-independent page mapping modes. */
+#define MM_MODE_R 0x01 /* read */
+#define MM_MODE_W 0x02 /* write */
+#define MM_MODE_X 0x04 /* execute */
+#define MM_MODE_D 0x08 /* device */
+
+/*
+ * This flag indicates that memory allocation must not use locks. This is
+ * relevant in systems where interlocked operations are only available after
+ * virtual memory is enabled.
+ */
+#define MM_MODE_NOSYNC 0x10
+
+/*
+ * This flag indicates that the mapping is intended to be used in a first
+ * stage translation table, which might have different encodings for the
+ * attribute bits than the second stage table.
+ */
+#define MM_MODE_STAGE1 0x20
+
+/*
+ * This flag indicates that no TLB invalidations should be issued for the
+ * changes in the page table.
+ */
+#define MM_MODE_NOINVALIDATE 0x40
+
+bool mm_ptable_init(struct mm_ptable *t, uint32_t id, int mode);
+void mm_ptable_dump(struct mm_ptable *t, int mode);
+void mm_ptable_defrag(struct mm_ptable *t, int mode);
+bool mm_ptable_unmap_hypervisor(struct mm_ptable *t, int mode);
+
+bool mm_vm_identity_map(struct mm_ptable *t, paddr_t begin, paddr_t end,
+			int mode, ipaddr_t *ipa);
+bool mm_vm_identity_map_page(struct mm_ptable *t, paddr_t begin, int mode,
+			     ipaddr_t *ipa);
+bool mm_vm_unmap(struct mm_ptable *t, paddr_t begin, paddr_t end, int mode);
+bool mm_vm_is_mapped(struct mm_ptable *t, ipaddr_t ipa, int mode);
+bool mm_vm_translate(struct mm_ptable *t, ipaddr_t ipa, paddr_t *pa);
+
+bool mm_init(void);
+bool mm_cpu_init(void);
+void *mm_identity_map(paddr_t begin, paddr_t end, int mode);
+bool mm_unmap(paddr_t begin, paddr_t end, int mode);
+void mm_defrag(void);
+
+#endif /* _MM_H */
diff --git a/inc/hf/spinlock.h b/inc/hf/spinlock.h
new file mode 100644
index 0000000..1061fb3
--- /dev/null
+++ b/inc/hf/spinlock.h
@@ -0,0 +1,32 @@
+#ifndef _SPINLOCK_H
+#define _SPINLOCK_H
+
+#include <stdatomic.h>
+
+struct spinlock {
+	atomic_flag v;
+};
+
+#define SPINLOCK_INIT                 \
+	{                             \
+		.v = ATOMIC_FLAG_INIT \
+	}
+
+static inline void sl_init(struct spinlock *l)
+{
+	*l = (struct spinlock)SPINLOCK_INIT;
+}
+
+static inline void sl_lock(struct spinlock *l)
+{
+	while (atomic_flag_test_and_set_explicit(&l->v, memory_order_acquire)) {
+		/* do nothing */
+	}
+}
+
+static inline void sl_unlock(struct spinlock *l)
+{
+	atomic_flag_clear_explicit(&l->v, memory_order_release);
+}
+
+#endif /* _SPINLOCK_H */
diff --git a/inc/hf/std.h b/inc/hf/std.h
new file mode 100644
index 0000000..d7cc124
--- /dev/null
+++ b/inc/hf/std.h
@@ -0,0 +1,58 @@
+#ifndef _STD_H
+#define _STD_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+void *memset(void *s, int c, size_t n);
+void *memcpy(void *dst, const void *src, size_t n);
+void *memmove(void *dst, const void *src, size_t n);
+int memcmp(const void *a, const void *b, size_t n);
+
+size_t strlen(const char *str);
+int strcmp(const char *a, const char *b);
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+
+#define be16toh(v) __builtin_bswap16(v)
+#define be32toh(v) __builtin_bswap32(v)
+#define be64toh(v) __builtin_bswap64(v)
+
+#define htobe16(v) __builtin_bswap16(v)
+#define htobe32(v) __builtin_bswap32(v)
+#define htobe64(v) __builtin_bswap64(v)
+
+#define le16toh(v) (v)
+#define le32toh(v) (v)
+#define le64toh(v) (v)
+
+#define htole16(v) (v)
+#define htole32(v) (v)
+#define htole64(v) (v)
+
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+
+#define be16toh(v) (v)
+#define be32toh(v) (v)
+#define be64toh(v) (v)
+
+#define htobe16(v) (v)
+#define htobe32(v) (v)
+#define htobe64(v) (v)
+
+#define le16toh(v) __builtin_bswap16(v)
+#define le32toh(v) __builtin_bswap32(v)
+#define le64toh(v) __builtin_bswap64(v)
+
+#define htole16(v) __builtin_bswap16(v)
+#define htole32(v) __builtin_bswap32(v)
+#define htole64(v) __builtin_bswap64(v)
+
+#else /* __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ && \
+	 __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__ */
+
+#error "Unsupported byte order"
+
+#endif
+
+#endif /* STD_H */
diff --git a/inc/hf/vm.h b/inc/hf/vm.h
new file mode 100644
index 0000000..ce88adc
--- /dev/null
+++ b/inc/hf/vm.h
@@ -0,0 +1,33 @@
+#ifndef _VM_H
+#define _VM_H
+
+#include "hf/cpu.h"
+#include "hf/mm.h"
+
+enum rpc_state {
+	rpc_state_idle,
+	rpc_state_pending,
+	rpc_state_inflight,
+};
+
+struct rpc {
+	enum rpc_state state;
+	int16_t recv_bytes;
+	void *recv;
+	const void *send;
+	struct vcpu *recv_waiter;
+};
+
+struct vm {
+	struct spinlock lock;
+	uint32_t vcpu_count;
+	struct vcpu vcpus[MAX_CPUS];
+	struct mm_ptable ptable;
+	struct rpc rpc;
+};
+
+bool vm_init(struct vm *vm, uint32_t id, uint32_t vcpu_count);
+void vm_start_vcpu(struct vm *vm, size_t index, ipaddr_t entry, size_t arg);
+void vm_set_current(struct vm *vm);
+
+#endif /* _VM_H */