From 7ea3f4a7927013033404e4dba6e10e90e1c49928 Mon Sep 17 00:00:00 2001 From: Alexander Tereshkin Date: Sat, 12 May 2012 19:27:09 +0400 Subject: [PATCH] vchan modifications for the Windows build. --- vchan/init.c | 160 +++++++++++++++++++++++++++++++++++++++-------- vchan/io.c | 9 ++- vchan/libvchan.h | 19 ++++-- vchan/sources | 22 +++++++ 4 files changed, 178 insertions(+), 32 deletions(-) create mode 100644 vchan/sources diff --git a/vchan/init.c b/vchan/init.c index 58ddffd7..03227686 100644 --- a/vchan/init.c +++ b/vchan/init.c @@ -19,6 +19,8 @@ * */ +#ifndef WINNT + #include #include #include @@ -27,18 +29,66 @@ #include #include #include -#include #include #include #include -#include -#include "libvchan.h" #ifndef CONFIG_STUBDOM #include "../u2mfn/u2mfnlib.h" #else #include #endif +#endif + +#include +#include +#include +#include "libvchan.h" + + +static int fill_ctrl(struct libvchan *ctrl, struct vchan_interface *ring, int ring_ref) +{ + if (!ctrl || !ring) + return -1; + + ctrl->ring = ring; + ctrl->ring_ref = ring_ref; + + ring->cons_in = ring->prod_in = ring->cons_out = ring->prod_out = + 0; + ring->server_closed = ring->client_closed = 0; + ring->debug = 0xaabbccdd; + + return 0; +} + +#ifdef WINNT +static int ring_init(struct libvchan *ctrl) +{ + struct gntmem_handle* h; + grant_ref_t grants[1]; + int result; + struct vchan_interface *ring; + + h = gntmem_open(); + if (h == INVALID_HANDLE_VALUE) + return -1; + + gntmem_set_local_quota(h, 1); + gntmem_set_global_quota(h, 1); + + memset(grants, 0, sizeof(grants)); + ring = gntmem_grant_pages_to_domain(h, 0, 1, grants); + if (!ring) { + gntmem_close(h); + return -1; + } + + return fill_ctrl(ctrl, ring, grants[0]); +} + +#else + static int ring_init(struct libvchan *ctrl) { int mfn; @@ -61,14 +111,11 @@ static int ring_init(struct libvchan *ctrl) return -1; #endif - ctrl->ring = ring; - ctrl->ring_ref = mfn; - ring->cons_in = ring->prod_in = ring->cons_out = ring->prod_out = - 0; - ring->server_closed = ring->client_closed = 0; - ring->debug = 0xaabbccdd; - return 0; + return fill_ctrl(ctrl, ring, mfn); } + +#endif + /** creates event channel; creates "ring-ref" and "event-channel" xenstore entries; @@ -86,12 +133,16 @@ static int server_interface_init(struct libvchan *ctrl, int devno) unsigned int len; /* XXX temp hack end */ #ifdef XENCTRL_HAS_XC_INTERFACE - xc_evtchn *evfd; + xc_evtchn *evfd; #else - int evfd; + EVTCHN evfd; #endif evtchn_port_or_error_t port; +#ifdef WINNT + xs = xs_domain_open(); +#else xs = xs_daemon_open(); +#endif if (!xs) { return ret; } @@ -117,6 +168,10 @@ static int server_interface_init(struct libvchan *ctrl, int devno) if (domid_s) domid = atoi(domid_s); + snprintf(buf, sizeof buf, "device/vchan/%d/version", devno); + if (!xs_write(xs, 0, buf, "2", strlen("2"))) + goto fail2; + snprintf(ref, sizeof ref, "%d", ctrl->ring_ref); snprintf(buf, sizeof buf, "device/vchan/%d/ring-ref", devno); if (!xs_write(xs, 0, buf, ref, strlen(ref))) @@ -151,8 +206,12 @@ static int server_interface_init(struct libvchan *ctrl, int devno) if (ret) #ifdef XENCTRL_HAS_XC_INTERFACE xc_evtchn_close(evfd); +#else +#ifdef WINNT + xc_evtchn_close(evfd); #else close(evfd); +#endif #endif fail: xs_daemon_close(xs); @@ -197,6 +256,8 @@ struct libvchan *libvchan_server_init(int devno) return ctrl; } +#ifndef WINNT + int libvchan_server_handle_connected(struct libvchan *ctrl) { struct xs_handle *xs; @@ -241,14 +302,16 @@ static int client_interface_init(struct libvchan *ctrl, int domain, int devno) unsigned int len; struct xs_handle *xs; #ifdef XENCTRL_HAS_XC_INTERFACE - xc_interface *xcfd; + xc_interface *xcfd; #else int xcfd; #endif + int xcg; char buf[64]; char *ref; + int version; #ifdef XENCTRL_HAS_XC_INTERFACE - xc_evtchn *evfd; + xc_evtchn *evfd; #else int evfd; #endif @@ -257,6 +320,18 @@ static int client_interface_init(struct libvchan *ctrl, int domain, int devno) if (!xs) { return ret; } + + version = 1; + snprintf(buf, sizeof buf, + "/local/domain/%d/device/vchan/%d/version", domain, + devno); + ref = xs_read(xs, 0, buf, &len); + if (ref) { + version = atoi(ref); + free(ref); + } + + snprintf(buf, sizeof buf, "/local/domain/%d/device/vchan/%d/ring-ref", domain, devno); @@ -277,23 +352,40 @@ static int client_interface_init(struct libvchan *ctrl, int domain, int devno) free(ref); if (!remote_port) goto fail; + + switch (version) { + case 1: + #ifdef XENCTRL_HAS_XC_INTERFACE - xcfd = xc_interface_open(NULL, NULL, 0); - if (!xcfd) - goto fail; + xcfd = xc_interface_open(NULL, NULL, 0); + if (!xcfd) + goto fail; #else - xcfd = xc_interface_open(); - if (xcfd < 0) - goto fail; + xcfd = xc_interface_open(); + if (xcfd < 0) + goto fail; #endif - ctrl->ring = (struct vchan_interface *) - xc_map_foreign_range(xcfd, domain, 4096, - PROT_READ | PROT_WRITE, ctrl->ring_ref); + ctrl->ring = (struct vchan_interface *) + xc_map_foreign_range(xcfd, domain, 4096, + PROT_READ | PROT_WRITE, ctrl->ring_ref); #ifdef XENCTRL_HAS_XC_INTERFACE - xc_interface_close(xcfd); + xc_interface_close(xcfd); #else - close(xcfd); + close(xcfd); #endif + break; + case 2: + xcg = xc_gnttab_open(); + if (xcg < 0) + goto fail; + ctrl->ring = (struct vchan_interface *) + xc_gnttab_map_grant_ref(xcg, domain, ctrl->ring_ref, PROT_READ | PROT_WRITE); + xc_gnttab_close(xcg); + break; + default: + goto fail; + } + if (ctrl->ring == 0 || ctrl->ring == MAP_FAILED) goto fail; #ifdef XENCTRL_HAS_XC_INTERFACE @@ -312,7 +404,7 @@ static int client_interface_init(struct libvchan *ctrl, int domain, int devno) #ifdef XENCTRL_HAS_XC_INTERFACE xc_evtchn_close(evfd); #else - close(evfd); + close(evfd); #endif else ret = 0; @@ -338,3 +430,19 @@ struct libvchan *libvchan_client_init(int domain, int devno) ctrl->is_server = 0; return ctrl; } + +#else + +// Windows domains can not be dom0 + +int libvchan_server_handle_connected(struct libvchan *ctrl) +{ + return -1; +} + +struct libvchan *libvchan_client_init(int domain, int devno) +{ + return NULL; +} + +#endif \ No newline at end of file diff --git a/vchan/io.c b/vchan/io.c index 23135a25..beed6caf 100644 --- a/vchan/io.c +++ b/vchan/io.c @@ -20,10 +20,15 @@ */ #include "libvchan.h" + +#ifndef WINNT #include -#include #include #include +#endif + +#include + /** \return How much data is immediately available for reading */ @@ -166,7 +171,7 @@ int libvchan_close(struct libvchan *ctrl) } /// The fd to use for select() set -int libvchan_fd_for_select(struct libvchan *ctrl) +EVTCHN libvchan_fd_for_select(struct libvchan *ctrl) { return xc_evtchn_fd(ctrl->evfd); } diff --git a/vchan/libvchan.h b/vchan/libvchan.h index 3f647462..63ab6e9f 100644 --- a/vchan/libvchan.h +++ b/vchan/libvchan.h @@ -22,7 +22,18 @@ #ifndef _LIBVCHAN_H #define _LIBVCHAN_H +#ifdef WINNT +#include +#include +#include +typedef HANDLE EVTCHN; +#define snprintf _snprintf +#else #include +typedef int EVTCHN; +#endif + + #include typedef uint32_t VCHAN_RING_IDX; @@ -42,9 +53,9 @@ struct libvchan { uint32_t ring_ref; /// descriptor to event channel interface #ifdef XENCTRL_HAS_XC_INTERFACE - xc_evtchn *evfd; + xc_evtchn *evfd; #else - int evfd; + EVTCHN evfd; #endif int evport; int devno; @@ -55,16 +66,16 @@ struct libvchan { }; struct libvchan *libvchan_server_init(int devno); -int libvchan_server_handle_connected(struct libvchan *ctrl); struct libvchan *libvchan_client_init(int domain, int devno); +int libvchan_server_handle_connected(struct libvchan *ctrl); int libvchan_write(struct libvchan *ctrl, char *data, int size); int libvchan_read(struct libvchan *ctrl, char *data, int size); int libvchan_wait(struct libvchan *ctrl); int libvchan_close(struct libvchan *ctrl); void libvchan_prepare_to_select(struct libvchan *ctrl); -int libvchan_fd_for_select(struct libvchan *ctrl); +EVTCHN libvchan_fd_for_select(struct libvchan *ctrl); int libvchan_is_eof(struct libvchan *ctrl); int libvchan_data_ready(struct libvchan *ctrl); int libvchan_buffer_space(struct libvchan *ctrl); diff --git a/vchan/sources b/vchan/sources new file mode 100644 index 00000000..6c3a4245 --- /dev/null +++ b/vchan/sources @@ -0,0 +1,22 @@ +TARGETNAME=libvchan +TARGETTYPE=LIBRARY +TARGETPATH=..\libs + +#BUILD_PASS0_CONSUMES=gntmem evtchn xenstore +#BUILD_PASS0_PRODUCES=vchan + +USE_MSVCRT=1 + +DLLDEF=libvchan.def + +INCLUDES=$(INCLUDES); \ + ..\include;\ + +SOURCES=io.c init.c + +TARGETLIBS=\ + $(SDK_LIB_PATH)\setupapi.lib \ + $(SDK_LIB_PATH)\kernel32.lib + + +