Opaque virtual address type
This ensures that conversions and arithmetic on virtual addresses are
explicit and not accidental due to it being a primitive integer.
Change-Id: I94dd8e82e065757ae448d98be0cb89eaa1f6542d
diff --git a/inc/api.h b/inc/api.h
index 851c2da..1db9ca8 100644
--- a/inc/api.h
+++ b/inc/api.h
@@ -16,7 +16,7 @@
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(paddr_t send, paddr_t recv);
+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);
diff --git a/inc/fdt_handler.h b/inc/fdt_handler.h
index 9ac6853..e85b8f5 100644
--- a/inc/fdt_handler.h
+++ b/inc/fdt_handler.h
@@ -3,8 +3,9 @@
#include "boot_params.h"
#include "fdt.h"
+#include "mm.h"
-bool fdt_get_boot_params(struct fdt_header *fdt, struct boot_params *p);
-bool fdt_patch(struct fdt_header *fdt, struct boot_params_update *p);
+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/load.h b/inc/load.h
index 7a41b9a..6d19ae6 100644
--- a/inc/load.h
+++ b/inc/load.h
@@ -6,10 +6,11 @@
#include "cpio.h"
#include "memiter.h"
+#include "mm.h"
bool load_primary(const struct memiter *cpio, size_t kernel_arg,
struct memiter *initrd);
-bool load_secondary(const struct memiter *cpio, uint64_t mem_begin,
- uint64_t *mem_end);
+bool load_secondary(const struct memiter *cpio, paddr_t mem_begin,
+ paddr_t *mem_end);
#endif /* _LOAD_H */
diff --git a/inc/mm.h b/inc/mm.h
index 31f5c2f..1e00310 100644
--- a/inc/mm.h
+++ b/inc/mm.h
@@ -7,10 +7,15 @@
#include "arch_mm.h"
struct mm_ptable {
- pte_t *table;
+ paddr_t table;
uint32_t id;
};
+/* An opaque type for an intermediate physical address from a VM. */
+typedef struct {
+ uintpaddr_t ipa;
+} ipaddr_t;
+
#define PAGE_SIZE (1 << PAGE_BITS)
/* The following are arch-independent page mapping modes. */
@@ -55,4 +60,68 @@
bool mm_unmap(vaddr_t begin, vaddr_t end, int mode);
void mm_defrag(void);
+/**
+ * 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;
+}
+
+/**
+ * Converts a physical address to a virtual address. Addresses are currently
+ * identity mapped so this is a simple type convertion.
+ */
+static inline vaddr_t mm_va_from_pa(paddr_t pa)
+{
+ return va_init(pa_addr(pa));
+}
+
+/**
+ * Converts a virtual address to a physical address. Addresses are currently
+ * identity mapped so this is a simple type convertion.
+ */
+static inline paddr_t mm_pa_from_va(vaddr_t va)
+{
+ return pa_init(va_addr(va));
+}
+
+/**
+ * Converts an intermediate physical address to a physical address. Addresses
+ * are currently identity mapped so this is a simple type convertion. Returns
+ * true if the address was mapped in the table and the address was converted.
+ */
+static inline bool mm_pa_from_ipa(struct mm_ptable *t, ipaddr_t ipa,
+ paddr_t *pa)
+{
+ /* TODO: the ptable functions map physical to virtual addresses but they
+ * should really be mapping to intermediate physical addresses.
+ * It might be better to have different interfaces to the mm functions?
+ * This might also mean ipaddr_t should be used when building the VM
+ * tables too?
+ * */
+ if (mm_ptable_is_mapped(t, va_init(ipa_addr(ipa)), 0)) {
+ *pa = pa_init(ipa_addr(ipa));
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Converts a virtual address to a pointer. Only use when the virtual address
+ * is mapped for the calling context.
+ */
+static inline void *mm_ptr_from_va(vaddr_t va)
+{
+ return (void *)va_addr(va);
+}
+
#endif /* _MM_H */