From owner-freebsd-emulation@FreeBSD.ORG Wed Apr 13 20:35:34 2005 Return-Path: Delivered-To: freebsd-emulation@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B65E116A4CE; Wed, 13 Apr 2005 20:35:34 +0000 (GMT) Received: from anuket.mj.niksun.com (gwnew.niksun.com [65.115.46.162]) by mx1.FreeBSD.org (Postfix) with ESMTP id BD37D43D46; Wed, 13 Apr 2005 20:35:30 +0000 (GMT) (envelope-from jkim@niksun.com) Received: from [10.70.0.244] (daemon.mj.niksun.com [10.70.0.244]) by anuket.mj.niksun.com (8.13.1/8.12.11) with ESMTP id j3DKZSdT082440; Wed, 13 Apr 2005 16:35:29 -0400 (EDT) (envelope-from jkim@niksun.com) From: Jung-uk Kim Organization: Niksun, Inc. To: freebsd-amd64@freebsd.org, freebsd-emulation@freebsd.org Date: Wed, 13 Apr 2005 16:35:26 -0400 User-Agent: KMail/1.6.2 MIME-Version: 1.0 Content-Disposition: inline Content-Type: Multipart/Mixed; boundary="Boundary-00=_OKYXC+kkn1fOkqy" Message-Id: <200504131635.26063.jkim@niksun.com> X-Virus-Scanned: ClamAV 0.83/826/Wed Apr 13 07:03:12 2005 on anuket.mj.niksun.com X-Virus-Status: Clean cc: Juergen Lock Subject: QEMU on FreeBSD/amd64 (patches) X-BeenThere: freebsd-emulation@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Development of Emulators of other operating systems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Apr 2005 20:35:34 -0000 --Boundary-00=_OKYXC+kkn1fOkqy Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline I finally manage to build QEMU snapshot on FreeBSD/amd64 6-CURRENT. There's ports/emulators/qemu but it doesn't build on AMD64 for several reasons, i. e., QEMU and FreeBSD are both fast moving targets (esp. src/lib/msun), some long double math functions don't exist on FreeBSD, GCC in base system doesn't build QEMU because of several optimization bugs specific to AMD64, etc. 1. Install GCC 3.4 from ports. Anything newer than 20050316 should work. (Theoretically you can use gcc40 newer than 20041127 but not verified. Actually I am using patched version of src/contrib/gcc. ;-) 2. Install following dependencies from ports: devel/gmake (of course) net/samba devel/sdl12 I believe samba is optional but sdl12 is not. It doesn't work without SDL because `-nographic' option is broken. I believe it is an upstream bug (related to FreeBSD's pty or termios, i. e., fail to get correct term size and segfault) but I couldn't pin-point the culprit yet. In fact, I didn't bother too much because SDL worked just fine. ;-) 3. Get the latest QEMU source from: http://www.dad-answers.com/qemu/ The file name is something like qemu-snapshot-*.tar.bz2. 4. Extract the tarball, chdir to it, and do the following: mkdir -p bsd/amd64 patch -p0 < ${PATCHDIR}/qemu-snapshot-fbsd.diff patch -p0 < ${PATCHDIR}/qemu-libmath-amd64.diff ./configure -cc=${GCC_BIN} gmake gmake install ${PATCHDIR} is where the attached patches are saved and ${GCC_BIN} is gcc path, e. g., /usr/local/bin/gcc34 for GCC 3.4.4 and /usr/local/bin/gcc40 for GCC 4.0.0, etc. I was able to run DragonFly 1.2 CD-ROM on i386 emulation (qemu) and Mandrake Linux 10.2rc1 for amd64 on x86-64 emulation (qemu-system-x86-64). ppc (qemu-system-ppc) and sparc (qemu-system-sparc) emulators are not tested. Enjoy, Jung-uk Kim Note 1: The limitations of this patch should be the same from ports because large portion was taken from it: http://www.freebsd.org/cgi/cvsweb.cgi/~checkout~/ports/emulators/qemu/pkg-message?rev=1.7&content-type=text/plain Note 2: qemu-libmath-amd64.diff contains C99 long double math functions taken from glibc-2.3.5 and modified for FreeBSD/amd64: http://ftp.gnu.org/gnu/glibc/ http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/?cvsroot=glibc rintl() sysdeps/i386/fpu/s_rintl.c atan2l() sysdeps/i386/fpu/e_atan2l.c sqrtl() sysdeps/i386/fpu/e_sqrtl.c llrintl() sysdeps/x86_64/fpu/s_llrintl.S lrintl() sysdeps/x86_64/fpu/s_llrintl.S sinl() sysdeps/x86_64/fpu/s_sinl.S cosl() sysdeps/x86_64/fpu/s_cosl.S tanl() sysdeps/x86_64/fpu/s_tanl.S logl() sysdeps/x86_64/fpu/e_logl.S powl() sysdeps/x86_64/fpu/e_powl.S remainderl() sysdeps/x86_64/fpu/e_remainderl.S Just enough to compile QEMU snapshot until we complete C99 project. ;-) Similarly you can add other architectures under bsd/${MACHINE_ARCH}. --Boundary-00=_OKYXC+kkn1fOkqy Content-Type: text/x-diff; charset="us-ascii"; name="qemu-libmath-amd64.diff" Content-Transfer-Encoding: 8bit Content-Disposition: attachment; filename="qemu-libmath-amd64.diff" diff -urN bsd.orig/Makefile bsd/Makefile --- bsd.orig/Makefile Wed Dec 31 19:00:00 1969 +++ bsd/Makefile Wed Apr 13 12:43:36 2005 @@ -0,0 +1,22 @@ +SRCS= ${MACHINE_ARCH}/e_atan2l.c \ + ${MACHINE_ARCH}/e_logl.S \ + ${MACHINE_ARCH}/e_powl.S \ + ${MACHINE_ARCH}/e_remainderl.S \ + ${MACHINE_ARCH}/e_sqrtl.c \ + ${MACHINE_ARCH}/s_cosl.S \ + ${MACHINE_ARCH}/s_llrintl.S \ + ${MACHINE_ARCH}/s_lrintl.S \ + ${MACHINE_ARCH}/s_rintl.c \ + ${MACHINE_ARCH}/s_sinl.S \ + ${MACHINE_ARCH}/s_tanl.S + +OBJS= ${SRCS:R:S/$/.o/} + +all: libmath.a + +libmath.a: ${OBJS} + rm -f $@ + ${AR} rcs $@ ${OBJS:T} + +clean: + rm -f ${OBJS:T} libmath.a diff -urN bsd.orig/amd64/e_atan2l.c bsd/amd64/e_atan2l.c --- bsd.orig/amd64/e_atan2l.c Wed Dec 31 19:00:00 1969 +++ bsd/amd64/e_atan2l.c Tue Apr 12 18:53:57 2005 @@ -0,0 +1,16 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * + * Adapted for `long double' by Ulrich Drepper . + */ + +long double +atan2l (long double y, long double x) +{ + long double res; + + asm ("fpatan" : "=t" (res) : "u" (y), "0" (x) : "st(1)"); + + return res; +} diff -urN bsd.orig/amd64/e_logl.S bsd/amd64/e_logl.S --- bsd.orig/amd64/e_logl.S Wed Dec 31 19:00:00 1969 +++ bsd/amd64/e_logl.S Tue Apr 12 18:53:59 2005 @@ -0,0 +1,34 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * + * Adapted for `long double' by Ulrich Drepper . + * Adapted for x86-64 by Andreas Jaeger . + */ + +#include + +RCSID("$NetBSD: $") + +one: .double 1.0 +limit: .double 0.29 + + .text +ENTRY(logl) + fldln2 // log(2) + fldt 8(%rsp) // x : log(2) + fld %st // x : x : log(2) + fsubl one(%rip) // x-1 : x : log(2) + fld %st // x-1 : x-1 : x : log(2) + fabs // |x-1| : x-1 : x : log(2) + fcompl limit(%rip) // x-1 : x : log(2) + fnstsw // x-1 : x : log(2) + andb $0x45, %ah + jz 2f + fstp %st(1) // x-1 : log(2) + fyl2xp1 // log(x) + ret + +2: fstp %st(0) // x : log(2) + fyl2x // log(x) + ret diff -urN bsd.orig/amd64/e_powl.S bsd/amd64/e_powl.S --- bsd.orig/amd64/e_powl.S Wed Dec 31 19:00:00 1969 +++ bsd/amd64/e_powl.S Tue Apr 12 18:53:59 2005 @@ -0,0 +1,301 @@ +/* ix87 specific implementation of pow function. + Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1996. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +inf_zero: +infinity: + .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f +zero: .double 0.0 +minf_mzero: +minfinity: + .byte 0, 0, 0, 0, 0, 0, 0xf0, 0xff +mzero: + .byte 0, 0, 0, 0, 0, 0, 0, 0x80 +one: .double 1.0 +limit: .double 0.29 +p63: + .byte 0, 0, 0, 0, 0, 0, 0xe0, 0x43 + + .text +ENTRY(powl) + fldt 24(%rsp) // y + fxam + + + fnstsw + movb %ah, %dl + andb $0x45, %ah + cmpb $0x40, %ah // is y == 0 ? + je 11f + + cmpb $0x05, %ah // is y == ±inf ? + je 12f + + cmpb $0x01, %ah // is y == NaN ? + je 30f + + fldt 8(%rsp) // x : y + + fxam + fnstsw + movb %ah, %dh + andb $0x45, %ah + cmpb $0x40, %ah + je 20f // x is ±0 + + cmpb $0x05, %ah + je 15f // x is ±inf + + fxch // y : x + + /* fistpll raises invalid exception for |y| >= 1L<<63. */ + fldl p63(%rip) // 1L<<63 : y : x + fld %st(1) // y : 1L<<63 : y : x + fabs // |y| : 1L<<63 : y : x + fcomip %st(1), %st // 1L<<63 : y : x + fstp %st(0) // y : x + jnc 2f + + /* First see whether `y' is a natural number. In this case we + can use a more precise algorithm. */ + fld %st // y : y : x + fistpll -8(%rsp) // y : x + fildll -8(%rsp) // int(y) : y : x + fucomip %st(1),%st // y : x + jne 2f + + /* OK, we have an integer value for y. */ + mov -8(%rsp),%eax + mov -4(%rsp),%edx + orl $0, %edx + fstp %st(0) // x + jns 4f // y >= 0, jump + fdivrl one(%rip) // 1/x (now referred to as x) + negl %eax + adcl $0, %edx + negl %edx +4: fldl one(%rip) // 1 : x + fxch + +6: shrdl $1, %edx, %eax + jnc 5f + fxch + fmul %st(1) // x : ST*x + fxch +5: fmul %st(0), %st // x*x : ST*x + shrl $1, %edx + movl %eax, %ecx + orl %edx, %ecx + jnz 6b + fstp %st(0) // ST*x + ret + + /* y is ±NAN */ +30: fldt 8(%rsp) // x : y + fldl one(%rip) // 1.0 : x : y + fucomip %st(1),%st // x : y + je 31f + fxch // y : x +31: fstp %st(1) + ret + +2: /* y is a real number. */ + fxch // x : y + fldl one(%rip) // 1.0 : x : y + fld %st(1) // x : 1.0 : x : y + fsub %st(1) // x-1 : 1.0 : x : y + fabs // |x-1| : 1.0 : x : y + fcompl limit(%rip) // 1.0 : x : y + fnstsw + fxch // x : 1.0 : y + test $4500,%eax + jz 7f + fsub %st(1) // x-1 : 1.0 : y + fyl2xp1 // log2(x) : y + jmp 8f + +7: fyl2x // log2(x) : y +8: fmul %st(1) // y*log2(x) : y + fxam + fnstsw + andb $0x45, %ah + cmpb $0x05, %ah // is y*log2(x) == ±inf ? + je 28f + fst %st(1) // y*log2(x) : y*log2(x) + frndint // int(y*log2(x)) : y*log2(x) + fsubr %st, %st(1) // int(y*log2(x)) : fract(y*log2(x)) + fxch // fract(y*log2(x)) : int(y*log2(x)) + f2xm1 // 2^fract(y*log2(x))-1 : int(y*log2(x)) + faddl one(%rip) // 2^fract(y*log2(x)) : int(y*log2(x)) + fscale // 2^fract(y*log2(x))*2^int(y*log2(x)) : int(y*log2(x)) + fstp %st(1) // 2^fract(y*log2(x))*2^int(y*log2(x)) + ret + +28: fstp %st(1) // y*log2(x) + fldl one(%rip) // 1 : y*log2(x) + fscale // 2^(y*log2(x)) : y*log2(x) + fstp %st(1) // 2^(y*log2(x)) + ret + + // pow(x,±0) = 1 +11: fstp %st(0) // pop y + fldl one(%rip) + ret + + // y == ±inf +12: fstp %st(0) // pop y + fldt 8(%rsp) // x + fabs + fcompl one(%rip) // < 1, == 1, or > 1 + fnstsw + andb $0x45, %ah + cmpb $0x45, %ah + je 13f // jump if x is NaN + + cmpb $0x40, %ah + je 14f // jump if |x| == 1 + + shlb $1, %ah + xorb %ah, %dl + andl $2, %edx +#ifdef PIC + lea inf_zero(%rip),%rcx + fldl (%rcx, %rdx, 4) +#else + fldl inf_zero(,%rdx, 4) +#endif + ret + +14: fldl one(%rip) + ret + +13: fldt 8(%rsp) // load x == NaN + ret + + // x is ±inf +15: fstp %st(0) // y + testb $2, %dh + jz 16f // jump if x == +inf + + // We must find out whether y is an odd integer. + fld %st // y : y + fistpll -8(%rsp) // y + fildll -8(%rsp) // int(y) : y + fucomip %st(1),%st + ffreep %st // + jne 17f + + // OK, the value is an integer, but is it odd? + mov -8(%rsp), %eax + mov -4(%rsp), %edx + andb $1, %al + jz 18f // jump if not odd + // It's an odd integer. + shrl $31, %edx +#ifdef PIC + lea minf_mzero(%rip),%rcx + fldl (%rcx, %rdx, 8) +#else + fldl minf_mzero(,%rdx, 8) +#endif + ret + +16: fcompl zero(%rip) + fnstsw + shrl $5, %eax + andl $8, %eax +#ifdef PIC + lea inf_zero(%rip),%rcx + fldl (%rcx, %rax, 1) +#else + fldl inf_zero(,%rax, 1) +#endif + ret + +17: shll $30, %edx // sign bit for y in right position +18: shrl $31, %edx +#ifdef PIC + lea inf_zero(%rip),%rcx + fldl (%rcx, %rdx, 8) +#else + fldl inf_zero(,%rdx, 8) +#endif + ret + + // x is ±0 +20: fstp %st(0) // y + testb $2, %dl + jz 21f // y > 0 + + // x is ±0 and y is < 0. We must find out whether y is an odd integer. + testb $2, %dh + jz 25f + + fld %st // y : y + fistpll -8(%rsp) // y + fildll -8(%rsp) // int(y) : y + fucomip %st(1),%st + ffreep %st // + jne 26f + + // OK, the value is an integer, but is it odd? + mov -8(%rsp),%eax + mov -4(%rsp),%edx + andb $1, %al + jz 27f // jump if not odd + // It's an odd integer. + // Raise divide-by-zero exception and get minus infinity value. + fldl one(%rip) + fdivl zero(%rip) + fchs + ret + +25: fstp %st(0) +26: +27: // Raise divide-by-zero exception and get infinity value. + fldl one(%rip) + fdivl zero(%rip) + ret + + // x is ±0 and y is > 0. We must find out whether y is an odd integer. +21: testb $2, %dh + jz 22f + + fld %st // y : y + fistpll -8(%rsp) // y + fildll -8(%rsp) // int(y) : y + fucomip %st(1),%st + ffreep %st // + jne 23f + + // OK, the value is an integer, but is it odd? + mov -8(%rsp),%eax + mov -4(%rsp),%edx + andb $1, %al + jz 24f // jump if not odd + // It's an odd integer. + fldl mzero(%rip) + ret + +22: fstp %st(0) +23: +24: fldl zero(%rip) + ret diff -urN bsd.orig/amd64/e_remainderl.S bsd/amd64/e_remainderl.S --- bsd.orig/amd64/e_remainderl.S Wed Dec 31 19:00:00 1969 +++ bsd/amd64/e_remainderl.S Tue Apr 12 18:53:59 2005 @@ -0,0 +1,19 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * + * Adapted for `long double' by Ulrich Drepper . + * Adapted for x86-64 by Andreas Jaeger . + */ + +#include + +ENTRY(remainderl) + fldt 24(%rsp) + fldt 8(%rsp) +1: fprem1 + fstsw %ax + testl $0x400,%eax + jnz 1b + fstp %st(1) + ret diff -urN bsd.orig/amd64/e_sqrtl.c bsd/amd64/e_sqrtl.c --- bsd.orig/amd64/e_sqrtl.c Wed Dec 31 19:00:00 1969 +++ bsd/amd64/e_sqrtl.c Tue Apr 12 18:53:57 2005 @@ -0,0 +1,16 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * + * Adapted for `long double' by Ulrich Drepper . + */ + +long double +sqrtl (long double x) +{ + long double res; + + asm ("fsqrt" : "=t" (res) : "0" (x)); + + return res; +} diff -urN bsd.orig/amd64/s_cosl.S bsd/amd64/s_cosl.S --- bsd.orig/amd64/s_cosl.S Wed Dec 31 19:00:00 1969 +++ bsd/amd64/s_cosl.S Tue Apr 12 18:53:59 2005 @@ -0,0 +1,30 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * + * Adapted for `long double' by Ulrich Drepper . + * Adapted for x86-64 by Andreas Jaeger . + */ + +#include + +RCSID("$NetBSD: $") + +ENTRY(cosl) + fldt 8(%rsp) + fcos + fnstsw %ax + testl $0x400,%eax + jnz 1f + ret + +1: fldpi + fadd %st(0) + fxch %st(1) +2: fprem1 + fnstsw %ax + testl $0x400,%eax + jnz 2b + fstp %st(1) + fcos + ret diff -urN bsd.orig/amd64/s_llrintl.S bsd/amd64/s_llrintl.S --- bsd.orig/amd64/s_llrintl.S Wed Dec 31 19:00:00 1969 +++ bsd/amd64/s_llrintl.S Tue Apr 12 18:53:59 2005 @@ -0,0 +1,28 @@ +/* Round argument to nearest integral value according to current rounding + direction. + Copyright (C) 1997, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +ENTRY(llrintl) + fldt 8(%rsp) + fistpll -8(%rsp) + fwait + movq -8(%rsp),%rax + ret diff -urN bsd.orig/amd64/s_lrintl.S bsd/amd64/s_lrintl.S --- bsd.orig/amd64/s_lrintl.S Wed Dec 31 19:00:00 1969 +++ bsd/amd64/s_lrintl.S Tue Apr 12 18:53:59 2005 @@ -0,0 +1,28 @@ +/* Round argument to nearest integral value according to current rounding + direction. + Copyright (C) 1997, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +ENTRY(lrintl) + fldt 8(%rsp) + fistpll -8(%rsp) + fwait + movq -8(%rsp),%rax + ret diff -urN bsd.orig/amd64/s_rintl.c bsd/amd64/s_rintl.c --- bsd.orig/amd64/s_rintl.c Wed Dec 31 19:00:00 1969 +++ bsd/amd64/s_rintl.c Tue Apr 12 18:53:57 2005 @@ -0,0 +1,14 @@ +/* + * Written by J.T. Conklin . + * Changes for long double by Ulrich Drepper + * Public domain. + */ + +long double +rintl (long double x) +{ + long double res; + + asm ("frndint" : "=t" (res) : "0" (x)); + return res; +} diff -urN bsd.orig/amd64/s_sinl.S bsd/amd64/s_sinl.S --- bsd.orig/amd64/s_sinl.S Wed Dec 31 19:00:00 1969 +++ bsd/amd64/s_sinl.S Tue Apr 12 18:53:59 2005 @@ -0,0 +1,27 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * + * Adapted for `long double' by Ulrich Drepper . + * Adapted for x86-64 by Andreas Jaeger . + */ + +#include + +ENTRY(sinl) + fldt 8(%rsp) + fsin + fnstsw %ax + testl $0x400,%eax + jnz 1f + ret +1: fldpi + fadd %st(0) + fxch %st(1) +2: fprem1 + fnstsw %ax + testl $0x400,%eax + jnz 2b + fstp %st(1) + fsin + ret diff -urN bsd.orig/amd64/s_tanl.S bsd/amd64/s_tanl.S --- bsd.orig/amd64/s_tanl.S Wed Dec 31 19:00:00 1969 +++ bsd/amd64/s_tanl.S Tue Apr 12 18:53:59 2005 @@ -0,0 +1,32 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * + * Adapted for `long double' by Ulrich Drepper . + * Adapted for x86-64 by Andreas Jaeger . + */ + +#include + +RCSID("$NetBSD: $") + +ENTRY(tanl) + fldt 8(%rsp) + fptan + fnstsw %ax + testl $0x400,%eax + jnz 1f + fstp %st(0) + ret + +1: fldpi + fadd %st(0) + fxch %st(1) +2: fprem1 + fstsw %ax + testl $0x400,%eax + jnz 2b + fstp %st(1) + fptan + fstp %st(0) + ret --Boundary-00=_OKYXC+kkn1fOkqy Content-Type: text/x-diff; charset="us-ascii"; name="qemu-snapshot-fbsd.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="qemu-snapshot-fbsd.diff" Index: Makefile =================================================================== RCS file: /cvsroot/qemu/qemu/Makefile,v retrieving revision 1.82 diff -u -r1.82 Makefile --- Makefile 10 Feb 2005 21:48:51 -0000 1.82 +++ Makefile 13 Apr 2005 18:06:10 -0000 @@ -13,7 +13,7 @@ endif DOCS=qemu-doc.html qemu-tech.html qemu.1 qemu-img.1 -all: dyngen$(EXESUF) $(TOOLS) $(DOCS) +all: bsd/libmath.a dyngen$(EXESUF) $(TOOLS) $(DOCS) for d in $(TARGET_DIRS); do \ $(MAKE) -C $$d $@ || exit 1 ; \ done @@ -21,6 +21,9 @@ $(MAKE) -C kqemu endif +bsd/libmath.a: + ( cd bsd ; /usr/bin/make ) + qemu-img$(EXESUF): qemu-img.c block.c block-cow.c block-qcow.c aes.c block-vmdk.c block-cloop.c block-dmg.c $(CC) -DQEMU_TOOL $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $@ $^ -lz $(LIBS) @@ -29,6 +32,7 @@ clean: # avoid old build problems by removing potentially incorrect old files + ( cd bsd ; /usr/bin/make clean ) rm -f config.mak config.h op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h rm -f *.o *.a $(TOOLS) dyngen$(EXESUF) TAGS *.pod *~ */*~ $(MAKE) -C tests clean @@ -82,7 +86,7 @@ # documentation %.html: %.texi - texi2html -monolithic -number $< + -texi2html -monolithic -number $< qemu.1: qemu-doc.texi ./texi2pod.pl $< qemu.pod Index: Makefile.target =================================================================== RCS file: /cvsroot/qemu/qemu/Makefile.target,v retrieving revision 1.63 diff -u -r1.63 Makefile.target --- Makefile.target 7 Apr 2005 22:20:27 -0000 1.63 +++ Makefile.target 13 Apr 2005 18:06:10 -0000 @@ -211,7 +211,7 @@ ######################################################### -DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DSMBD=\"/usr/local/sbin/smbd\" LIBS+=-lm ifndef CONFIG_USER_ONLY LIBS+=-lz @@ -388,8 +388,8 @@ VL_LDFLAGS+=-Wl,-G0 -Wl,-T,$(SRC_PATH)/ia64.ld endif -$(QEMU_SYSTEM): $(VL_OBJS) libqemu.a - $(CC) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(VL_LIBS) +$(QEMU_SYSTEM): $(VL_OBJS) libqemu.a ../bsd/libmath.a + $(CC) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(VL_LIBS) ../bsd/libmath.a cocoa.o: cocoa.m $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $< Index: block.c =================================================================== RCS file: /cvsroot/qemu/qemu/block.c,v retrieving revision 1.16 diff -u -r1.16 block.c --- block.c 12 Dec 2004 11:24:44 -0000 1.16 +++ block.c 13 Apr 2005 18:06:10 -0000 @@ -21,6 +21,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + +#include "config-host.h" + +#ifdef _BSD +#include +#include +#include +#include +#include +#endif + #include "vl.h" #include "block_int.h" @@ -92,14 +103,25 @@ { int fd, ret, score, score_max; BlockDriver *drv1, *drv; - uint8_t buf[1024]; + uint8_t *buf; + size_t bufsize = 1024; + u_int sectorsize = 512; fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE); if (fd < 0) return NULL; - ret = read(fd, buf, sizeof(buf)); +#ifdef DIOCGSECTORSIZE + if (!ioctl(fd, DIOCGSECTORSIZE, §orsize) && + sectorsize > bufsize) + bufsize = sectorsize; +#endif + buf = malloc(bufsize); + if (!buf) + return NULL; + ret = read(fd, buf, bufsize); if (ret < 0) { close(fd); + free(buf); return NULL; } close(fd); @@ -113,6 +135,7 @@ drv = drv1; } } + free(buf); return drv; } @@ -532,6 +555,15 @@ return -1; bs->read_only = 1; } +#ifdef _BSD + struct stat sb; + if (!fstat(fd,&sb) && (S_IFCHR & sb.st_mode)) { +#ifdef DIOCGMEDIASIZE + if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size)) +#endif + size = lseek(fd, 0LL, SEEK_END); + } else +#endif size = lseek(fd, 0, SEEK_END); bs->total_sectors = size / 512; s->fd = fd; Index: configure =================================================================== RCS file: /cvsroot/qemu/qemu/configure,v retrieving revision 1.61 diff -u -r1.61 configure --- configure 13 Mar 2005 16:51:53 -0000 1.61 +++ configure 13 Apr 2005 18:06:10 -0000 @@ -18,7 +18,7 @@ # default parameters prefix="" -interp_prefix="/usr/gnemul/qemu-%M" +interp_prefix="/usr/local/bin/qemu-%M" static="no" cross_prefix="" cc="gcc" @@ -255,7 +255,7 @@ if test -z "$sdl" ; then -sdl_config="sdl-config" +sdl_config="sdl11-config" sdl=no sdl_static=no @@ -344,7 +344,7 @@ if test -z "$prefix" ; then prefix="/usr/local" fi -mandir="$prefix/share/man" +mandir="$prefix/man" datadir="$prefix/share/qemu" docdir="$prefix/share/doc/qemu" bindir="$prefix/bin" Index: vl.c =================================================================== RCS file: /cvsroot/qemu/qemu/vl.c,v retrieving revision 1.126 diff -u -r1.126 vl.c --- vl.c 7 Apr 2005 22:20:28 -0000 1.126 +++ vl.c 13 Apr 2005 18:06:11 -0000 @@ -45,6 +45,9 @@ #ifndef __APPLE__ #include #endif +#ifdef __FreeBSD__ +#include +#endif #else #include #include @@ -754,6 +757,14 @@ case QEMU_TIMER_REALTIME: #ifdef _WIN32 return GetTickCount(); +#elif defined(_BSD) + { + struct timeval r; + if (!gettimeofday(&r, NULL)) { + return ((timer_freq * 1000LL) * (int64_t)r.tv_sec + + ((int64_t)r.tv_usec * timer_freq) / 1000) / timer_freq; + } + } #else { struct tms tp; @@ -1579,8 +1590,13 @@ fclose(f); atexit(smb_exit); +#if defined(__FreeBSD__) + snprintf(smb_cmdline, sizeof(smb_cmdline), SMBD " -s %s", + smb_conf); +#else snprintf(smb_cmdline, sizeof(smb_cmdline), "/usr/sbin/smbd -s %s", smb_conf); +#endif slirp_add_exec(0, smb_cmdline, 4, 139); } @@ -1589,6 +1605,34 @@ #endif /* CONFIG_SLIRP */ +#ifdef __FreeBSD__ +#define LOAD_QUIETLY 1 +#define LOAD_VERBOSLY 2 + +int +loadmodules(int how, const char *module, ...) +{ + int loaded = 0; + va_list ap; + + va_start(ap, module); +#ifndef NO_MODULES + while (module != NULL) { + if (modfind(module) == -1) { + if (kldload(module) == -1) { + if (how == LOAD_VERBOSLY) + fprintf(stderr, "%s: Cannot load module\n", module); + } else + loaded++; + } + module = va_arg(ap, const char *); + } + va_end(ap); +#endif + return loaded; +} +#endif + #if !defined(_WIN32) #ifdef _BSD static int tun_open(char *ifname, int ifname_size) @@ -1597,11 +1641,55 @@ char *dev; struct stat s; +#ifdef __FreeBSD__ + int i, kldtried = 0, enoentcount = 0, err = 0; + char dname[100]; +#ifdef USE_DEVTAP + /* + * 5.x has /dev/tap, but that seems to just blindly increase its + * couter on every open() for some people(??), i.e. on every qemu run. + */ + i = -1; +#else + i = 0; +#endif + for (; i < 10; i++) { + if (i == -1) + strcpy(dname, "/dev/tap"); + else + snprintf(dname, sizeof dname, "%s%d", + "/dev/tap", i); + fd = open(dname, O_RDWR); + if (fd >= 0) + break; + else if (errno == ENXIO || errno == ENOENT) { + if (i == 0 && !kldtried++) { + /* + * Attempt to load the tunnel interface KLD if it isn't loaded + * already. + */ + if (loadmodules(LOAD_VERBOSLY, "if_tap", NULL)) + i = -1; + continue; + } + if (errno != ENOENT || ++enoentcount > 3) { + err = errno; + break; + } + } else + err = errno; + } + if (fd < 0) { + fprintf(stderr, "warning: could not open %s (%s): no virtual network emulation\n", dname, strerror(err)); + return -1; + } +#else fd = open("/dev/tap", O_RDWR); if (fd < 0) { - fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n"); + fprintf(stderr, "warning: could not open /dev/tap (%s): no virtual network emulation\n", strerror(errno)); return -1; } +#endif fstat(fd, &s); dev = devname(s.st_rdev, S_IFCHR); Index: x86_64.ld =================================================================== RCS file: /cvsroot/qemu/qemu/x86_64.ld,v retrieving revision 1.1 diff -u -r1.1 x86_64.ld --- x86_64.ld 6 Jan 2005 20:50:00 -0000 1.1 +++ x86_64.ld 13 Apr 2005 18:06:11 -0000 @@ -2,7 +2,7 @@ OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") OUTPUT_ARCH(i386:x86-64) ENTRY(_start) -SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib64"); +SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/usr/X11R6/lib"); SECTIONS { /* Read-only sections, merged into text segment: */ Index: fpu/softfloat-native.c =================================================================== RCS file: /cvsroot/qemu/qemu/fpu/softfloat-native.c,v retrieving revision 1.2 diff -u -r1.2 softfloat-native.c --- fpu/softfloat-native.c 20 Mar 2005 10:33:58 -0000 1.2 +++ fpu/softfloat-native.c 13 Apr 2005 18:06:12 -0000 @@ -6,7 +6,7 @@ void set_float_rounding_mode(int val STATUS_PARAM) { STATUS(float_rounding_mode) = val; -#if defined(_BSD) && !defined(__APPLE__) +#if defined(_BSD) && !defined(__APPLE__) && !defined(__FreeBSD__) fpsetround(val); #elif defined(__arm__) /* nothing to do */ @@ -22,7 +22,7 @@ } #endif -#if defined(_BSD) +#if defined(_BSD) && !defined(__FreeBSD__) #define lrint(d) ((int32_t)rint(d)) #define llrint(d) ((int64_t)rint(d)) #endif Index: fpu/softfloat-native.h =================================================================== RCS file: /cvsroot/qemu/qemu/fpu/softfloat-native.h,v retrieving revision 1.2 diff -u -r1.2 softfloat-native.h --- fpu/softfloat-native.h 20 Mar 2005 10:33:58 -0000 1.2 +++ fpu/softfloat-native.h 13 Apr 2005 18:06:12 -0000 @@ -1,6 +1,6 @@ /* Native implementation of soft float functions */ #include -#if defined(_BSD) && !defined(__APPLE__) +#if defined(_BSD) && !defined(__APPLE__) && !defined(__FreeBSD__) #include #else #include @@ -33,7 +33,7 @@ /*---------------------------------------------------------------------------- | Software IEC/IEEE floating-point rounding mode. *----------------------------------------------------------------------------*/ -#if defined(_BSD) && !defined(__APPLE__) +#if defined(_BSD) && !defined(__APPLE__) && !defined(__FreeBSD__) enum { float_round_nearest_even = FP_RN, float_round_down = FE_RM, Index: fpu/softfloat.h =================================================================== RCS file: /cvsroot/qemu/qemu/fpu/softfloat.h,v retrieving revision 1.2 diff -u -r1.2 softfloat.h --- fpu/softfloat.h 13 Mar 2005 18:52:29 -0000 1.2 +++ fpu/softfloat.h 13 Apr 2005 18:06:12 -0000 @@ -84,7 +84,8 @@ #define FLOAT128 #else /* native float support */ -#if (defined(__i386__) || defined(__x86_64__)) && !defined(_BSD) +#if (defined(__i386__) || defined(__x86_64__)) && \ + (!defined(_BSD) || defined(__FreeBSD__)) #define FLOATX80 #endif #endif /* !CONFIG_SOFTFLOAT */ Index: slirp/bootp.c =================================================================== RCS file: /cvsroot/qemu/qemu/slirp/bootp.c,v retrieving revision 1.6 diff -u -r1.6 bootp.c --- slirp/bootp.c 3 Oct 2004 11:44:41 -0000 1.6 +++ slirp/bootp.c 13 Apr 2005 18:06:12 -0000 @@ -29,11 +29,12 @@ #define START_ADDR 15 -#define LEASE_TIME (24 * 3600) +#define LEASE_TIME (120) typedef struct { uint8_t allocated; uint8_t macaddr[6]; + int time; } BOOTPClient; BOOTPClient bootp_clients[NB_ADDR]; @@ -51,15 +52,19 @@ { BOOTPClient *bc; int i; + int now = time(NULL); for(i = 0; i < NB_ADDR; i++) { if (!bootp_clients[i].allocated) goto found; } + for(i = 0; i < NB_ADDR; i++) { + if (now-bootp_clients[i].time > 3*LEASE_TIME) + goto found; + } return NULL; found: bc = &bootp_clients[i]; - bc->allocated = 1; paddr->s_addr = htonl(ntohl(special_addr.s_addr) | (i + START_ADDR)); return bc; } @@ -81,13 +86,36 @@ return bc; } -static void dhcp_decode(const uint8_t *buf, int size, - int *pmsg_type) +static BOOTPClient *find_reqaddr(struct in_addr *paddr, struct in_addr *reqaddr, const uint8_t *macaddr) +{ + BOOTPClient *bc=NULL; + int i; + /*check the net prefix*/ + if ((ntohl(reqaddr->s_addr) & 0xffffff00) == + (ntohl(special_addr.s_addr) & 0xffffff00)) { + i=(ntohl(reqaddr->s_addr) & 0xff) - START_ADDR; + if (i>=0 && i< NB_ADDR) { + bc = &bootp_clients[i]; + if (bc->allocated && + (memcmp(macaddr, bootp_clients[i].macaddr, 6)==0)) { + paddr->s_addr = reqaddr->s_addr; + return bc; + } + else + bc=NULL; + } + } + return bc; +} + +static void dhcp_decode(const uint8_t *buf, int size, int *pmsg_type, + struct sockaddr_in *preqaddr) { const uint8_t *p, *p_end; int len, tag; *pmsg_type = 0; + preqaddr->sin_addr.s_addr=htonl(0L); p = buf; p_end = buf + size; @@ -114,6 +142,10 @@ if (len >= 1) *pmsg_type = p[0]; break; + case RFC2132_REQ_ADDR: + if (len == 4) { + memcpy(&(preqaddr->sin_addr),p,4); + } default: break; } @@ -127,14 +159,14 @@ BOOTPClient *bc; struct mbuf *m; struct bootp_t *rbp; - struct sockaddr_in saddr, daddr; + struct sockaddr_in saddr, daddr, reqaddr; struct in_addr dns_addr; int dhcp_msg_type, val; - uint8_t *q; + uint8_t *q, replytype; /* extract exact DHCP msg type */ - dhcp_decode(bp->bp_vend, DHCP_OPT_LEN, &dhcp_msg_type); - dprintf("bootp packet op=%d msgtype=%d\n", bp->bp_op, dhcp_msg_type); + dhcp_decode(bp->bp_vend, DHCP_OPT_LEN, &dhcp_msg_type,&reqaddr); + dprintf("bootp packet op=%d msgtype=%d reqaddr=%x\n", bp->bp_op, dhcp_msg_type,ntohl(reqaddr.sin_addr.s_addr)); if (dhcp_msg_type == 0) dhcp_msg_type = DHCPREQUEST; /* Force reply for old BOOTP clients */ @@ -152,21 +184,18 @@ m->m_data += sizeof(struct udpiphdr); memset(rbp, 0, sizeof(struct bootp_t)); - if (dhcp_msg_type == DHCPDISCOVER) { - new_addr: - bc = get_new_addr(&daddr.sin_addr); - if (!bc) { - dprintf("no address left\n"); - return; - } - memcpy(bc->macaddr, client_ethaddr, 6); - } else { - bc = find_addr(&daddr.sin_addr, bp->bp_hwaddr); - if (!bc) { - /* if never assigned, behaves as if it was already - assigned (windows fix because it remembers its address) */ - goto new_addr; - } + bc=NULL; + daddr.sin_addr.s_addr=htonl(0L); + if (dhcp_msg_type == DHCPREQUEST) { + if (reqaddr.sin_addr.s_addr != htonl(0L)) + bc = find_reqaddr(&daddr.sin_addr, &reqaddr.sin_addr, bp->bp_hwaddr); + else + bc = find_addr(&daddr.sin_addr, bp->bp_hwaddr); + } + else if (dhcp_msg_type == DHCPDISCOVER) { + bc = find_addr(&daddr.sin_addr, bp->bp_hwaddr); + if (!bc) + bc = get_new_addr(&daddr.sin_addr); } dprintf("offered addr=%08x\n", ntohl(daddr.sin_addr.s_addr)); @@ -181,25 +210,27 @@ rbp->bp_hlen = 6; memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, 6); - rbp->bp_yiaddr = daddr.sin_addr; /* Client IP address */ - rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */ + rbp->bp_yiaddr = daddr.sin_addr; /* IP address */ q = rbp->bp_vend; memcpy(q, rfc1533_cookie, 4); q += 4; - if (dhcp_msg_type == DHCPDISCOVER) { - *q++ = RFC2132_MSG_TYPE; - *q++ = 1; - *q++ = DHCPOFFER; - } else if (dhcp_msg_type == DHCPREQUEST) { - *q++ = RFC2132_MSG_TYPE; - *q++ = 1; - *q++ = DHCPACK; - } - - if (dhcp_msg_type == DHCPDISCOVER || - dhcp_msg_type == DHCPREQUEST) { + if (bc != NULL) { + memcpy(bc->macaddr, client_ethaddr, 6); + bc->allocated = 1; + bc->time = time(NULL); + replytype=(dhcp_msg_type == DHCPDISCOVER)?DHCPOFFER:DHCPACK; + } + else + replytype=DHCPNACK; + + *q++ = RFC2132_MSG_TYPE; + *q++ = 1; + *q++ = replytype; + + if ((dhcp_msg_type == DHCPDISCOVER || + dhcp_msg_type == DHCPREQUEST) && replytype!=DHCPNACK) { *q++ = RFC2132_SRV_ID; *q++ = 4; memcpy(q, &saddr.sin_addr, 4); Index: slirp/bootp.h =================================================================== RCS file: /cvsroot/qemu/qemu/slirp/bootp.h,v retrieving revision 1.1 diff -u -r1.1 bootp.h --- slirp/bootp.h 22 Apr 2004 00:10:47 -0000 1.1 +++ slirp/bootp.h 13 Apr 2005 18:06:12 -0000 @@ -71,6 +71,7 @@ #define DHCPOFFER 2 #define DHCPREQUEST 3 #define DHCPACK 5 +#define DHCPNACK 6 #define RFC1533_VENDOR_MAJOR 0 #define RFC1533_VENDOR_MINOR 0 Index: slirp/slirp_config.h =================================================================== RCS file: /cvsroot/qemu/qemu/slirp/slirp_config.h,v retrieving revision 1.3 diff -u -r1.3 slirp_config.h --- slirp/slirp_config.h 12 Jul 2004 22:33:05 -0000 1.3 +++ slirp/slirp_config.h 13 Apr 2005 18:06:12 -0000 @@ -92,7 +92,7 @@ #undef BAD_SPRINTF /* Define if you have readv */ -#undef HAVE_READV +#define HAVE_READV /* Define if iovec needs to be declared */ #undef DECLARE_IOVEC @@ -104,7 +104,7 @@ #undef DECLARE_SPRINTF /* Define if you have a POSIX.1 sys/wait.h */ -#undef HAVE_SYS_WAIT_H +#define HAVE_SYS_WAIT_H /* Define if you have sys/select.h */ #undef HAVE_SYS_SELECT_H @@ -122,7 +122,7 @@ #endif /* Define if you have sys/signal.h */ -#undef HAVE_SYS_SIGNAL_H +#define HAVE_SYS_SIGNAL_H /* Define if you have sys/stropts.h */ #undef HAVE_SYS_STROPTS_H @@ -198,7 +198,7 @@ #undef HAVE_GRANTPT /* Define if you have fchmod */ -#undef HAVE_FCHMOD +#define HAVE_FCHMOD /* Define if you have */ #undef HAVE_SYS_TYPES32_H --Boundary-00=_OKYXC+kkn1fOkqy--