ia64/xen-unstable

view tools/libxc/xc_minios.c @ 17042:a905c582a406

Add stubdomain support. See stubdom/README for usage details.

- Move PAGE_SIZE and STACK_SIZE into __PAGE_SIZE and __STACK_SIZE in
arch_limits.h so as to permit getting them from there without
pulling all the internal Mini-OS defines.
- Setup a xen-elf cross-compilation environment in stubdom/cross-root
- Add a POSIX layer on top of Mini-OS by linking against the newlib C
library and lwIP, and implementing the Unixish part in mini-os/lib/sys.c
- Cross-compile zlib and libpci too.
- Add an xs.h-compatible layer on top of Mini-OS' xenbus.
- Cross-compile libxc with an additional xc_minios.c and a few things
disabled.
- Cross-compile ioemu with an additional block-vbd, but without sound,
tpm and other details. A few hacks are needed:
- Align ide and scsi buffers at least on sector size to permit
direct transmission to the block backend. While we are at it, just
page-align it to possibly save a segment. Also, limit the scsi
buffer size because of limitations of the block paravirtualization
protocol.
- Allocate big tables dynamically rather that letting them go to
bss: when Mini-OS gets installed in memory, bss is not lazily
allocated, and doing so during Mini-OS is unnecessarily trick while
we can simply use malloc.
- Had to change the Mini-OS compilation somehow, so as to export
Mini-OS compilation flags to the Makefiles of libxc and ioemu.

Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Feb 12 14:35:39 2008 +0000 (2008-02-12)
parents
children ea5ee63548e4
line source
1 /******************************************************************************
2 *
3 * Copyright 2007-2008 Samuel Thibault <samuel.thibault@eu.citrix.com>.
4 * All rights reserved.
5 * Use is subject to license terms.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2 of the
10 * License.
11 */
13 #undef NDEBUG
14 #include <types.h>
15 #include <os.h>
16 #include <mm.h>
17 #include <lib.h>
18 #include <events.h>
19 #include <wait.h>
20 #include <sys/mman.h>
21 #include <errno.h>
23 #include <xen/memory.h>
24 #include <xen/sys/evtchn.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <stdio.h>
28 #include <assert.h>
29 #include <stdint.h>
30 #include <inttypes.h>
32 #include "xc_private.h"
34 extern struct wait_queue_head event_queue;
36 int xc_interface_open(void)
37 {
38 return 0;
39 }
41 int xc_interface_close(int xc_handle)
42 {
43 return 0;
44 }
46 void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
47 xen_pfn_t *arr, int num)
48 {
49 unsigned long pt_prot = 0;
50 #ifdef __ia64__
51 /* TODO */
52 #else
53 if (prot & PROT_READ)
54 pt_prot = L1_PROT_RO;
55 if (prot & PROT_WRITE)
56 pt_prot = L1_PROT;
57 #endif
58 return map_frames_ex(arr, num, 1, 0, 1, dom, 1, pt_prot);
59 }
61 void *xc_map_foreign_range(int xc_handle, uint32_t dom,
62 int size, int prot,
63 unsigned long mfn)
64 {
65 unsigned long pt_prot = 0;
66 printf("xc_map_foreign_range(%lx, %d)\n", mfn, size);
67 #ifdef __ia64__
68 /* TODO */
69 #else
70 if (prot & PROT_READ)
71 pt_prot = L1_PROT_RO;
72 if (prot & PROT_WRITE)
73 pt_prot = L1_PROT;
74 #endif
75 assert(!(size % getpagesize()));
76 return map_frames_ex(&mfn, size / getpagesize(), 0, 1, 1, dom, 0, pt_prot);
77 }
79 int xc_map_foreign_ranges(int xc_handle, uint32_t dom,
80 privcmd_mmap_entry_t *entries, int nr)
81 {
82 printf("xc_map_foreign_ranges, TODO\n");
83 do_exit();
84 }
86 int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall)
87 {
88 multicall_entry_t call;
89 int i, ret;
91 call.op = hypercall->op;
92 for (i = 0; i < sizeof(hypercall->arg) / sizeof(*hypercall->arg); i++)
93 call.args[i] = hypercall->arg[i];
95 ret = HYPERVISOR_multicall(&call, 1);
97 if (ret < 0) {
98 errno = -ret;
99 return -1;
100 }
101 if (call.result < 0) {
102 errno = -call.result;
103 return -1;
104 }
105 return call.result;
106 }
108 int xc_find_device_number(const char *name)
109 {
110 printf("xc_find_device_number(%s)\n", name);
111 do_exit();
112 }
114 int xc_evtchn_open(void)
115 {
116 int fd = alloc_fd(FTYPE_EVTCHN), i;
117 for (i = 0; i < MAX_EVTCHN_PORTS; i++) {
118 files[fd].evtchn.ports[i].port = -1;
119 files[fd].evtchn.ports[i].bound = 0;
120 }
121 printf("evtchn_open() -> %d\n", fd);
122 return fd;
123 }
125 int xc_evtchn_close(int xce_handle)
126 {
127 int i;
128 for (i = 0; i < MAX_EVTCHN_PORTS; i++)
129 if (files[xce_handle].evtchn.ports[i].bound)
130 unbind_evtchn(files[xce_handle].evtchn.ports[i].port);
131 files[xce_handle].type = FTYPE_NONE;
132 return 0;
133 }
135 int xc_evtchn_fd(int xce_handle)
136 {
137 return xce_handle;
138 }
140 int xc_evtchn_notify(int xce_handle, evtchn_port_t port)
141 {
142 int ret;
144 ret = notify_remote_via_evtchn(port);
146 if (ret < 0) {
147 errno = -ret;
148 ret = -1;
149 }
150 return ret;
151 }
153 /* XXX Note: This is not threadsafe */
154 static int port_alloc(int xce_handle) {
155 int i;
156 for (i= 0; i < MAX_EVTCHN_PORTS; i++)
157 if (files[xce_handle].evtchn.ports[i].port == -1)
158 break;
159 if (i == MAX_EVTCHN_PORTS) {
160 printf("Too many ports in xc handle\n");
161 errno = EMFILE;
162 return -1;
163 }
164 files[xce_handle].evtchn.ports[i].pending = 0;
165 return i;
166 }
168 static void poke_port(int xce_handle, evtchn_port_t port)
169 {
170 shared_info_t *s = HYPERVISOR_shared_info;
171 printk("poking port %d\n", port);
172 synch_set_bit(port, &s->evtchn_pending[0]);
173 xc_evtchn_unmask(xce_handle, port);
174 }
176 static void evtchn_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
177 {
178 int xce_handle = (intptr_t) data;
179 int i;
180 assert(files[xce_handle].type == FTYPE_EVTCHN);
181 mask_evtchn(port);
182 for (i= 0; i < MAX_EVTCHN_PORTS; i++)
183 if (files[xce_handle].evtchn.ports[i].port == port)
184 break;
185 if (i == MAX_EVTCHN_PORTS) {
186 printk("Unknown port for handle %d\n", xce_handle);
187 return;
188 }
189 files[xce_handle].evtchn.ports[i].pending++;
190 files[xce_handle].read = 1;
191 wake_up(&event_queue);
192 }
194 evtchn_port_or_error_t xc_evtchn_bind_unbound_port(int xce_handle, int domid)
195 {
196 int ret, i;
197 evtchn_port_t port;
199 assert(get_current() == main_thread);
200 i = port_alloc(xce_handle);
201 if (i == -1)
202 return -1;
204 printf("xc_evtchn_bind_unbound_port(%d)", domid);
205 ret = evtchn_alloc_unbound(domid, evtchn_handler, (void*)(intptr_t)xce_handle, &port);
206 printf(" = %d\n", ret);
208 if (ret < 0) {
209 errno = -ret;
210 return -1;
211 }
212 files[xce_handle].evtchn.ports[i].bound = 1;
213 files[xce_handle].evtchn.ports[i].port = port;
214 return port;
215 }
217 evtchn_port_or_error_t xc_evtchn_bind_interdomain(int xce_handle, int domid,
218 evtchn_port_t remote_port)
219 {
220 evtchn_port_t local_port;
221 int ret, i;
223 assert(get_current() == main_thread);
224 i = port_alloc(xce_handle);
225 if (i == -1)
226 return -1;
228 printf("xc_evtchn_bind_interdomain(%d, %"PRId32")", domid, remote_port);
229 ret = evtchn_bind_interdomain(domid, remote_port, evtchn_handler, (void*)(intptr_t)xce_handle, &local_port);
230 printf(" = %d\n", ret);
232 if (ret < 0) {
233 errno = -ret;
234 return -1;
235 }
236 files[xce_handle].evtchn.ports[i].bound = 1;
237 files[xce_handle].evtchn.ports[i].port = local_port;
238 /* Poke port on start: HVM won't send an event for the very first request since
239 * we were not ready yet */
240 poke_port(xce_handle, local_port);
241 return local_port;
242 }
244 int xc_evtchn_unbind(int xce_handle, evtchn_port_t port)
245 {
246 int i;
247 for (i = 0; i < MAX_EVTCHN_PORTS; i++)
248 if (files[xce_handle].evtchn.ports[i].port == port) {
249 files[xce_handle].evtchn.ports[i].port = -1;
250 break;
251 }
252 if (i == MAX_EVTCHN_PORTS)
253 printf("Warning: couldn't find port %"PRId32" for xc handle %x\n", port, xce_handle);
254 files[xce_handle].evtchn.ports[i].bound = 0;
255 unbind_evtchn(port);
256 return 0;
257 }
259 evtchn_port_or_error_t xc_evtchn_bind_virq(int xce_handle, unsigned int virq)
260 {
261 evtchn_port_t port;
262 int i;
264 assert(get_current() == main_thread);
265 i = port_alloc(xce_handle);
266 if (i == -1)
267 return -1;
269 printf("xc_evtchn_bind_virq(%d)", virq);
270 port = bind_virq(virq, evtchn_handler, (void*)(intptr_t)xce_handle);
272 if (port < 0) {
273 errno = -port;
274 return -1;
275 }
276 files[xce_handle].evtchn.ports[i].bound = 1;
277 files[xce_handle].evtchn.ports[i].port = port;
278 return port;
279 }
281 evtchn_port_or_error_t xc_evtchn_pending(int xce_handle)
282 {
283 int i;
284 unsigned long flags;
285 local_irq_save(flags);
286 for (i = 0; i < MAX_EVTCHN_PORTS; i++) {
287 evtchn_port_t port = files[xce_handle].evtchn.ports[i].port;
288 if (port != -1 && files[xce_handle].evtchn.ports[i].pending) {
289 files[xce_handle].evtchn.ports[i].pending--;
290 local_irq_restore(flags);
291 return port;
292 }
293 }
294 files[xce_handle].read = 0;
295 local_irq_restore(flags);
296 return -1;
297 }
299 int xc_evtchn_unmask(int xce_handle, evtchn_port_t port)
300 {
301 unmask_evtchn(port);
302 return 0;
303 }
305 /*
306 * Local variables:
307 * mode: C
308 * c-set-style: "BSD"
309 * c-basic-offset: 4
310 * tab-width: 4
311 * indent-tabs-mode: nil
312 * End:
313 */