]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/xen/xengrant.c
bcm: flush out early boot messages on uart and screen initialization
[plan9front.git] / sys / src / 9 / xen / xengrant.c
1 /*
2  * Sharing page frames with other domains
3  */
4 #include        "u.h"
5 #include        "../port/lib.h"
6 #include        "mem.h"
7 #include        "dat.h"
8 #include        "fns.h"
9
10 enum {
11         Nframes = 1,    // XXX don't increase this without setting up extra mappings in xengrant_init()
12 };
13
14 static struct {
15         Lock;
16         ushort free;
17         ushort *refs;
18 } refalloc;
19
20 static grant_entry_t *granttab;
21
22 void
23 xengrantinit(void)
24 {
25         gnttab_setup_table_t setup;
26         ulong frames[Nframes];
27         int nrefs, i;
28
29         setup.dom = DOMID_SELF;
30         setup.nr_frames = Nframes;
31         set_xen_guest_handle(setup.frame_list, frames);
32         if (HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1) != 0 || setup.status != 0)
33                 panic("xen grant table setup");
34         granttab = (grant_entry_t*)mmumapframe(XENGRANTTAB, frames[0]);
35         nrefs = Nframes * BY2PG / sizeof(grant_entry_t);
36         refalloc.refs = (ushort*)malloc(nrefs*sizeof(ushort));
37         for (i = 0; i < nrefs; i++)
38                 refalloc.refs[i] = i-1;
39         refalloc.free = nrefs-1;
40 }
41
42 static int
43 allocref(void)
44 {
45         int ref;
46
47         ilock(&refalloc);
48         ref = refalloc.free;
49         if (ref > 0)
50                 refalloc.free = refalloc.refs[ref];
51         iunlock(&refalloc);
52         return ref;
53 }
54
55 static void
56 freeref(int ref)
57 {
58         ilock(&refalloc);
59         refalloc.refs[ref] = refalloc.free;
60         refalloc.free = ref;
61         iunlock(&refalloc);
62 }
63
64 int
65 xengrant(domid_t domid, ulong frame, int flags)
66 {
67         int ref;
68         grant_entry_t *gt;
69
70         if ((ref = allocref()) < 0)
71                 panic("out of xengrant refs");
72         gt = &granttab[ref];
73         gt->frame = frame;
74         gt->domid = domid;
75         coherence();
76         gt->flags = flags;
77         return ref;
78 }
79
80 int
81 xengrantend(int ref)
82 {
83         grant_entry_t *gt;
84         int frame;
85
86         gt = &granttab[ref];
87         coherence();
88         if (gt->flags&GTF_accept_transfer) {
89                 if ((gt->flags&GTF_transfer_completed) == 0)
90                         panic("xengrantend transfer in progress");
91         } else {
92                 if (gt->flags&(GTF_reading|GTF_writing))
93                         panic("xengrantend frame in use");
94         }
95         coherence();
96         frame = gt->frame;
97         gt->flags = GTF_invalid;
98         freeref(ref);
99         return frame;
100 }