ia64/xen-unstable

view tools/ioemu/patches/qemu-target-i386-dm @ 10800:14642f36a201

Fix cirrus and rt8139 co-exist issue in new qemu-dm.
The root cause is that if two MMIO spaces are continuous, qemu may misuse
last MMIO space's read/write to handle current request.

Signed-off-by: Yang Xiaowei <xiaowei.yang@intel.com>
Signed-off-by: Christian Limpach <Christian.Limpach@xensource.com>
author chris@kneesaa.uk.xensource.com
date Wed Jul 26 11:47:44 2006 +0100 (2006-07-26)
parents b450f21472a0
children f2eb2089c9eb
line source
1 Index: ioemu/Makefile.target
2 ===================================================================
3 --- ioemu.orig/Makefile.target 2006-07-26 11:45:57.572129351 +0100
4 +++ ioemu/Makefile.target 2006-07-26 11:45:57.589127569 +0100
5 @@ -57,6 +57,8 @@
6 QEMU_SYSTEM=qemu-fast
7 endif
9 +QEMU_SYSTEM=qemu-dm
10 +
11 ifdef CONFIG_USER_ONLY
12 PROGS=$(QEMU_USER)
13 else
14 @@ -274,6 +276,9 @@
15 OBJS+=gdbstub.o
16 endif
18 +# qemu-dm objects
19 +LIBOBJS=helper2.o exec-dm.o i8259-dm.o
20 +
21 all: $(PROGS)
23 $(QEMU_USER): $(OBJS)
24 @@ -328,7 +333,7 @@
25 ifeq ($(TARGET_BASE_ARCH), i386)
26 # Hardware support
27 VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
28 -VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
29 +VL_OBJS+= fdc.o mc146818rtc.o serial.o i8254.o pcspk.o pc.o
30 VL_OBJS+= cirrus_vga.o mixeng.o apic.o parallel.o
31 DEFINES += -DHAS_AUDIO
32 endif
33 Index: ioemu/configure
34 ===================================================================
35 --- ioemu.orig/configure 2006-07-26 11:45:57.573129246 +0100
36 +++ ioemu/configure 2006-07-26 11:45:57.590127464 +0100
37 @@ -359,6 +359,8 @@
38 if [ "$user" = "yes" ] ; then
39 target_list="i386-user arm-user armeb-user sparc-user ppc-user mips-user mipsel-user $target_list"
40 fi
41 +# the i386-dm target
42 + target_list="i386-dm"
43 else
44 target_list=`echo "$target_list" | sed -e 's/,/ /g'`
45 fi
46 Index: ioemu/monitor.c
47 ===================================================================
48 --- ioemu.orig/monitor.c 2006-07-26 11:45:57.576128931 +0100
49 +++ ioemu/monitor.c 2006-07-26 11:45:57.591127359 +0100
50 @@ -1142,6 +1142,10 @@
51 "", "show host USB devices", },
52 { "profile", "", do_info_profile,
53 "", "show profiling information", },
54 +#ifdef CONFIG_DM
55 + { "hvmiopage", "", sp_info,
56 + "", "show HVM device model shared page info", },
57 +#endif /* CONFIG_DM */
58 { NULL, NULL, },
59 };
61 Index: ioemu/vl.c
62 ===================================================================
63 --- ioemu.orig/vl.c 2006-07-26 11:45:57.579128617 +0100
64 +++ ioemu/vl.c 2006-07-26 11:45:57.593127149 +0100
65 @@ -87,7 +87,7 @@
67 #include "exec-all.h"
69 -#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
70 +#define DEFAULT_NETWORK_SCRIPT "/etc/xen/qemu-ifup"
72 //#define DEBUG_UNUSED_IOPORT
73 //#define DEBUG_IOPORT
74 @@ -4382,7 +4382,7 @@
76 static QEMUResetEntry *first_reset_entry;
77 static int reset_requested;
78 -static int shutdown_requested;
79 +int shutdown_requested;
80 static int powerdown_requested;
82 void qemu_register_reset(QEMUResetHandler *func, void *opaque)
83 @@ -4534,6 +4534,7 @@
84 qemu_get_clock(rt_clock));
85 }
87 +#ifndef CONFIG_DM
88 static CPUState *cur_cpu;
90 int main_loop(void)
91 @@ -4608,6 +4609,7 @@
92 cpu_disable_ticks();
93 return ret;
94 }
95 +#endif /* !CONFIG_DM */
97 void help(void)
98 {
99 Index: ioemu/vl.h
100 ===================================================================
101 --- ioemu.orig/vl.h 2006-07-26 11:45:39.289045710 +0100
102 +++ ioemu/vl.h 2006-07-26 11:45:57.594127044 +0100
103 @@ -38,6 +38,8 @@
104 #include <fcntl.h>
105 #include <sys/stat.h>
106 #include "audio/audio.h"
107 +#include "xenctrl.h"
108 +#include "xs.h"
110 #ifndef O_LARGEFILE
111 #define O_LARGEFILE 0
112 @@ -131,6 +133,11 @@
114 void main_loop_wait(int timeout);
116 +extern FILE *logfile;
117 +
118 +extern int xc_handle;
119 +extern int domid;
120 +
121 extern int ram_size;
122 extern int bios_size;
123 extern int rtc_utc;
124 @@ -814,6 +821,7 @@
125 uint32_t pic_intack_read(PicState2 *s);
126 void pic_info(void);
127 void irq_info(void);
128 +void sp_info(void);
130 /* APIC */
131 typedef struct IOAPICState IOAPICState;
132 Index: ioemu/target-i386-dm/cpu.h
133 ===================================================================
134 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
135 +++ ioemu/target-i386-dm/cpu.h 2006-07-26 11:45:57.594127044 +0100
136 @@ -0,0 +1,86 @@
137 +/*
138 + * i386 virtual CPU header
139 + *
140 + * Copyright (c) 2003 Fabrice Bellard
141 + *
142 + * This library is free software; you can redistribute it and/or
143 + * modify it under the terms of the GNU Lesser General Public
144 + * License as published by the Free Software Foundation; either
145 + * version 2 of the License, or (at your option) any later version.
146 + *
147 + * This library is distributed in the hope that it will be useful,
148 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
149 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
150 + * Lesser General Public License for more details.
151 + *
152 + * You should have received a copy of the GNU Lesser General Public
153 + * License along with this library; if not, write to the Free Software
154 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
155 + */
156 +#ifndef CPU_I386_H
157 +#define CPU_I386_H
158 +
159 +#include "config.h"
160 +
161 +#ifdef TARGET_X86_64
162 +#define TARGET_LONG_BITS 64
163 +#else
164 +#define TARGET_LONG_BITS 32
165 +#endif
166 +
167 +/* target supports implicit self modifying code */
168 +#define TARGET_HAS_SMC
169 +/* support for self modifying code even if the modified instruction is
170 + close to the modifying instruction */
171 +#define TARGET_HAS_PRECISE_SMC
172 +
173 +#include "cpu-defs.h"
174 +
175 +#include "softfloat.h"
176 +
177 +#if defined(__i386__) && !defined(CONFIG_SOFTMMU)
178 +#define USE_CODE_COPY
179 +#endif
180 +
181 +#ifdef USE_X86LDOUBLE
182 +typedef floatx80 CPU86_LDouble;
183 +#else
184 +typedef float64 CPU86_LDouble;
185 +#endif
186 +
187 +/* Empty for now */
188 +typedef struct CPUX86State {
189 + uint32_t a20_mask;
190 +
191 + int interrupt_request;
192 +
193 + CPU_COMMON
194 +
195 + int send_event;
196 +} CPUX86State;
197 +
198 +CPUX86State *cpu_x86_init(void);
199 +int cpu_x86_exec(CPUX86State *s);
200 +void cpu_x86_close(CPUX86State *s);
201 +int cpu_get_pic_interrupt(CPUX86State *s);
202 +/* MSDOS compatibility mode FPU exception support */
203 +void cpu_set_ferr(CPUX86State *s);
204 +
205 +void cpu_x86_set_a20(CPUX86State *env, int a20_state);
206 +
207 +#ifndef IN_OP_I386
208 +void cpu_x86_outb(CPUX86State *env, int addr, int val);
209 +void cpu_x86_outw(CPUX86State *env, int addr, int val);
210 +void cpu_x86_outl(CPUX86State *env, int addr, int val);
211 +int cpu_x86_inb(CPUX86State *env, int addr);
212 +int cpu_x86_inw(CPUX86State *env, int addr);
213 +int cpu_x86_inl(CPUX86State *env, int addr);
214 +#endif
215 +
216 +/* helper2.c */
217 +int main_loop(void);
218 +
219 +#define TARGET_PAGE_BITS 12
220 +#include "cpu-all.h"
221 +
222 +#endif /* CPU_I386_H */
223 Index: ioemu/target-i386-dm/exec-dm.c
224 ===================================================================
225 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
226 +++ ioemu/target-i386-dm/exec-dm.c 2006-07-26 11:46:01.059763730 +0100
227 @@ -0,0 +1,512 @@
228 +/*
229 + * virtual page mapping and translated block handling
230 + *
231 + * Copyright (c) 2003 Fabrice Bellard
232 + *
233 + * This library is free software; you can redistribute it and/or
234 + * modify it under the terms of the GNU Lesser General Public
235 + * License as published by the Free Software Foundation; either
236 + * version 2 of the License, or (at your option) any later version.
237 + *
238 + * This library is distributed in the hope that it will be useful,
239 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
240 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
241 + * Lesser General Public License for more details.
242 + *
243 + * You should have received a copy of the GNU Lesser General Public
244 + * License along with this library; if not, write to the Free Software
245 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
246 + */
247 +#include "config.h"
248 +#ifdef _WIN32
249 +#include <windows.h>
250 +#else
251 +#include <sys/types.h>
252 +#include <sys/mman.h>
253 +#endif
254 +#include <stdlib.h>
255 +#include <stdio.h>
256 +#include <stdarg.h>
257 +#include <string.h>
258 +#include <errno.h>
259 +#include <unistd.h>
260 +#include <inttypes.h>
261 +
262 +#include "cpu.h"
263 +#include "exec-all.h"
264 +
265 +//#define DEBUG_TB_INVALIDATE
266 +//#define DEBUG_FLUSH
267 +//#define DEBUG_TLB
268 +
269 +/* make various TB consistency checks */
270 +//#define DEBUG_TB_CHECK
271 +//#define DEBUG_TLB_CHECK
272 +
273 +#ifndef CONFIG_DM
274 +/* threshold to flush the translated code buffer */
275 +#define CODE_GEN_BUFFER_MAX_SIZE (CODE_GEN_BUFFER_SIZE - CODE_GEN_MAX_SIZE)
276 +
277 +#define SMC_BITMAP_USE_THRESHOLD 10
278 +
279 +#define MMAP_AREA_START 0x00000000
280 +#define MMAP_AREA_END 0xa8000000
281 +
282 +TranslationBlock tbs[CODE_GEN_MAX_BLOCKS];
283 +TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE];
284 +TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
285 +int nb_tbs;
286 +/* any access to the tbs or the page table must use this lock */
287 +spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
288 +
289 +uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE];
290 +uint8_t *code_gen_ptr;
291 +#endif /* !CONFIG_DM */
292 +
293 +uint64_t phys_ram_size;
294 +int phys_ram_fd;
295 +uint8_t *phys_ram_base;
296 +uint8_t *phys_ram_dirty;
297 +
298 +CPUState *first_cpu;
299 +/* current CPU in the current thread. It is only valid inside
300 + cpu_exec() */
301 +CPUState *cpu_single_env;
302 +
303 +typedef struct PageDesc {
304 + /* list of TBs intersecting this ram page */
305 + TranslationBlock *first_tb;
306 + /* in order to optimize self modifying code, we count the number
307 + of lookups we do to a given page to use a bitmap */
308 + unsigned int code_write_count;
309 + uint8_t *code_bitmap;
310 +#if defined(CONFIG_USER_ONLY)
311 + unsigned long flags;
312 +#endif
313 +} PageDesc;
314 +
315 +typedef struct PhysPageDesc {
316 + /* offset in host memory of the page + io_index in the low 12 bits */
317 + unsigned long phys_offset;
318 +} PhysPageDesc;
319 +
320 +typedef struct VirtPageDesc {
321 + /* physical address of code page. It is valid only if 'valid_tag'
322 + matches 'virt_valid_tag' */
323 + target_ulong phys_addr;
324 + unsigned int valid_tag;
325 +#if !defined(CONFIG_SOFTMMU)
326 + /* original page access rights. It is valid only if 'valid_tag'
327 + matches 'virt_valid_tag' */
328 + unsigned int prot;
329 +#endif
330 +} VirtPageDesc;
331 +
332 +#define L2_BITS 10
333 +#define L1_BITS (32 - L2_BITS - TARGET_PAGE_BITS)
334 +
335 +#define L1_SIZE (1 << L1_BITS)
336 +#define L2_SIZE (1 << L2_BITS)
337 +
338 +unsigned long qemu_real_host_page_size;
339 +unsigned long qemu_host_page_bits;
340 +unsigned long qemu_host_page_size;
341 +unsigned long qemu_host_page_mask;
342 +
343 +/* io memory support */
344 +CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
345 +CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
346 +void *io_mem_opaque[IO_MEM_NB_ENTRIES];
347 +static int io_mem_nb = 1;
348 +
349 +/* log support */
350 +char *logfilename = "/tmp/qemu.log";
351 +FILE *logfile;
352 +int loglevel;
353 +
354 +void cpu_exec_init(CPUState *env)
355 +{
356 + CPUState **penv;
357 + int cpu_index;
358 +
359 + env->next_cpu = NULL;
360 + penv = &first_cpu;
361 + cpu_index = 0;
362 + while (*penv != NULL) {
363 + penv = (CPUState **)&(*penv)->next_cpu;
364 + cpu_index++;
365 + }
366 + env->cpu_index = cpu_index;
367 + *penv = env;
368 +
369 + /* alloc dirty bits array */
370 + phys_ram_dirty = qemu_malloc(phys_ram_size >> TARGET_PAGE_BITS);
371 +}
372 +
373 +/* enable or disable low levels log */
374 +void cpu_set_log(int log_flags)
375 +{
376 + loglevel = log_flags;
377 + if (!logfile) {
378 + logfile = fopen(logfilename, "w");
379 + if (!logfile) {
380 + perror(logfilename);
381 + _exit(1);
382 + }
383 +#if !defined(CONFIG_SOFTMMU)
384 + /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
385 + {
386 + static uint8_t logfile_buf[4096];
387 + setvbuf(logfile, logfile_buf, _IOLBF, sizeof(logfile_buf));
388 + }
389 +#else
390 + setvbuf(logfile, NULL, _IOLBF, 0);
391 +#endif
392 + stdout = logfile;
393 + stderr = logfile;
394 + }
395 +}
396 +
397 +void cpu_set_log_filename(const char *filename)
398 +{
399 + logfilename = strdup(filename);
400 +}
401 +
402 +/* mask must never be zero, except for A20 change call */
403 +void cpu_interrupt(CPUState *env, int mask)
404 +{
405 + env->interrupt_request |= mask;
406 +}
407 +
408 +void cpu_reset_interrupt(CPUState *env, int mask)
409 +{
410 + env->interrupt_request &= ~mask;
411 +}
412 +
413 +CPULogItem cpu_log_items[] = {
414 + { CPU_LOG_TB_OUT_ASM, "out_asm",
415 + "show generated host assembly code for each compiled TB" },
416 + { CPU_LOG_TB_IN_ASM, "in_asm",
417 + "show target assembly code for each compiled TB" },
418 + { CPU_LOG_TB_OP, "op",
419 + "show micro ops for each compiled TB (only usable if 'in_asm' used)" },
420 +#ifdef TARGET_I386
421 + { CPU_LOG_TB_OP_OPT, "op_opt",
422 + "show micro ops after optimization for each compiled TB" },
423 +#endif
424 + { CPU_LOG_INT, "int",
425 + "show interrupts/exceptions in short format" },
426 + { CPU_LOG_EXEC, "exec",
427 + "show trace before each executed TB (lots of logs)" },
428 + { CPU_LOG_TB_CPU, "cpu",
429 + "show CPU state before bloc translation" },
430 +#ifdef TARGET_I386
431 + { CPU_LOG_PCALL, "pcall",
432 + "show protected mode far calls/returns/exceptions" },
433 +#endif
434 +#ifdef DEBUG_IOPORT
435 + { CPU_LOG_IOPORT, "ioport",
436 + "show all i/o ports accesses" },
437 +#endif
438 + { 0, NULL, NULL },
439 +};
440 +
441 +static int cmp1(const char *s1, int n, const char *s2)
442 +{
443 + if (strlen(s2) != n)
444 + return 0;
445 + return memcmp(s1, s2, n) == 0;
446 +}
447 +
448 +/* takes a comma separated list of log masks. Return 0 if error. */
449 +int cpu_str_to_log_mask(const char *str)
450 +{
451 + CPULogItem *item;
452 + int mask;
453 + const char *p, *p1;
454 +
455 + p = str;
456 + mask = 0;
457 + for(;;) {
458 + p1 = strchr(p, ',');
459 + if (!p1)
460 + p1 = p + strlen(p);
461 + if(cmp1(p,p1-p,"all")) {
462 + for(item = cpu_log_items; item->mask != 0; item++) {
463 + mask |= item->mask;
464 + }
465 + } else {
466 + for(item = cpu_log_items; item->mask != 0; item++) {
467 + if (cmp1(p, p1 - p, item->name))
468 + goto found;
469 + }
470 + return 0;
471 + }
472 + found:
473 + mask |= item->mask;
474 + if (*p1 != ',')
475 + break;
476 + p = p1 + 1;
477 + }
478 + return mask;
479 +}
480 +
481 +void cpu_abort(CPUState *env, const char *fmt, ...)
482 +{
483 + va_list ap;
484 +
485 + va_start(ap, fmt);
486 + fprintf(stderr, "qemu: fatal: ");
487 + vfprintf(stderr, fmt, ap);
488 + fprintf(stderr, "\n");
489 + va_end(ap);
490 + abort();
491 +}
492 +
493 +
494 +/* XXX: Simple implementation. Fix later */
495 +#define MAX_MMIO 32
496 +struct mmio_space {
497 + target_phys_addr_t start;
498 + unsigned long size;
499 + unsigned long io_index;
500 +} mmio[MAX_MMIO];
501 +unsigned long mmio_cnt;
502 +
503 +/* register physical memory. 'size' must be a multiple of the target
504 + page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
505 + io memory page */
506 +void cpu_register_physical_memory(target_phys_addr_t start_addr,
507 + unsigned long size,
508 + unsigned long phys_offset)
509 +{
510 + int i;
511 +
512 + for (i = 0; i < mmio_cnt; i++) {
513 + if(mmio[i].start == start_addr) {
514 + mmio[i].io_index = phys_offset;
515 + mmio[i].size = size;
516 + return;
517 + }
518 + }
519 +
520 + if (mmio_cnt == MAX_MMIO) {
521 + fprintf(logfile, "too many mmio regions\n");
522 + exit(-1);
523 + }
524 +
525 + mmio[mmio_cnt].io_index = phys_offset;
526 + mmio[mmio_cnt].start = start_addr;
527 + mmio[mmio_cnt++].size = size;
528 +}
529 +
530 +/* mem_read and mem_write are arrays of functions containing the
531 + function to access byte (index 0), word (index 1) and dword (index
532 + 2). All functions must be supplied. If io_index is non zero, the
533 + corresponding io zone is modified. If it is zero, a new io zone is
534 + allocated. The return value can be used with
535 + cpu_register_physical_memory(). (-1) is returned if error. */
536 +int cpu_register_io_memory(int io_index,
537 + CPUReadMemoryFunc **mem_read,
538 + CPUWriteMemoryFunc **mem_write,
539 + void *opaque)
540 +{
541 + int i;
542 +
543 + if (io_index <= 0) {
544 + if (io_index >= IO_MEM_NB_ENTRIES)
545 + return -1;
546 + io_index = io_mem_nb++;
547 + } else {
548 + if (io_index >= IO_MEM_NB_ENTRIES)
549 + return -1;
550 + }
551 +
552 + for(i = 0;i < 3; i++) {
553 + io_mem_read[io_index][i] = mem_read[i];
554 + io_mem_write[io_index][i] = mem_write[i];
555 + }
556 + io_mem_opaque[io_index] = opaque;
557 + return io_index << IO_MEM_SHIFT;
558 +}
559 +
560 +CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index)
561 +{
562 + return io_mem_write[io_index >> IO_MEM_SHIFT];
563 +}
564 +
565 +CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index)
566 +{
567 + return io_mem_read[io_index >> IO_MEM_SHIFT];
568 +}
569 +
570 +/* physical memory access (slow version, mainly for debug) */
571 +#if defined(CONFIG_USER_ONLY)
572 +void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
573 + int len, int is_write)
574 +{
575 + int l, flags;
576 + target_ulong page;
577 +
578 + while (len > 0) {
579 + page = addr & TARGET_PAGE_MASK;
580 + l = (page + TARGET_PAGE_SIZE) - addr;
581 + if (l > len)
582 + l = len;
583 + flags = page_get_flags(page);
584 + if (!(flags & PAGE_VALID))
585 + return;
586 + if (is_write) {
587 + if (!(flags & PAGE_WRITE))
588 + return;
589 + memcpy((uint8_t *)addr, buf, len);
590 + } else {
591 + if (!(flags & PAGE_READ))
592 + return;
593 + memcpy(buf, (uint8_t *)addr, len);
594 + }
595 + len -= l;
596 + buf += l;
597 + addr += l;
598 + }
599 +}
600 +#else
601 +
602 +int iomem_index(target_phys_addr_t addr)
603 +{
604 + int i;
605 +
606 + for (i = 0; i < mmio_cnt; i++) {
607 + unsigned long start, end;
608 +
609 + start = mmio[i].start;
610 + end = mmio[i].start + mmio[i].size;
611 +
612 + if ((addr >= start) && (addr < end)){
613 + return (mmio[i].io_index >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
614 + }
615 + }
616 + return 0;
617 +}
618 +
619 +void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
620 + int len, int is_write)
621 +{
622 + int l, io_index;
623 + uint8_t *ptr;
624 + uint32_t val;
625 + target_phys_addr_t page;
626 + unsigned long pd;
627 +
628 + while (len > 0) {
629 + page = addr & TARGET_PAGE_MASK;
630 + l = (page + TARGET_PAGE_SIZE) - addr;
631 + if (l > len)
632 + l = len;
633 +
634 + pd = page;
635 + io_index = iomem_index(page);
636 + if (is_write) {
637 + if (io_index) {
638 + if (l >= 4 && ((addr & 3) == 0)) {
639 + /* 32 bit read access */
640 + val = ldl_raw(buf);
641 + io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
642 + l = 4;
643 + } else if (l >= 2 && ((addr & 1) == 0)) {
644 + /* 16 bit read access */
645 + val = lduw_raw(buf);
646 + io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val);
647 + l = 2;
648 + } else {
649 + /* 8 bit access */
650 + val = ldub_raw(buf);
651 + io_mem_write[io_index][0](io_mem_opaque[io_index], addr, val);
652 + l = 1;
653 + }
654 + } else {
655 + unsigned long addr1;
656 +
657 + addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
658 + /* RAM case */
659 + ptr = phys_ram_base + addr1;
660 + memcpy(ptr, buf, l);
661 + }
662 + } else {
663 + if (io_index) {
664 + if (l >= 4 && ((addr & 3) == 0)) {
665 + /* 32 bit read access */
666 + val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
667 + stl_raw(buf, val);
668 + l = 4;
669 + } else if (l >= 2 && ((addr & 1) == 0)) {
670 + /* 16 bit read access */
671 + val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr);
672 + stw_raw(buf, val);
673 + l = 2;
674 + } else {
675 + /* 8 bit access */
676 + val = io_mem_read[io_index][0](io_mem_opaque[io_index], addr);
677 + stb_raw(buf, val);
678 + l = 1;
679 + }
680 + } else {
681 + /* RAM case */
682 + ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
683 + (addr & ~TARGET_PAGE_MASK);
684 + memcpy(buf, ptr, l);
685 + }
686 + }
687 + len -= l;
688 + buf += l;
689 + addr += l;
690 + }
691 +}
692 +#endif
693 +
694 +/* virtual memory access for debug */
695 +int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
696 + uint8_t *buf, int len, int is_write)
697 +{
698 + int l;
699 + target_ulong page, phys_addr;
700 +
701 + while (len > 0) {
702 + page = addr & TARGET_PAGE_MASK;
703 + phys_addr = cpu_get_phys_page_debug(env, page);
704 + /* if no physical page mapped, return an error */
705 + if (phys_addr == -1)
706 + return -1;
707 + l = (page + TARGET_PAGE_SIZE) - addr;
708 + if (l > len)
709 + l = len;
710 + cpu_physical_memory_rw(phys_addr + (addr & ~TARGET_PAGE_MASK),
711 + buf, l, is_write);
712 + len -= l;
713 + buf += l;
714 + addr += l;
715 + }
716 + return 0;
717 +}
718 +
719 +void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
720 + int dirty_flags)
721 +{
722 + unsigned long length;
723 + int i, mask, len;
724 + uint8_t *p;
725 +
726 + start &= TARGET_PAGE_MASK;
727 + end = TARGET_PAGE_ALIGN(end);
728 +
729 + length = end - start;
730 + if (length == 0)
731 + return;
732 + mask = ~dirty_flags;
733 + p = phys_ram_dirty + (start >> TARGET_PAGE_BITS);
734 + len = length >> TARGET_PAGE_BITS;
735 + for(i = 0; i < len; i++)
736 + p[i] &= mask;
737 +
738 + return;
739 +}
740 Index: ioemu/target-i386-dm/helper2.c
741 ===================================================================
742 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
743 +++ ioemu/target-i386-dm/helper2.c 2006-07-26 11:45:57.596126835 +0100
744 @@ -0,0 +1,464 @@
745 +/*
746 + * i386 helpers (without register variable usage)
747 + *
748 + * Copyright (c) 2003 Fabrice Bellard
749 + *
750 + * This library is free software; you can redistribute it and/or
751 + * modify it under the terms of the GNU Lesser General Public
752 + * License as published by the Free Software Foundation; either
753 + * version 2 of the License, or (at your option) any later version.
754 + *
755 + * This library is distributed in the hope that it will be useful,
756 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
757 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
758 + * Lesser General Public License for more details.
759 + *
760 + * You should have received a copy of the GNU Lesser General Public
761 + * License along with this library; if not, write to the Free Software
762 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
763 + */
764 +
765 +/*
766 + * Main cpu loop for handling I/O requests coming from a virtual machine
767 + * Copyright 2004, Intel Corporation.
768 + * Copyright 2005, International Business Machines Corporation.
769 + *
770 + * This program is free software; you can redistribute it and/or modify it
771 + * under the terms and conditions of the GNU Lesser General Public License,
772 + * version 2.1, as published by the Free Software Foundation.
773 + *
774 + * This program is distributed in the hope it will be useful, but WITHOUT
775 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
776 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
777 + * more details.
778 + *
779 + * You should have received a copy of the GNU Lesser General Public License
780 + * along with this program; if not, write to the Free Software Foundation,
781 + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA.
782 + */
783 +#include <stdarg.h>
784 +#include <stdlib.h>
785 +#include <stdio.h>
786 +#include <string.h>
787 +#include <inttypes.h>
788 +#include <signal.h>
789 +#include <assert.h>
790 +
791 +#include <limits.h>
792 +#include <fcntl.h>
793 +
794 +#include <xenctrl.h>
795 +#include <xen/hvm/ioreq.h>
796 +
797 +#include "cpu.h"
798 +#include "exec-all.h"
799 +
800 +//#define DEBUG_MMU
801 +
802 +#ifdef USE_CODE_COPY
803 +#include <asm/ldt.h>
804 +#include <linux/unistd.h>
805 +#include <linux/version.h>
806 +
807 +_syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)
808 +
809 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 66)
810 +#define modify_ldt_ldt_s user_desc
811 +#endif
812 +#endif /* USE_CODE_COPY */
813 +
814 +#include "vl.h"
815 +
816 +int domid = -1;
817 +int vcpus = 1;
818 +
819 +int xc_handle;
820 +
821 +shared_iopage_t *shared_page = NULL;
822 +
823 +/* the evtchn fd for polling */
824 +int xce_handle = -1;
825 +
826 +/* which vcpu we are serving */
827 +int send_vcpu = 0;
828 +
829 +CPUX86State *cpu_x86_init(void)
830 +{
831 + CPUX86State *env;
832 + static int inited;
833 + int i, rc;
834 +
835 + env = qemu_mallocz(sizeof(CPUX86State));
836 + if (!env)
837 + return NULL;
838 + cpu_exec_init(env);
839 +
840 + /* init various static tables */
841 + if (!inited) {
842 + inited = 1;
843 +
844 + cpu_single_env = env;
845 +
846 + xce_handle = xc_evtchn_open();
847 + if (xce_handle == -1) {
848 + perror("open");
849 + return NULL;
850 + }
851 +
852 + /* FIXME: how about if we overflow the page here? */
853 + for (i = 0; i < vcpus; i++) {
854 + rc = xc_evtchn_bind_interdomain(
855 + xce_handle, domid, shared_page->vcpu_iodata[i].vp_eport);
856 + if (rc == -1) {
857 + fprintf(logfile, "bind interdomain ioctl error %d\n", errno);
858 + return NULL;
859 + }
860 + shared_page->vcpu_iodata[i].dm_eport = rc;
861 + }
862 + }
863 +
864 + return env;
865 +}
866 +
867 +/* called from main_cpu_reset */
868 +void cpu_reset(CPUX86State *env)
869 +{
870 +}
871 +
872 +void cpu_x86_close(CPUX86State *env)
873 +{
874 + free(env);
875 +}
876 +
877 +
878 +void cpu_dump_state(CPUState *env, FILE *f,
879 + int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
880 + int flags)
881 +{
882 +}
883 +
884 +/***********************************************************/
885 +/* x86 mmu */
886 +/* XXX: add PGE support */
887 +
888 +void cpu_x86_set_a20(CPUX86State *env, int a20_state)
889 +{
890 + a20_state = (a20_state != 0);
891 + if (a20_state != ((env->a20_mask >> 20) & 1)) {
892 +#if defined(DEBUG_MMU)
893 + printf("A20 update: a20=%d\n", a20_state);
894 +#endif
895 + env->a20_mask = 0xffefffff | (a20_state << 20);
896 + }
897 +}
898 +
899 +target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
900 +{
901 + return addr;
902 +}
903 +
904 +//some functions to handle the io req packet
905 +void sp_info()
906 +{
907 + ioreq_t *req;
908 + int i;
909 +
910 + for (i = 0; i < vcpus; i++) {
911 + req = &(shared_page->vcpu_iodata[i].vp_ioreq);
912 + term_printf("vcpu %d: event port %d\n", i,
913 + shared_page->vcpu_iodata[i].vp_eport);
914 + term_printf(" req state: %x, pvalid: %x, addr: %"PRIx64", "
915 + "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
916 + req->state, req->pdata_valid, req->addr,
917 + req->u.data, req->count, req->size);
918 + term_printf(" IO totally occurred on this vcpu: %"PRIx64"\n",
919 + req->io_count);
920 + }
921 +}
922 +
923 +//get the ioreq packets from share mem
924 +static ioreq_t *__cpu_get_ioreq(int vcpu)
925 +{
926 + ioreq_t *req;
927 +
928 + req = &(shared_page->vcpu_iodata[vcpu].vp_ioreq);
929 +
930 + if (req->state == STATE_IOREQ_READY) {
931 + req->state = STATE_IOREQ_INPROCESS;
932 + return req;
933 + }
934 +
935 + fprintf(logfile, "False I/O request ... in-service already: "
936 + "%x, pvalid: %x, port: %"PRIx64", "
937 + "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
938 + req->state, req->pdata_valid, req->addr,
939 + req->u.data, req->count, req->size);
940 + return NULL;
941 +}
942 +
943 +//use poll to get the port notification
944 +//ioreq_vec--out,the
945 +//retval--the number of ioreq packet
946 +static ioreq_t *cpu_get_ioreq(void)
947 +{
948 + int i;
949 + evtchn_port_t port;
950 +
951 + port = xc_evtchn_pending(xce_handle);
952 + if (port != -1) {
953 + for ( i = 0; i < vcpus; i++ )
954 + if ( shared_page->vcpu_iodata[i].dm_eport == port )
955 + break;
956 +
957 + if ( i == vcpus ) {
958 + fprintf(logfile, "Fatal error while trying to get io event!\n");
959 + exit(1);
960 + }
961 +
962 + // unmask the wanted port again
963 + xc_evtchn_unmask(xce_handle, port);
964 +
965 + //get the io packet from shared memory
966 + send_vcpu = i;
967 + return __cpu_get_ioreq(i);
968 + }
969 +
970 + //read error or read nothing
971 + return NULL;
972 +}
973 +
974 +unsigned long do_inp(CPUState *env, unsigned long addr, unsigned long size)
975 +{
976 + switch(size) {
977 + case 1:
978 + return cpu_inb(env, addr);
979 + case 2:
980 + return cpu_inw(env, addr);
981 + case 4:
982 + return cpu_inl(env, addr);
983 + default:
984 + fprintf(logfile, "inp: bad size: %lx %lx\n", addr, size);
985 + exit(-1);
986 + }
987 +}
988 +
989 +void do_outp(CPUState *env, unsigned long addr,
990 + unsigned long size, unsigned long val)
991 +{
992 + switch(size) {
993 + case 1:
994 + return cpu_outb(env, addr, val);
995 + case 2:
996 + return cpu_outw(env, addr, val);
997 + case 4:
998 + return cpu_outl(env, addr, val);
999 + default:
1000 + fprintf(logfile, "outp: bad size: %lx %lx\n", addr, size);
1001 + exit(-1);
1002 + }
1003 +}
1005 +extern void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
1006 + int len, int is_write);
1008 +static inline void read_physical(uint64_t addr, unsigned long size, void *val)
1009 +{
1010 + return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 0);
1011 +}
1013 +static inline void write_physical(uint64_t addr, unsigned long size, void *val)
1014 +{
1015 + return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 1);
1016 +}
1018 +void cpu_ioreq_pio(CPUState *env, ioreq_t *req)
1019 +{
1020 + int i, sign;
1022 + sign = req->df ? -1 : 1;
1024 + if (req->dir == IOREQ_READ) {
1025 + if (!req->pdata_valid) {
1026 + req->u.data = do_inp(env, req->addr, req->size);
1027 + } else {
1028 + unsigned long tmp;
1030 + for (i = 0; i < req->count; i++) {
1031 + tmp = do_inp(env, req->addr, req->size);
1032 + write_physical((target_phys_addr_t) req->u.pdata
1033 + + (sign * i * req->size),
1034 + req->size, &tmp);
1035 + }
1036 + }
1037 + } else if (req->dir == IOREQ_WRITE) {
1038 + if (!req->pdata_valid) {
1039 + do_outp(env, req->addr, req->size, req->u.data);
1040 + } else {
1041 + for (i = 0; i < req->count; i++) {
1042 + unsigned long tmp;
1044 + read_physical((target_phys_addr_t) req->u.pdata
1045 + + (sign * i * req->size),
1046 + req->size, &tmp);
1047 + do_outp(env, req->addr, req->size, tmp);
1048 + }
1049 + }
1050 + }
1051 +}
1053 +void cpu_ioreq_move(CPUState *env, ioreq_t *req)
1054 +{
1055 + int i, sign;
1057 + sign = req->df ? -1 : 1;
1059 + if (!req->pdata_valid) {
1060 + if (req->dir == IOREQ_READ) {
1061 + for (i = 0; i < req->count; i++) {
1062 + read_physical(req->addr
1063 + + (sign * i * req->size),
1064 + req->size, &req->u.data);
1065 + }
1066 + } else if (req->dir == IOREQ_WRITE) {
1067 + for (i = 0; i < req->count; i++) {
1068 + write_physical(req->addr
1069 + + (sign * i * req->size),
1070 + req->size, &req->u.data);
1071 + }
1072 + }
1073 + } else {
1074 + unsigned long tmp;
1076 + if (req->dir == IOREQ_READ) {
1077 + for (i = 0; i < req->count; i++) {
1078 + read_physical(req->addr
1079 + + (sign * i * req->size),
1080 + req->size, &tmp);
1081 + write_physical((target_phys_addr_t )req->u.pdata
1082 + + (sign * i * req->size),
1083 + req->size, &tmp);
1084 + }
1085 + } else if (req->dir == IOREQ_WRITE) {
1086 + for (i = 0; i < req->count; i++) {
1087 + read_physical((target_phys_addr_t) req->u.pdata
1088 + + (sign * i * req->size),
1089 + req->size, &tmp);
1090 + write_physical(req->addr
1091 + + (sign * i * req->size),
1092 + req->size, &tmp);
1093 + }
1094 + }
1095 + }
1096 +}
1098 +void cpu_ioreq_and(CPUState *env, ioreq_t *req)
1099 +{
1100 + unsigned long tmp1, tmp2;
1102 + if (req->pdata_valid != 0)
1103 + hw_error("expected scalar value");
1105 + read_physical(req->addr, req->size, &tmp1);
1106 + if (req->dir == IOREQ_WRITE) {
1107 + tmp2 = tmp1 & (unsigned long) req->u.data;
1108 + write_physical(req->addr, req->size, &tmp2);
1109 + }
1110 + req->u.data = tmp1;
1111 +}
1113 +void cpu_ioreq_or(CPUState *env, ioreq_t *req)
1114 +{
1115 + unsigned long tmp1, tmp2;
1117 + if (req->pdata_valid != 0)
1118 + hw_error("expected scalar value");
1120 + read_physical(req->addr, req->size, &tmp1);
1121 + if (req->dir == IOREQ_WRITE) {
1122 + tmp2 = tmp1 | (unsigned long) req->u.data;
1123 + write_physical(req->addr, req->size, &tmp2);
1124 + }
1125 + req->u.data = tmp1;
1126 +}
1128 +void cpu_ioreq_xor(CPUState *env, ioreq_t *req)
1129 +{
1130 + unsigned long tmp1, tmp2;
1132 + if (req->pdata_valid != 0)
1133 + hw_error("expected scalar value");
1135 + read_physical(req->addr, req->size, &tmp1);
1136 + if (req->dir == IOREQ_WRITE) {
1137 + tmp2 = tmp1 ^ (unsigned long) req->u.data;
1138 + write_physical(req->addr, req->size, &tmp2);
1139 + }
1140 + req->u.data = tmp1;
1141 +}
1143 +void cpu_handle_ioreq(void *opaque)
1144 +{
1145 + CPUState *env = opaque;
1146 + ioreq_t *req = cpu_get_ioreq();
1148 + if (req) {
1149 + if ((!req->pdata_valid) && (req->dir == IOREQ_WRITE)) {
1150 + if (req->size != 4)
1151 + req->u.data &= (1UL << (8 * req->size))-1;
1152 + }
1154 + switch (req->type) {
1155 + case IOREQ_TYPE_PIO:
1156 + cpu_ioreq_pio(env, req);
1157 + break;
1158 + case IOREQ_TYPE_COPY:
1159 + cpu_ioreq_move(env, req);
1160 + break;
1161 + case IOREQ_TYPE_AND:
1162 + cpu_ioreq_and(env, req);
1163 + break;
1164 + case IOREQ_TYPE_OR:
1165 + cpu_ioreq_or(env, req);
1166 + break;
1167 + case IOREQ_TYPE_XOR:
1168 + cpu_ioreq_xor(env, req);
1169 + break;
1170 + default:
1171 + hw_error("Invalid ioreq type 0x%x\n", req->type);
1172 + }
1174 + /* No state change if state = STATE_IORESP_HOOK */
1175 + if (req->state == STATE_IOREQ_INPROCESS)
1176 + req->state = STATE_IORESP_READY;
1177 + env->send_event = 1;
1178 + }
1179 +}
1181 +int main_loop(void)
1182 +{
1183 + extern int vm_running;
1184 + extern int shutdown_requested;
1185 + CPUState *env = cpu_single_env;
1186 + int evtchn_fd = xc_evtchn_fd(xce_handle);
1188 + qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env);
1190 + env->send_event = 0;
1192 + while (1) {
1193 + if (vm_running) {
1194 + if (shutdown_requested)
1195 + break;
1196 + }
1198 + /* Wait up to 10 msec. */
1199 + main_loop_wait(10);
1201 + if (env->send_event) {
1202 + env->send_event = 0;
1203 + xc_evtchn_notify(xce_handle,
1204 + shared_page->vcpu_iodata[send_vcpu].dm_eport);
1205 + }
1206 + }
1207 + return 0;
1208 +}
1209 Index: ioemu/target-i386-dm/i8259-dm.c
1210 ===================================================================
1211 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
1212 +++ ioemu/target-i386-dm/i8259-dm.c 2006-07-26 11:45:57.596126835 +0100
1213 @@ -0,0 +1,107 @@
1214 +/* Xen 8259 stub for interrupt controller emulation
1215 + *
1216 + * Copyright (c) 2003-2004 Fabrice Bellard
1217 + * Copyright (c) 2005 Intel corperation
1218 + *
1219 + * Permission is hereby granted, free of charge, to any person obtaining a copy
1220 + * of this software and associated documentation files (the "Software"), to deal
1221 + * in the Software without restriction, including without limitation the rights
1222 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1223 + * copies of the Software, and to permit persons to whom the Software is
1224 + * furnished to do so, subject to the following conditions:
1225 + *
1226 + * The above copyright notice and this permission notice shall be included in
1227 + * all copies or substantial portions of the Software.
1228 + *
1229 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1230 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1231 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1232 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1233 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1234 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1235 + * THE SOFTWARE.
1236 + */
1237 +#include "vl.h"
1239 +/* debug PIC */
1240 +//#define DEBUG_PIC
1242 +//#define DEBUG_IRQ_LATENCY
1243 +//#define DEBUG_IRQ_COUNT
1245 +#include "xenctrl.h"
1246 +#include <xen/hvm/ioreq.h>
1247 +#include <stdio.h>
1248 +#include "cpu.h"
1249 +#include "cpu-all.h"
1251 +extern shared_iopage_t *shared_page;
1253 +struct PicState2 {
1254 +};
1256 +void pic_set_irq_new(void *opaque, int irq, int level)
1257 +{
1258 + /* PicState2 *s = opaque; */
1259 + global_iodata_t *gio;
1260 + int mask;
1262 + gio = &shared_page->sp_global;
1263 + mask = 1 << irq;
1264 + if ( gio->pic_elcr & mask ) {
1265 + /* level */
1266 + if ( level ) {
1267 + atomic_clear_bit(irq, &gio->pic_clear_irr);
1268 + atomic_set_bit(irq, &gio->pic_irr);
1269 + cpu_single_env->send_event = 1;
1270 + }
1271 + else {
1272 + atomic_clear_bit(irq, &gio->pic_irr);
1273 + atomic_set_bit(irq, &gio->pic_clear_irr);
1274 + cpu_single_env->send_event = 1;
1275 + }
1276 + }
1277 + else {
1278 + /* edge */
1279 + if ( level ) {
1280 + if ( (mask & gio->pic_last_irr) == 0 ) {
1281 + atomic_set_bit(irq, &gio->pic_irr);
1282 + atomic_set_bit(irq, &gio->pic_last_irr);
1283 + cpu_single_env->send_event = 1;
1284 + }
1285 + }
1286 + else {
1287 + atomic_clear_bit(irq, &gio->pic_last_irr);
1288 + }
1289 + }
1290 +}
1292 +/* obsolete function */
1293 +void pic_set_irq(int irq, int level)
1294 +{
1295 + pic_set_irq_new(isa_pic, irq, level);
1296 +}
1298 +void irq_info(void)
1299 +{
1300 + term_printf("irq statistic code not compiled.\n");
1301 +}
1303 +void pic_info(void)
1304 +{
1305 + term_printf("pic_info code not compiled.\n");
1306 +}
1308 +PicState2 *pic_init(IRQRequestFunc *irq_request, void *irq_request_opaque)
1309 +{
1310 + PicState2 *s;
1311 + s = qemu_mallocz(sizeof(PicState2));
1312 + if (!s)
1313 + return NULL;
1314 + return s;
1315 +}
1317 +void pic_set_alt_irq_func(PicState2 *s, SetIRQFunc *alt_irq_func,
1318 + void *alt_irq_opaque)
1319 +{
1320 +}
1321 Index: ioemu/target-i386-dm/qemu-dm.debug
1322 ===================================================================
1323 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
1324 +++ ioemu/target-i386-dm/qemu-dm.debug 2006-07-26 11:45:57.596126835 +0100
1325 @@ -0,0 +1,5 @@
1326 +#!/bin/sh
1328 +echo $* > /tmp/args
1329 +echo $DISPLAY >> /tmp/args
1330 +exec /usr/lib/xen/bin/qemu-dm $*
1331 Index: ioemu/target-i386-dm/qemu-ifup
1332 ===================================================================
1333 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
1334 +++ ioemu/target-i386-dm/qemu-ifup 2006-07-26 11:45:57.597126730 +0100
1335 @@ -0,0 +1,10 @@
1336 +#!/bin/sh
1338 +#. /etc/rc.d/init.d/functions
1339 +#ulimit -c unlimited
1341 +echo -c 'config qemu network with xen bridge for '
1342 +echo $*
1344 +ifconfig $1 0.0.0.0 up
1345 +brctl addif $2 $1