summaryrefslogtreecommitdiffstats
path: root/src/include/ipxe/xengrant.h
diff options
context:
space:
mode:
authorMichael Brown2014-07-29 00:38:30 +0200
committerMichael Brown2014-07-29 16:57:44 +0200
commit036af27a4523c4e15e28d30a1513a3f6d9671774 (patch)
treebf284637f91e2258906d736f07a54b1f98dfd68d /src/include/ipxe/xengrant.h
parent[xen] Import selected public headers (diff)
downloadipxe-036af27a4523c4e15e28d30a1513a3f6d9671774.tar.gz
ipxe-036af27a4523c4e15e28d30a1513a3f6d9671774.tar.xz
ipxe-036af27a4523c4e15e28d30a1513a3f6d9671774.zip
[xen] Add basic support for PV-HVM domains
Add basic support for Xen PV-HVM domains (detected via the Xen platform PCI device with IDs 5853:0001), including support for accessing configuration via XenStore and enumerating devices via XenBus. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/include/ipxe/xengrant.h')
-rw-r--r--src/include/ipxe/xengrant.h102
1 files changed, 102 insertions, 0 deletions
diff --git a/src/include/ipxe/xengrant.h b/src/include/ipxe/xengrant.h
new file mode 100644
index 00000000..776eb927
--- /dev/null
+++ b/src/include/ipxe/xengrant.h
@@ -0,0 +1,102 @@
+#ifndef _IPXE_XENGRANT_H
+#define _IPXE_XENGRANT_H
+
+/** @file
+ *
+ * Xen grant tables
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdint.h>
+#include <ipxe/io.h>
+#include <ipxe/xen.h>
+#include <xen/grant_table.h>
+
+/**
+ * Query grant table size
+ *
+ * @v xen Xen hypervisor
+ * @v size Table size
+ * @ret xenrc Xen status code
+ */
+static inline __attribute__ (( always_inline )) int
+xengrant_query_size ( struct xen_hypervisor *xen,
+ struct gnttab_query_size *size ) {
+
+ return xen_hypercall_3 ( xen, __HYPERVISOR_grant_table_op,
+ GNTTABOP_query_size,
+ virt_to_phys ( size ), 1 );
+}
+
+/**
+ * Set grant table version
+ *
+ * @v xen Xen hypervisor
+ * @v version Version
+ * @ret xenrc Xen status code
+ */
+static inline __attribute__ (( always_inline )) int
+xengrant_set_version ( struct xen_hypervisor *xen,
+ struct gnttab_set_version *version ) {
+
+ return xen_hypercall_3 ( xen, __HYPERVISOR_grant_table_op,
+ GNTTABOP_set_version,
+ virt_to_phys ( version ), 1 );
+}
+
+/**
+ * Invalidate access to a page
+ *
+ * @v xen Xen hypervisor
+ * @v ref Grant reference
+ */
+static inline __attribute__ (( always_inline )) void
+xengrant_invalidate ( struct xen_hypervisor *xen, grant_ref_t ref ) {
+ union grant_entry_v2 *entry = &xen->grant.table[ref];
+
+ /* Sanity check */
+ assert ( ( readw ( &entry->hdr.flags ) &
+ ( GTF_reading | GTF_writing ) ) == 0 );
+
+ /* This should apparently be done using a cmpxchg instruction.
+ * We omit this: partly in the interests of simplicity, but
+ * mainly since our control flow generally does not permit
+ * failure paths to themselves fail.
+ */
+ writew ( 0, &entry->hdr.flags );
+}
+
+/**
+ * Permit access to a page
+ *
+ * @v xen Xen hypervisor
+ * @v ref Grant reference
+ * @v domid Domain ID
+ * @v subflags Additional flags
+ * @v page Page start
+ */
+static inline __attribute__ (( always_inline )) void
+xengrant_permit_access ( struct xen_hypervisor *xen, grant_ref_t ref,
+ domid_t domid, unsigned int subflags, void *page ) {
+ union grant_entry_v2 *entry = &xen->grant.table[ref];
+ unsigned long frame = ( virt_to_phys ( page ) / PAGE_SIZE );
+
+ writew ( domid, &entry->full_page.hdr.domid );
+ if ( sizeof ( physaddr_t ) == sizeof ( uint64_t ) ) {
+ writeq ( frame, &entry->full_page.frame );
+ } else {
+ writel ( frame, &entry->full_page.frame );
+ }
+ wmb();
+ writew ( ( GTF_permit_access | subflags ), &entry->full_page.hdr.flags);
+ wmb();
+}
+
+extern int xengrant_alloc ( struct xen_hypervisor *xen, grant_ref_t *refs,
+ unsigned int count );
+extern void xengrant_free ( struct xen_hypervisor *xen, grant_ref_t *refs,
+ unsigned int count );
+
+#endif /* _IPXE_XENGRANT_H */