- Update to 2005-05-02 snapshot
- Add kqemu support PR: ports/80595 Submitted by: Juergen Lock <nox@jelal.kn-bremen.de> (maintainer)
This commit is contained in:
parent
c68ca78bd1
commit
8ca48ff897
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/head/; revision=134652
@ -6,10 +6,13 @@
|
||||
#
|
||||
|
||||
PORTNAME= qemu
|
||||
PORTVERSION= 0.7.0
|
||||
POTREVISION= 1
|
||||
PORTVERSION= 0.7.0s.20050502
|
||||
CATEGORIES= emulators
|
||||
MASTER_SITES= http://www.qemu.org/
|
||||
MASTER_SITES= http://www.qemu.org/ \
|
||||
http://people.fruitsalad.org/nox/qemu/ \
|
||||
http://dad-answers.com/qemu/
|
||||
DISTNAME= ${PORTNAME}-snapshot-2005-05-02_23
|
||||
EXTRACT_ONLY= ${DISTNAME}${EXTRACT_SUFX}
|
||||
|
||||
MAINTAINER= nox@jelal.kn-bremen.de
|
||||
COMMENT= QEMU CPU Emulator
|
||||
@ -19,7 +22,13 @@ BUILD_DEPENDS+= texi2html:${PORTSDIR}/textproc/texi2html
|
||||
RUN_DEPENDS+= ${LOCALBASE}/sbin/smbd:${PORTSDIR}/net/samba
|
||||
.endif
|
||||
|
||||
.if defined(WITH_KQEMU)
|
||||
DISTKQEMU= kqemu-0.6.2-1.tar.gz
|
||||
DISTFILES= ${EXTRACT_ONLY} ${DISTKQEMU}
|
||||
.endif
|
||||
|
||||
HAS_CONFIGURE= yes
|
||||
USE_BZIP2= yes
|
||||
USE_GMAKE= yes
|
||||
USE_GETOPT_LONG= yes
|
||||
USE_SDL= sdl
|
||||
@ -29,6 +38,14 @@ CONFIGURE_ARGS+= --prefix=${PREFIX} --cc=${CC}
|
||||
MAKE_ENV+= BSD_MAKE=${MAKE}
|
||||
MAN1= qemu.1 qemu-img.1
|
||||
ONLY_FOR_ARCHS= amd64 i386
|
||||
.if defined(WITH_KQEMU)
|
||||
NO_PACKAGE= Depends on kernel, and module not redistributable
|
||||
PLIST_SUB= WITH_KQEMU=""
|
||||
PLIST_SUB+= KMODDIR=${KMODDIR}
|
||||
EXTRA_PATCHES= ${FILESDIR}/kqemu-patch
|
||||
.else
|
||||
PLIST_SUB= WITH_KQEMU="@comment "
|
||||
.endif
|
||||
|
||||
# gcc34 (system cc on 5.x now) has problems with qemu on amd64
|
||||
# (doesnt build target-i386/op.c), try the one in ports which is newer
|
||||
@ -47,19 +64,48 @@ USE_GCC= 3.4
|
||||
USE_GCC= 3.4
|
||||
.endif
|
||||
|
||||
.if defined(WITH_KQEMU) && ${ARCH} != "i386"
|
||||
IGNORE= kqemu only supported on i386
|
||||
.endif
|
||||
|
||||
.if defined(WITH_KQEMU) && !exists(${SRC_BASE}/sys/Makefile)
|
||||
IGNORE= kqemu requires kernel source to be installed
|
||||
.endif
|
||||
|
||||
pre-everything::
|
||||
.if !defined(WITH_KQEMU) && ${ARCH} == "i386"
|
||||
@${ECHO_MSG} "Notice: you can build qemu with the (alpha!) kqemu accelerator kernel module"
|
||||
@${ECHO_MSG} "by defining WITH_KQEMU."
|
||||
.endif
|
||||
.if !defined(WITH_SAMBA) && !exists(${LOCALBASE}/sbin/smbd)
|
||||
@${ECHO_MSG} "Notice: if you need qemu's -smb option (smb-export local dir to guest)"
|
||||
@${ECHO_MSG} "then you also need samba, you can have this port install it by defining"
|
||||
@${ECHO_MSG} "WITH_SAMBA."
|
||||
.endif
|
||||
|
||||
.if defined(WITH_KQEMU)
|
||||
post-extract:
|
||||
@cd ${WRKSRC} && ${TAR} xfz ${_DISTDIR}/${DISTKQEMU}
|
||||
@${CP} ${FILESDIR}/kmod_bsd.c ${WRKSRC}/kqemu
|
||||
.endif
|
||||
|
||||
pre-patch:
|
||||
@for A in ${ONLY_FOR_ARCHS}; do \
|
||||
${MKDIR} ${WRKSRC}/bsd/$$A; \
|
||||
done
|
||||
|
||||
post-install:
|
||||
.if defined(WITH_KQEMU)
|
||||
${INSTALL_SCRIPT} ${WRKSRC}/kqemu/kqemu.ko ${KMODDIR}
|
||||
if mount |${GREP} ^devfs >/dev/null ; then \
|
||||
: ; \
|
||||
else \
|
||||
if [ ! -e /dev/kqemu ]; then\
|
||||
mknod /dev/kqemu c 250 0 ; \
|
||||
fi ; \
|
||||
${CHMOD} 666 /dev/kqemu ; \
|
||||
fi
|
||||
.endif
|
||||
@${CAT} ${PKGMESSAGE}
|
||||
|
||||
.include <bsd.port.post.mk>
|
||||
|
@ -1,2 +1,4 @@
|
||||
MD5 (qemu-0.7.0.tar.gz) = 234e9ace03b00259bb57dc5a9c633056
|
||||
SIZE (qemu-0.7.0.tar.gz) = 1211802
|
||||
MD5 (qemu-snapshot-2005-05-02_23.tar.bz2) = b7d4115a68bf93a9ad2c0c64a0c59137
|
||||
SIZE (qemu-snapshot-2005-05-02_23.tar.bz2) = 1020482
|
||||
MD5 (kqemu-0.6.2-1.tar.gz) = c6bb3b40fb3d526d731eb0f1f9dee7ee
|
||||
SIZE (kqemu-0.6.2-1.tar.gz) = 21002
|
||||
|
575
emulators/qemu-devel/files/kmod_bsd.c
Normal file
575
emulators/qemu-devel/files/kmod_bsd.c
Normal file
@ -0,0 +1,575 @@
|
||||
/*
|
||||
* FreeBSD kernel wrapper for KQEMU
|
||||
* Copyright (c) 2005 Antony T Curtis
|
||||
*
|
||||
* Based upon the Linux wrapper by Fabrice Bellard
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#if __FreeBSD_version < 500000
|
||||
#include <sys/buf.h>
|
||||
#endif
|
||||
#include <sys/uio.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/ctype.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/proc.h>
|
||||
#if __FreeBSD_version > 500000
|
||||
#include <sys/ktr.h>
|
||||
#include <sys/sched.h>
|
||||
#endif
|
||||
#include <sys/ioccom.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/resourcevar.h>
|
||||
#include <sys/module.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <vm/vm_map.h>
|
||||
#include <vm/vm_page.h>
|
||||
#include <vm/vm_kern.h>
|
||||
#include <vm/vm_extern.h>
|
||||
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
#define __KERNEL__
|
||||
|
||||
#include "kqemu.h"
|
||||
|
||||
static unsigned long cache_page(vm_offset_t paddr, caddr_t addr);
|
||||
static caddr_t find_page(vm_offset_t paddr, int free);
|
||||
|
||||
static MALLOC_DEFINE(M_KQEMU, "KQEMU", "KQEMU Resources");
|
||||
|
||||
struct pagecache {
|
||||
caddr_t addr;
|
||||
};
|
||||
|
||||
static struct pagecache **pagecache;
|
||||
#if __FreeBSD_version > 500000
|
||||
static struct mtx cache_lock;
|
||||
#endif
|
||||
|
||||
static unsigned long cache_page(vm_offset_t paddr, caddr_t addr)
|
||||
{
|
||||
unsigned long ppn = (unsigned long)(paddr >> PAGE_SHIFT);
|
||||
int pci = (int)(ppn >> 10);
|
||||
struct pagecache *cache;
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_lock_spin(&cache_lock);
|
||||
#endif
|
||||
if (!(cache = pagecache[pci])) {
|
||||
if (!addr) {
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_unlock_spin(&cache_lock);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
cache = pagecache[pci] = (struct pagecache *)
|
||||
kqemu_vmalloc(1024 * sizeof(struct pagecache));
|
||||
|
||||
memset(cache, 0, 1024 * sizeof(struct pagecache));
|
||||
}
|
||||
if (!addr) {
|
||||
int i;
|
||||
cache[ppn & 1023].addr = (caddr_t) 0;
|
||||
for (i = 1023; i >= 0; i--, cache++)
|
||||
if (cache->addr)
|
||||
break;
|
||||
if (i < 0) {
|
||||
kqemu_vfree(pagecache[pci]);
|
||||
pagecache[pci] = 0;
|
||||
}
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_unlock_spin(&cache_lock);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
cache[ppn & 1023].addr = (caddr_t) (((unsigned long) addr) & ~PAGE_MASK);
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_unlock_spin(&cache_lock);
|
||||
#endif
|
||||
return ppn;
|
||||
}
|
||||
|
||||
static caddr_t find_page(vm_offset_t paddr, int free)
|
||||
{
|
||||
unsigned long ppn = (unsigned long)(paddr >> PAGE_SHIFT);
|
||||
struct pagecache *cache;
|
||||
caddr_t addr;
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_lock_spin(&cache_lock);
|
||||
#endif
|
||||
if (!(cache = pagecache[ppn >> 10])) {
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_unlock_spin(&cache_lock);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
addr = (caddr_t)(((unsigned long)cache[ppn & 1023].addr)
|
||||
| ((unsigned long)paddr & PAGE_MASK));
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_unlock_spin(&cache_lock);
|
||||
#endif
|
||||
if (free && addr)
|
||||
cache_page(paddr, 0);
|
||||
return addr;
|
||||
}
|
||||
|
||||
/* lock the page at virtual address 'user_addr' and return its
|
||||
page index. Return -1 if error */
|
||||
unsigned long CDECL kqemu_lock_user_page(unsigned long user_addr)
|
||||
{
|
||||
int rc;
|
||||
caddr_t addr = (caddr_t) user_addr;
|
||||
vm_page_t m;
|
||||
vm_offset_t paddr;
|
||||
|
||||
/*kqemu_log("kqemu_lock_user_page(0x%08x)\n", addr);*/
|
||||
|
||||
rc = vm_fault_quick(addr, VM_PROT_READ|VM_PROT_WRITE);
|
||||
if (rc < 0) {
|
||||
/*kqemu_log("vm_fault_quick failed rc=%d\n",rc);*/
|
||||
return -1;
|
||||
}
|
||||
paddr = vtophys(addr);
|
||||
m = PHYS_TO_VM_PAGE(paddr);
|
||||
vm_page_wire(m);
|
||||
|
||||
return cache_page(paddr, addr);
|
||||
}
|
||||
|
||||
void CDECL kqemu_unlock_user_page(unsigned long page_index)
|
||||
{
|
||||
vm_page_t m;
|
||||
vm_offset_t paddr;
|
||||
/*kqemu_log("kqemu_unlock_user_page(0x%08x)\n",page_index);*/
|
||||
|
||||
paddr = (vm_offset_t)(page_index << PAGE_SHIFT);
|
||||
m = PHYS_TO_VM_PAGE(paddr);
|
||||
vm_page_unwire(m, 1);
|
||||
cache_page(paddr, 0);
|
||||
}
|
||||
|
||||
unsigned long CDECL kqemu_alloc_zeroed_page(void)
|
||||
{
|
||||
void *addr;
|
||||
vm_offset_t paddr;
|
||||
|
||||
/*kqemu_log("kqemu_alloc_zeroed_page()\n");*/
|
||||
addr = contigmalloc(PAGE_SIZE, M_KQEMU, M_WAITOK, 0, ~0ul, PAGE_SIZE, 0);
|
||||
if (!addr) {
|
||||
/*kqemu_log("contigmalloc failed\n");*/
|
||||
return -1;
|
||||
}
|
||||
memset(addr, 0, PAGE_SIZE);
|
||||
paddr = vtophys(addr);
|
||||
return cache_page(paddr, addr);
|
||||
}
|
||||
|
||||
void CDECL kqemu_free_page(unsigned long page_index)
|
||||
{
|
||||
vm_offset_t paddr;
|
||||
caddr_t addr;
|
||||
/*kqemu_log("kqemu_free_page(0x%08x)\n", page_index);*/
|
||||
paddr = (vm_offset_t) (page_index << PAGE_SHIFT);
|
||||
if ((addr = find_page(paddr,1))) {
|
||||
contigfree((void *) addr, PAGE_SIZE, M_KQEMU);
|
||||
}
|
||||
}
|
||||
|
||||
void * CDECL kqemu_page_kaddr(unsigned long page_index)
|
||||
{
|
||||
vm_offset_t paddr;
|
||||
/*kqemu_log("kqemu_page_kaddr(0x%08x)\n", page_index);*/
|
||||
paddr = (vm_offset_t) (page_index << PAGE_SHIFT);
|
||||
return (void *) find_page(paddr, 0);
|
||||
}
|
||||
|
||||
/* contraint: each page of the vmalloced area must be in the first 4
|
||||
GB of physical memory */
|
||||
void * CDECL kqemu_vmalloc(unsigned int size)
|
||||
{
|
||||
/*kqemu_log("kqemu_vmalloc(0x%08x)\n", size);*/
|
||||
return malloc(size, M_KQEMU, M_WAITOK);
|
||||
}
|
||||
|
||||
void CDECL kqemu_vfree(void *ptr)
|
||||
{
|
||||
/*kqemu_log("kqemu_vfree(0x%08x)\n", ptr);*/
|
||||
return free(ptr, M_KQEMU);
|
||||
}
|
||||
|
||||
unsigned long CDECL kqemu_vmalloc_to_phys(const void *vaddr)
|
||||
{
|
||||
caddr_t addr = (caddr_t)vaddr;
|
||||
vm_offset_t paddr = vtophys(addr);
|
||||
return cache_page(paddr, addr);
|
||||
}
|
||||
|
||||
#if __FreeBSD_version < 500000
|
||||
static int
|
||||
curpriority_cmp(struct proc *p)
|
||||
{
|
||||
int c_class, p_class;
|
||||
|
||||
c_class = RTP_PRIO_BASE(curproc->p_rtprio.type);
|
||||
p_class = RTP_PRIO_BASE(p->p_rtprio.type);
|
||||
if (p_class != c_class)
|
||||
return (p_class - c_class);
|
||||
if (p_class == RTP_PRIO_NORMAL)
|
||||
return (((int)p->p_priority - (int)curpriority) / PPQ);
|
||||
return ((int)p->p_rtprio.prio - (int)curproc->p_rtprio.prio);
|
||||
}
|
||||
|
||||
/* return TRUE if a signal is pending (i.e. the guest must stop
|
||||
execution) */
|
||||
int CDECL kqemu_schedule(void)
|
||||
{
|
||||
struct proc *p = curproc;
|
||||
if (curpriority_cmp(p) > 0) {
|
||||
int s = splhigh();
|
||||
p->p_priority = MAXPRI;
|
||||
setrunqueue(p);
|
||||
p->p_stats->p_ru.ru_nvcsw++;
|
||||
mi_switch();
|
||||
splx(s);
|
||||
}
|
||||
return issignal(curproc) != 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* return TRUE if a signal is pending (i.e. the guest must stop
|
||||
execution) */
|
||||
int CDECL kqemu_schedule(void)
|
||||
{
|
||||
struct thread *td = curthread;
|
||||
struct proc *p = td->td_proc;
|
||||
int rc;
|
||||
mtx_lock_spin(&sched_lock);
|
||||
sched_prio(td, td->td_ksegrp->kg_user_pri);
|
||||
mi_switch(SW_INVOL, NULL);
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
|
||||
PROC_LOCK(p);
|
||||
mtx_lock(&p->p_sigacts->ps_mtx);
|
||||
rc = cursig(td);
|
||||
mtx_unlock(&p->p_sigacts->ps_mtx);
|
||||
PROC_UNLOCK(p);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static char log_buf[4096];
|
||||
|
||||
void CDECL kqemu_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(log_buf, sizeof(log_buf), fmt, ap);
|
||||
printf("kqemu: %s", log_buf);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
|
||||
#define KQEMU_MAX_INSTANCES 4
|
||||
|
||||
struct kqemu_instance {
|
||||
struct kqemu_state *state;
|
||||
};
|
||||
|
||||
static int kqemu_ref_count = 0;
|
||||
static int max_locked_pages;
|
||||
#if __FreeBSD_version < 500000
|
||||
static dev_t kqemu_dev;
|
||||
#else
|
||||
static struct cdev *kqemu_dev;
|
||||
#endif
|
||||
|
||||
|
||||
static d_open_t kqemu_open;
|
||||
static d_close_t kqemu_close;
|
||||
static d_ioctl_t kqemu_ioctl;
|
||||
|
||||
static struct cdevsw kqemu_cdevsw = {
|
||||
#if __FreeBSD_version < 500000
|
||||
/* open */ kqemu_open,
|
||||
/* close */ kqemu_close,
|
||||
/* read */ noread,
|
||||
/* write */ nowrite,
|
||||
/* ioctl */ kqemu_ioctl,
|
||||
/* poll */ nopoll,
|
||||
/* mmap */ nommap,
|
||||
/* strategy */ nostrategy,
|
||||
/* name */ "kqemu",
|
||||
/* maj */ KQEMU_MAJOR,
|
||||
/* dump */ nodump,
|
||||
/* psize */ nopsize,
|
||||
/* flags */ 0,
|
||||
/* bmaj */ -1
|
||||
#else
|
||||
.d_version = D_VERSION,
|
||||
.d_open = kqemu_open,
|
||||
.d_close = kqemu_close,
|
||||
.d_ioctl = kqemu_ioctl,
|
||||
.d_name = "kqemu",
|
||||
#endif
|
||||
};
|
||||
|
||||
int
|
||||
#if __FreeBSD_version < 500000
|
||||
kqemu_open(dev, flags, fmt, p)
|
||||
dev_t dev;
|
||||
int flags, fmt;
|
||||
struct proc *p;
|
||||
{
|
||||
#else
|
||||
kqemu_open(dev, flags, fmt, td)
|
||||
struct cdev *dev;
|
||||
int flags, fmt;
|
||||
struct thread *td;
|
||||
{
|
||||
struct proc *p = td->td_proc;
|
||||
#endif
|
||||
struct kqemu_instance *ks;
|
||||
|
||||
if (dev->si_drv1 || kqemu_ref_count >= KQEMU_MAX_INSTANCES)
|
||||
return(EBUSY);
|
||||
|
||||
if ((flags & (FREAD|FWRITE)) == FREAD)
|
||||
return(EPERM);
|
||||
|
||||
ks = (struct kqemu_instance *) malloc(sizeof(*ks), M_KQEMU, M_WAITOK);
|
||||
if (ks == NULL)
|
||||
return(ENOMEM);
|
||||
memset(ks, 0, sizeof *ks);
|
||||
|
||||
dev->si_drv1 = ks;
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_lock_spin(&cache_lock);
|
||||
#endif
|
||||
kqemu_ref_count++;
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_unlock_spin(&cache_lock);
|
||||
#endif
|
||||
kqemu_log("opened by pid=%d\n", p->p_pid);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
#if __FreeBSD_version < 500000
|
||||
kqemu_close(dev, flags, fmt, p)
|
||||
dev_t dev;
|
||||
int flags, fmt;
|
||||
struct proc *p;
|
||||
{
|
||||
#else
|
||||
kqemu_close(dev, flags, fmt, td)
|
||||
struct cdev *dev;
|
||||
int flags, fmt;
|
||||
struct thread *td;
|
||||
{
|
||||
struct proc *p = td->td_proc;
|
||||
#endif
|
||||
struct kqemu_instance *ks = (struct kqemu_instance *) dev->si_drv1;
|
||||
|
||||
if (ks->state) {
|
||||
kqemu_delete(ks->state);
|
||||
ks->state = NULL;
|
||||
}
|
||||
|
||||
free(ks, M_KQEMU);
|
||||
dev->si_drv1 = NULL;
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_lock_spin(&cache_lock);
|
||||
#endif
|
||||
if (!--kqemu_ref_count) {
|
||||
int i;
|
||||
for (i = 1023; i >= 0; i--)
|
||||
kqemu_vfree(pagecache[i]);
|
||||
memset(pagecache, 0, 1024 * sizeof(void *));
|
||||
}
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_unlock_spin(&cache_lock);
|
||||
#endif
|
||||
kqemu_log("closed by pid=%d\n", p->p_pid);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
#if __FreeBSD_version < 500000
|
||||
kqemu_ioctl(dev, cmd, cmdarg, flags, p)
|
||||
dev_t dev;
|
||||
unsigned long cmd;
|
||||
caddr_t cmdarg;
|
||||
int flags;
|
||||
struct proc *p;
|
||||
{
|
||||
#else
|
||||
kqemu_ioctl(dev, cmd, cmdarg, flags, td)
|
||||
struct cdev *dev;
|
||||
unsigned long cmd;
|
||||
caddr_t cmdarg;
|
||||
int flags;
|
||||
struct thread *td;
|
||||
{
|
||||
#endif
|
||||
struct kqemu_instance *ks = (struct kqemu_instance *) dev->si_drv1;
|
||||
struct kqemu_state *s = ks->state;
|
||||
long ret;
|
||||
int error = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case KQEMU_INIT:
|
||||
/*kqemu_log("KQEMU_INIT data=0x%08x\n",cmdarg);*/
|
||||
{
|
||||
if (s) {
|
||||
error = (EIO);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(s = kqemu_init((struct kqemu_init *)cmdarg, max_locked_pages))) {
|
||||
error = (ENOMEM);
|
||||
break;
|
||||
}
|
||||
|
||||
ks->state = s;
|
||||
break;
|
||||
}
|
||||
case KQEMU_EXEC:
|
||||
/*kqemu_log("KQEMU_EXEC data=0x%08x\n",cmdarg);*/
|
||||
{
|
||||
struct kqemu_cpu_state *ctx;
|
||||
|
||||
if (!s) {
|
||||
error = (EIO);
|
||||
break;
|
||||
}
|
||||
|
||||
ctx = kqemu_get_cpu_state(s);
|
||||
memcpy((void *)ctx, (void *)cmdarg, sizeof(struct kqemu_cpu_state));
|
||||
|
||||
ret = kqemu_exec(s);
|
||||
#if __FreeBSD_version > 500000
|
||||
td->td_retval[0] = ret;
|
||||
#else
|
||||
p->p_retval[0] = ret;
|
||||
#endif
|
||||
memcpy((void *)cmdarg, (void *)ctx, sizeof(struct kqemu_cpu_state));
|
||||
|
||||
break;
|
||||
}
|
||||
case KQEMU_GET_VERSION:
|
||||
/*kqemu_log("KQEMU_GET_VERSION data=0x%08x\n",cmdarg);*/
|
||||
{
|
||||
*(int *)cmdarg = KQEMU_VERSION;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/*kqemu_log("ioctl unknown 0x%08x\n",cmd);*/
|
||||
error = (ENXIO);
|
||||
}
|
||||
return(error);
|
||||
}
|
||||
|
||||
static int
|
||||
init_module(void)
|
||||
{
|
||||
#if __FreeBSD_version < 500000
|
||||
int rc;
|
||||
#endif
|
||||
printf("QEMU Accelerator Module version %d.%d.%d, Copyright (c) 2005 Fabrice Bellard\n"
|
||||
"FreeBSD wrapper port, Copyright (c) 2005 Antony T Curtis\n"
|
||||
"This is a proprietary product. Read the LICENSE file for more information\n"
|
||||
"Redistribution of this module is prohibited without authorization\n",
|
||||
(KQEMU_VERSION >> 16),
|
||||
(KQEMU_VERSION >> 8) & 0xff,
|
||||
(KQEMU_VERSION) & 0xff);
|
||||
|
||||
if (!(pagecache = (struct pagecache **)
|
||||
kqemu_vmalloc(1024 * sizeof(void *))))
|
||||
return(ENOMEM);
|
||||
memset(pagecache, 0, 1024 * sizeof(void *));
|
||||
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_init(&cache_lock, "pagecache lock", NULL, MTX_SPIN);
|
||||
#endif
|
||||
|
||||
max_locked_pages = physmem / (2 * KQEMU_MAX_INSTANCES);
|
||||
if (max_locked_pages > 32768)
|
||||
max_locked_pages = 32768;
|
||||
|
||||
#if __FreeBSD_version < 500000
|
||||
if ((rc = cdevsw_add(&kqemu_cdevsw))) {
|
||||
kqemu_log("error registering cdevsw, rc=%d\n", rc);
|
||||
return(ENOENT);
|
||||
}
|
||||
#endif
|
||||
|
||||
kqemu_dev = make_dev(&kqemu_cdevsw, 0, UID_ROOT, GID_WHEEL, 0660, "kqemu");
|
||||
|
||||
kqemu_log("KQEMU installed, max_instances=%d max_locked_mem=%dkB.\n",
|
||||
KQEMU_MAX_INSTANCES, max_locked_pages * 4);
|
||||
|
||||
kqemu_ref_count = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup_module(void)
|
||||
{
|
||||
#if __FreeBSD_version < 500000
|
||||
int rc;
|
||||
#endif
|
||||
|
||||
destroy_dev(kqemu_dev);
|
||||
#if __FreeBSD_version < 500000
|
||||
if ((rc = cdevsw_remove(&kqemu_cdevsw)))
|
||||
kqemu_log("error unregistering, rc=%d\n", rc);
|
||||
#endif
|
||||
|
||||
kqemu_vfree(pagecache);
|
||||
pagecache = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
kqemu_modevent(module_t mod, int type, void *data)
|
||||
{
|
||||
int err = 0;
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
err = init_module();
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
if (kqemu_ref_count > 0) {
|
||||
err = EBUSY;
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
case MOD_SHUTDOWN:
|
||||
cleanup_module();
|
||||
break;
|
||||
default:
|
||||
err = EINVAL;
|
||||
break;
|
||||
}
|
||||
return(err);
|
||||
}
|
||||
|
||||
static moduledata_t kqemu_mod = {
|
||||
"kqemu_driver",
|
||||
kqemu_modevent,
|
||||
NULL
|
||||
};
|
||||
|
||||
DECLARE_MODULE(kqemu, kqemu_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
|
||||
|
68
emulators/qemu-devel/files/kqemu-patch
Normal file
68
emulators/qemu-devel/files/kqemu-patch
Normal file
@ -0,0 +1,68 @@
|
||||
Index: qemu/kqemu/Makefile
|
||||
@@ -1,62 +1,5 @@
|
||||
-ifeq ($(PATCHLEVEL),)
|
||||
-# compile in kqemu directory
|
||||
+KMOD= kqemu
|
||||
+SRCS= kmod_bsd.c
|
||||
+OBJS= kqemu-mod-i386.o
|
||||
|
||||
--include ../config-host.mak
|
||||
-
|
||||
-ifdef CONFIG_KBUILD26
|
||||
-# 2.6 build
|
||||
-
|
||||
-all: kqemu.ko
|
||||
-
|
||||
-kqemu.ko:
|
||||
- make -C $(KERNEL_PATH) M=`pwd` modules
|
||||
-
|
||||
-else
|
||||
-# 2.4 build
|
||||
-
|
||||
-all: kqemu.o
|
||||
-
|
||||
-kqemu.o:
|
||||
- make -C $(KERNEL_PATH) SUBDIRS=`pwd` modules
|
||||
-
|
||||
-endif # !CONFIG_KBUILD26
|
||||
-
|
||||
-clean:
|
||||
- rm -f kqemu.o kqemu.ko kmod.o kqemu-mod.o kqemu.mod.c *~
|
||||
-
|
||||
-FILES=Makefile README LICENSE install.sh kmod.c kqemu.h kqemu-mod-i386.o \
|
||||
- kqemu-doc.texi kqemu-doc.html
|
||||
-VERSION=0.6.2
|
||||
-
|
||||
-tar:
|
||||
- cd .. ; tar zcvf /tmp/kqemu-$(VERSION).tar.gz $(addprefix kqemu/, $(FILES))
|
||||
-
|
||||
-# documentation
|
||||
-doc: kqemu-doc.html
|
||||
-
|
||||
-%.html: %.texi
|
||||
- texi2html -monolithic -number $<
|
||||
-
|
||||
-else
|
||||
-
|
||||
-ifeq ($(PATCHLEVEL),4)
|
||||
-# called from 2.4 kernel kbuild
|
||||
-
|
||||
-obj-m:= kqemu.o
|
||||
-kqemu-objs:= kmod.o kqemu-mod-i386.o
|
||||
-
|
||||
-include $(TOPDIR)/Rules.make
|
||||
-
|
||||
-kqemu.o: $(kqemu-objs)
|
||||
- $(LD) -r -o $@ $(kqemu-objs)
|
||||
-
|
||||
-else
|
||||
-# called from 2.6 kernel kbuild
|
||||
-
|
||||
-obj-m:= kqemu.o
|
||||
-kqemu-objs:= kmod.o kqemu-mod.o
|
||||
-
|
||||
-$(obj)/kqemu-mod.o: $(src)/kqemu-mod-i386.o
|
||||
- cp $< $@
|
||||
-endif
|
||||
-endif # PATCHLEVEL
|
||||
+.include <bsd.kmod.mk>
|
@ -8,14 +8,19 @@ Index: qemu/Makefile
|
||||
for d in $(TARGET_DIRS); do \
|
||||
$(MAKE) -C $$d $@ || exit 1 ; \
|
||||
done
|
||||
@@ -25,6 +25,9 @@
|
||||
@@ -21,10 +21,13 @@
|
||||
ifdef CONFIG_WIN32
|
||||
$(MAKE) -C kqemu -f Makefile.winnt
|
||||
else
|
||||
- $(MAKE) -C kqemu
|
||||
+ cd kqemu && $(BSD_MAKE)
|
||||
endif
|
||||
endif
|
||||
|
||||
+bsd/libmath.a:
|
||||
+ ( cd bsd ; $(BSD_MAKE) CC=$(CC) )
|
||||
+
|
||||
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 block-bochs.c block-vpc.c
|
||||
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 block-bochs.c block-vpc.c block-vvfat.c
|
||||
$(CC) -DQEMU_TOOL $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $@ $^ -lz $(LIBS)
|
||||
|
||||
@@ -33,6 +36,7 @@
|
||||
@ -26,6 +31,25 @@ Index: qemu/Makefile
|
||||
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
|
||||
@@ -40,7 +44,7 @@
|
||||
$(MAKE) -C $$d $@ || exit 1 ; \
|
||||
done
|
||||
ifdef CONFIG_KQEMU
|
||||
- $(MAKE) -C kqemu clean
|
||||
+ cd kqemu && $(BSD_MAKE) clean
|
||||
endif
|
||||
|
||||
distclean: clean
|
||||
@@ -73,9 +77,6 @@
|
||||
for d in $(TARGET_DIRS); do \
|
||||
$(MAKE) -C $$d $@ || exit 1 ; \
|
||||
done
|
||||
-ifdef CONFIG_KQEMU
|
||||
- cd kqemu ; ./install.sh
|
||||
-endif
|
||||
|
||||
# various test targets
|
||||
test speed test2: all
|
||||
Index: qemu/Makefile.target
|
||||
@@ -391,8 +391,8 @@
|
||||
VL_LDFLAGS+=-Wl,-G0 -Wl,-T,$(SRC_PATH)/ia64.ld
|
||||
|
40
emulators/qemu-devel/files/patch-osdep.c
Normal file
40
emulators/qemu-devel/files/patch-osdep.c
Normal file
@ -0,0 +1,40 @@
|
||||
Index: qemu/osdep.c
|
||||
@@ -323,7 +323,9 @@
|
||||
|
||||
#elif defined(USE_KQEMU)
|
||||
|
||||
+#ifndef __FreeBSD__
|
||||
#include <sys/vfs.h>
|
||||
+#endif
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
@@ -334,6 +336,7 @@
|
||||
const char *tmpdir;
|
||||
char phys_ram_file[1024];
|
||||
void *ptr;
|
||||
+#ifndef __FreeBSD__
|
||||
struct statfs stfs;
|
||||
|
||||
if (phys_ram_fd < 0) {
|
||||
@@ -389,12 +392,20 @@
|
||||
}
|
||||
unlink(phys_ram_file);
|
||||
}
|
||||
+#endif
|
||||
size = (size + 4095) & ~4095;
|
||||
+#ifndef __FreeBSD__
|
||||
ftruncate(phys_ram_fd, phys_ram_size + size);
|
||||
ptr = mmap(NULL,
|
||||
size,
|
||||
PROT_WRITE | PROT_READ, MAP_SHARED,
|
||||
phys_ram_fd, phys_ram_size);
|
||||
+#else
|
||||
+ ptr = mmap(NULL,
|
||||
+ size,
|
||||
+ PROT_WRITE | PROT_READ, MAP_PRIVATE|MAP_ANON,
|
||||
+ -1, 0);
|
||||
+#endif
|
||||
if (ptr == MAP_FAILED) {
|
||||
fprintf(stderr, "Could not map physical memory\n");
|
||||
exit(1);
|
@ -49,3 +49,5 @@ share/qemu/keymaps/tr
|
||||
@dirrm share/qemu/keymaps
|
||||
@dirrm share/qemu
|
||||
%%PORTDOCS%%@dirrm %%DOCSDIR%%
|
||||
@cwd /
|
||||
%%WITH_KQEMU%%%%KMODDIR%%/kqemu.ko
|
||||
|
@ -6,10 +6,13 @@
|
||||
#
|
||||
|
||||
PORTNAME= qemu
|
||||
PORTVERSION= 0.7.0
|
||||
POTREVISION= 1
|
||||
PORTVERSION= 0.7.0s.20050502
|
||||
CATEGORIES= emulators
|
||||
MASTER_SITES= http://www.qemu.org/
|
||||
MASTER_SITES= http://www.qemu.org/ \
|
||||
http://people.fruitsalad.org/nox/qemu/ \
|
||||
http://dad-answers.com/qemu/
|
||||
DISTNAME= ${PORTNAME}-snapshot-2005-05-02_23
|
||||
EXTRACT_ONLY= ${DISTNAME}${EXTRACT_SUFX}
|
||||
|
||||
MAINTAINER= nox@jelal.kn-bremen.de
|
||||
COMMENT= QEMU CPU Emulator
|
||||
@ -19,7 +22,13 @@ BUILD_DEPENDS+= texi2html:${PORTSDIR}/textproc/texi2html
|
||||
RUN_DEPENDS+= ${LOCALBASE}/sbin/smbd:${PORTSDIR}/net/samba
|
||||
.endif
|
||||
|
||||
.if defined(WITH_KQEMU)
|
||||
DISTKQEMU= kqemu-0.6.2-1.tar.gz
|
||||
DISTFILES= ${EXTRACT_ONLY} ${DISTKQEMU}
|
||||
.endif
|
||||
|
||||
HAS_CONFIGURE= yes
|
||||
USE_BZIP2= yes
|
||||
USE_GMAKE= yes
|
||||
USE_GETOPT_LONG= yes
|
||||
USE_SDL= sdl
|
||||
@ -29,6 +38,14 @@ CONFIGURE_ARGS+= --prefix=${PREFIX} --cc=${CC}
|
||||
MAKE_ENV+= BSD_MAKE=${MAKE}
|
||||
MAN1= qemu.1 qemu-img.1
|
||||
ONLY_FOR_ARCHS= amd64 i386
|
||||
.if defined(WITH_KQEMU)
|
||||
NO_PACKAGE= Depends on kernel, and module not redistributable
|
||||
PLIST_SUB= WITH_KQEMU=""
|
||||
PLIST_SUB+= KMODDIR=${KMODDIR}
|
||||
EXTRA_PATCHES= ${FILESDIR}/kqemu-patch
|
||||
.else
|
||||
PLIST_SUB= WITH_KQEMU="@comment "
|
||||
.endif
|
||||
|
||||
# gcc34 (system cc on 5.x now) has problems with qemu on amd64
|
||||
# (doesnt build target-i386/op.c), try the one in ports which is newer
|
||||
@ -47,19 +64,48 @@ USE_GCC= 3.4
|
||||
USE_GCC= 3.4
|
||||
.endif
|
||||
|
||||
.if defined(WITH_KQEMU) && ${ARCH} != "i386"
|
||||
IGNORE= kqemu only supported on i386
|
||||
.endif
|
||||
|
||||
.if defined(WITH_KQEMU) && !exists(${SRC_BASE}/sys/Makefile)
|
||||
IGNORE= kqemu requires kernel source to be installed
|
||||
.endif
|
||||
|
||||
pre-everything::
|
||||
.if !defined(WITH_KQEMU) && ${ARCH} == "i386"
|
||||
@${ECHO_MSG} "Notice: you can build qemu with the (alpha!) kqemu accelerator kernel module"
|
||||
@${ECHO_MSG} "by defining WITH_KQEMU."
|
||||
.endif
|
||||
.if !defined(WITH_SAMBA) && !exists(${LOCALBASE}/sbin/smbd)
|
||||
@${ECHO_MSG} "Notice: if you need qemu's -smb option (smb-export local dir to guest)"
|
||||
@${ECHO_MSG} "then you also need samba, you can have this port install it by defining"
|
||||
@${ECHO_MSG} "WITH_SAMBA."
|
||||
.endif
|
||||
|
||||
.if defined(WITH_KQEMU)
|
||||
post-extract:
|
||||
@cd ${WRKSRC} && ${TAR} xfz ${_DISTDIR}/${DISTKQEMU}
|
||||
@${CP} ${FILESDIR}/kmod_bsd.c ${WRKSRC}/kqemu
|
||||
.endif
|
||||
|
||||
pre-patch:
|
||||
@for A in ${ONLY_FOR_ARCHS}; do \
|
||||
${MKDIR} ${WRKSRC}/bsd/$$A; \
|
||||
done
|
||||
|
||||
post-install:
|
||||
.if defined(WITH_KQEMU)
|
||||
${INSTALL_SCRIPT} ${WRKSRC}/kqemu/kqemu.ko ${KMODDIR}
|
||||
if mount |${GREP} ^devfs >/dev/null ; then \
|
||||
: ; \
|
||||
else \
|
||||
if [ ! -e /dev/kqemu ]; then\
|
||||
mknod /dev/kqemu c 250 0 ; \
|
||||
fi ; \
|
||||
${CHMOD} 666 /dev/kqemu ; \
|
||||
fi
|
||||
.endif
|
||||
@${CAT} ${PKGMESSAGE}
|
||||
|
||||
.include <bsd.port.post.mk>
|
||||
|
@ -1,2 +1,4 @@
|
||||
MD5 (qemu-0.7.0.tar.gz) = 234e9ace03b00259bb57dc5a9c633056
|
||||
SIZE (qemu-0.7.0.tar.gz) = 1211802
|
||||
MD5 (qemu-snapshot-2005-05-02_23.tar.bz2) = b7d4115a68bf93a9ad2c0c64a0c59137
|
||||
SIZE (qemu-snapshot-2005-05-02_23.tar.bz2) = 1020482
|
||||
MD5 (kqemu-0.6.2-1.tar.gz) = c6bb3b40fb3d526d731eb0f1f9dee7ee
|
||||
SIZE (kqemu-0.6.2-1.tar.gz) = 21002
|
||||
|
575
emulators/qemu/files/kmod_bsd.c
Normal file
575
emulators/qemu/files/kmod_bsd.c
Normal file
@ -0,0 +1,575 @@
|
||||
/*
|
||||
* FreeBSD kernel wrapper for KQEMU
|
||||
* Copyright (c) 2005 Antony T Curtis
|
||||
*
|
||||
* Based upon the Linux wrapper by Fabrice Bellard
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#if __FreeBSD_version < 500000
|
||||
#include <sys/buf.h>
|
||||
#endif
|
||||
#include <sys/uio.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/ctype.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/proc.h>
|
||||
#if __FreeBSD_version > 500000
|
||||
#include <sys/ktr.h>
|
||||
#include <sys/sched.h>
|
||||
#endif
|
||||
#include <sys/ioccom.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/resourcevar.h>
|
||||
#include <sys/module.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <vm/vm_map.h>
|
||||
#include <vm/vm_page.h>
|
||||
#include <vm/vm_kern.h>
|
||||
#include <vm/vm_extern.h>
|
||||
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
#define __KERNEL__
|
||||
|
||||
#include "kqemu.h"
|
||||
|
||||
static unsigned long cache_page(vm_offset_t paddr, caddr_t addr);
|
||||
static caddr_t find_page(vm_offset_t paddr, int free);
|
||||
|
||||
static MALLOC_DEFINE(M_KQEMU, "KQEMU", "KQEMU Resources");
|
||||
|
||||
struct pagecache {
|
||||
caddr_t addr;
|
||||
};
|
||||
|
||||
static struct pagecache **pagecache;
|
||||
#if __FreeBSD_version > 500000
|
||||
static struct mtx cache_lock;
|
||||
#endif
|
||||
|
||||
static unsigned long cache_page(vm_offset_t paddr, caddr_t addr)
|
||||
{
|
||||
unsigned long ppn = (unsigned long)(paddr >> PAGE_SHIFT);
|
||||
int pci = (int)(ppn >> 10);
|
||||
struct pagecache *cache;
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_lock_spin(&cache_lock);
|
||||
#endif
|
||||
if (!(cache = pagecache[pci])) {
|
||||
if (!addr) {
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_unlock_spin(&cache_lock);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
cache = pagecache[pci] = (struct pagecache *)
|
||||
kqemu_vmalloc(1024 * sizeof(struct pagecache));
|
||||
|
||||
memset(cache, 0, 1024 * sizeof(struct pagecache));
|
||||
}
|
||||
if (!addr) {
|
||||
int i;
|
||||
cache[ppn & 1023].addr = (caddr_t) 0;
|
||||
for (i = 1023; i >= 0; i--, cache++)
|
||||
if (cache->addr)
|
||||
break;
|
||||
if (i < 0) {
|
||||
kqemu_vfree(pagecache[pci]);
|
||||
pagecache[pci] = 0;
|
||||
}
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_unlock_spin(&cache_lock);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
cache[ppn & 1023].addr = (caddr_t) (((unsigned long) addr) & ~PAGE_MASK);
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_unlock_spin(&cache_lock);
|
||||
#endif
|
||||
return ppn;
|
||||
}
|
||||
|
||||
static caddr_t find_page(vm_offset_t paddr, int free)
|
||||
{
|
||||
unsigned long ppn = (unsigned long)(paddr >> PAGE_SHIFT);
|
||||
struct pagecache *cache;
|
||||
caddr_t addr;
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_lock_spin(&cache_lock);
|
||||
#endif
|
||||
if (!(cache = pagecache[ppn >> 10])) {
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_unlock_spin(&cache_lock);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
addr = (caddr_t)(((unsigned long)cache[ppn & 1023].addr)
|
||||
| ((unsigned long)paddr & PAGE_MASK));
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_unlock_spin(&cache_lock);
|
||||
#endif
|
||||
if (free && addr)
|
||||
cache_page(paddr, 0);
|
||||
return addr;
|
||||
}
|
||||
|
||||
/* lock the page at virtual address 'user_addr' and return its
|
||||
page index. Return -1 if error */
|
||||
unsigned long CDECL kqemu_lock_user_page(unsigned long user_addr)
|
||||
{
|
||||
int rc;
|
||||
caddr_t addr = (caddr_t) user_addr;
|
||||
vm_page_t m;
|
||||
vm_offset_t paddr;
|
||||
|
||||
/*kqemu_log("kqemu_lock_user_page(0x%08x)\n", addr);*/
|
||||
|
||||
rc = vm_fault_quick(addr, VM_PROT_READ|VM_PROT_WRITE);
|
||||
if (rc < 0) {
|
||||
/*kqemu_log("vm_fault_quick failed rc=%d\n",rc);*/
|
||||
return -1;
|
||||
}
|
||||
paddr = vtophys(addr);
|
||||
m = PHYS_TO_VM_PAGE(paddr);
|
||||
vm_page_wire(m);
|
||||
|
||||
return cache_page(paddr, addr);
|
||||
}
|
||||
|
||||
void CDECL kqemu_unlock_user_page(unsigned long page_index)
|
||||
{
|
||||
vm_page_t m;
|
||||
vm_offset_t paddr;
|
||||
/*kqemu_log("kqemu_unlock_user_page(0x%08x)\n",page_index);*/
|
||||
|
||||
paddr = (vm_offset_t)(page_index << PAGE_SHIFT);
|
||||
m = PHYS_TO_VM_PAGE(paddr);
|
||||
vm_page_unwire(m, 1);
|
||||
cache_page(paddr, 0);
|
||||
}
|
||||
|
||||
unsigned long CDECL kqemu_alloc_zeroed_page(void)
|
||||
{
|
||||
void *addr;
|
||||
vm_offset_t paddr;
|
||||
|
||||
/*kqemu_log("kqemu_alloc_zeroed_page()\n");*/
|
||||
addr = contigmalloc(PAGE_SIZE, M_KQEMU, M_WAITOK, 0, ~0ul, PAGE_SIZE, 0);
|
||||
if (!addr) {
|
||||
/*kqemu_log("contigmalloc failed\n");*/
|
||||
return -1;
|
||||
}
|
||||
memset(addr, 0, PAGE_SIZE);
|
||||
paddr = vtophys(addr);
|
||||
return cache_page(paddr, addr);
|
||||
}
|
||||
|
||||
void CDECL kqemu_free_page(unsigned long page_index)
|
||||
{
|
||||
vm_offset_t paddr;
|
||||
caddr_t addr;
|
||||
/*kqemu_log("kqemu_free_page(0x%08x)\n", page_index);*/
|
||||
paddr = (vm_offset_t) (page_index << PAGE_SHIFT);
|
||||
if ((addr = find_page(paddr,1))) {
|
||||
contigfree((void *) addr, PAGE_SIZE, M_KQEMU);
|
||||
}
|
||||
}
|
||||
|
||||
void * CDECL kqemu_page_kaddr(unsigned long page_index)
|
||||
{
|
||||
vm_offset_t paddr;
|
||||
/*kqemu_log("kqemu_page_kaddr(0x%08x)\n", page_index);*/
|
||||
paddr = (vm_offset_t) (page_index << PAGE_SHIFT);
|
||||
return (void *) find_page(paddr, 0);
|
||||
}
|
||||
|
||||
/* contraint: each page of the vmalloced area must be in the first 4
|
||||
GB of physical memory */
|
||||
void * CDECL kqemu_vmalloc(unsigned int size)
|
||||
{
|
||||
/*kqemu_log("kqemu_vmalloc(0x%08x)\n", size);*/
|
||||
return malloc(size, M_KQEMU, M_WAITOK);
|
||||
}
|
||||
|
||||
void CDECL kqemu_vfree(void *ptr)
|
||||
{
|
||||
/*kqemu_log("kqemu_vfree(0x%08x)\n", ptr);*/
|
||||
return free(ptr, M_KQEMU);
|
||||
}
|
||||
|
||||
unsigned long CDECL kqemu_vmalloc_to_phys(const void *vaddr)
|
||||
{
|
||||
caddr_t addr = (caddr_t)vaddr;
|
||||
vm_offset_t paddr = vtophys(addr);
|
||||
return cache_page(paddr, addr);
|
||||
}
|
||||
|
||||
#if __FreeBSD_version < 500000
|
||||
static int
|
||||
curpriority_cmp(struct proc *p)
|
||||
{
|
||||
int c_class, p_class;
|
||||
|
||||
c_class = RTP_PRIO_BASE(curproc->p_rtprio.type);
|
||||
p_class = RTP_PRIO_BASE(p->p_rtprio.type);
|
||||
if (p_class != c_class)
|
||||
return (p_class - c_class);
|
||||
if (p_class == RTP_PRIO_NORMAL)
|
||||
return (((int)p->p_priority - (int)curpriority) / PPQ);
|
||||
return ((int)p->p_rtprio.prio - (int)curproc->p_rtprio.prio);
|
||||
}
|
||||
|
||||
/* return TRUE if a signal is pending (i.e. the guest must stop
|
||||
execution) */
|
||||
int CDECL kqemu_schedule(void)
|
||||
{
|
||||
struct proc *p = curproc;
|
||||
if (curpriority_cmp(p) > 0) {
|
||||
int s = splhigh();
|
||||
p->p_priority = MAXPRI;
|
||||
setrunqueue(p);
|
||||
p->p_stats->p_ru.ru_nvcsw++;
|
||||
mi_switch();
|
||||
splx(s);
|
||||
}
|
||||
return issignal(curproc) != 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* return TRUE if a signal is pending (i.e. the guest must stop
|
||||
execution) */
|
||||
int CDECL kqemu_schedule(void)
|
||||
{
|
||||
struct thread *td = curthread;
|
||||
struct proc *p = td->td_proc;
|
||||
int rc;
|
||||
mtx_lock_spin(&sched_lock);
|
||||
sched_prio(td, td->td_ksegrp->kg_user_pri);
|
||||
mi_switch(SW_INVOL, NULL);
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
|
||||
PROC_LOCK(p);
|
||||
mtx_lock(&p->p_sigacts->ps_mtx);
|
||||
rc = cursig(td);
|
||||
mtx_unlock(&p->p_sigacts->ps_mtx);
|
||||
PROC_UNLOCK(p);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static char log_buf[4096];
|
||||
|
||||
void CDECL kqemu_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(log_buf, sizeof(log_buf), fmt, ap);
|
||||
printf("kqemu: %s", log_buf);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
|
||||
#define KQEMU_MAX_INSTANCES 4
|
||||
|
||||
struct kqemu_instance {
|
||||
struct kqemu_state *state;
|
||||
};
|
||||
|
||||
static int kqemu_ref_count = 0;
|
||||
static int max_locked_pages;
|
||||
#if __FreeBSD_version < 500000
|
||||
static dev_t kqemu_dev;
|
||||
#else
|
||||
static struct cdev *kqemu_dev;
|
||||
#endif
|
||||
|
||||
|
||||
static d_open_t kqemu_open;
|
||||
static d_close_t kqemu_close;
|
||||
static d_ioctl_t kqemu_ioctl;
|
||||
|
||||
static struct cdevsw kqemu_cdevsw = {
|
||||
#if __FreeBSD_version < 500000
|
||||
/* open */ kqemu_open,
|
||||
/* close */ kqemu_close,
|
||||
/* read */ noread,
|
||||
/* write */ nowrite,
|
||||
/* ioctl */ kqemu_ioctl,
|
||||
/* poll */ nopoll,
|
||||
/* mmap */ nommap,
|
||||
/* strategy */ nostrategy,
|
||||
/* name */ "kqemu",
|
||||
/* maj */ KQEMU_MAJOR,
|
||||
/* dump */ nodump,
|
||||
/* psize */ nopsize,
|
||||
/* flags */ 0,
|
||||
/* bmaj */ -1
|
||||
#else
|
||||
.d_version = D_VERSION,
|
||||
.d_open = kqemu_open,
|
||||
.d_close = kqemu_close,
|
||||
.d_ioctl = kqemu_ioctl,
|
||||
.d_name = "kqemu",
|
||||
#endif
|
||||
};
|
||||
|
||||
int
|
||||
#if __FreeBSD_version < 500000
|
||||
kqemu_open(dev, flags, fmt, p)
|
||||
dev_t dev;
|
||||
int flags, fmt;
|
||||
struct proc *p;
|
||||
{
|
||||
#else
|
||||
kqemu_open(dev, flags, fmt, td)
|
||||
struct cdev *dev;
|
||||
int flags, fmt;
|
||||
struct thread *td;
|
||||
{
|
||||
struct proc *p = td->td_proc;
|
||||
#endif
|
||||
struct kqemu_instance *ks;
|
||||
|
||||
if (dev->si_drv1 || kqemu_ref_count >= KQEMU_MAX_INSTANCES)
|
||||
return(EBUSY);
|
||||
|
||||
if ((flags & (FREAD|FWRITE)) == FREAD)
|
||||
return(EPERM);
|
||||
|
||||
ks = (struct kqemu_instance *) malloc(sizeof(*ks), M_KQEMU, M_WAITOK);
|
||||
if (ks == NULL)
|
||||
return(ENOMEM);
|
||||
memset(ks, 0, sizeof *ks);
|
||||
|
||||
dev->si_drv1 = ks;
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_lock_spin(&cache_lock);
|
||||
#endif
|
||||
kqemu_ref_count++;
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_unlock_spin(&cache_lock);
|
||||
#endif
|
||||
kqemu_log("opened by pid=%d\n", p->p_pid);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
#if __FreeBSD_version < 500000
|
||||
kqemu_close(dev, flags, fmt, p)
|
||||
dev_t dev;
|
||||
int flags, fmt;
|
||||
struct proc *p;
|
||||
{
|
||||
#else
|
||||
kqemu_close(dev, flags, fmt, td)
|
||||
struct cdev *dev;
|
||||
int flags, fmt;
|
||||
struct thread *td;
|
||||
{
|
||||
struct proc *p = td->td_proc;
|
||||
#endif
|
||||
struct kqemu_instance *ks = (struct kqemu_instance *) dev->si_drv1;
|
||||
|
||||
if (ks->state) {
|
||||
kqemu_delete(ks->state);
|
||||
ks->state = NULL;
|
||||
}
|
||||
|
||||
free(ks, M_KQEMU);
|
||||
dev->si_drv1 = NULL;
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_lock_spin(&cache_lock);
|
||||
#endif
|
||||
if (!--kqemu_ref_count) {
|
||||
int i;
|
||||
for (i = 1023; i >= 0; i--)
|
||||
kqemu_vfree(pagecache[i]);
|
||||
memset(pagecache, 0, 1024 * sizeof(void *));
|
||||
}
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_unlock_spin(&cache_lock);
|
||||
#endif
|
||||
kqemu_log("closed by pid=%d\n", p->p_pid);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
#if __FreeBSD_version < 500000
|
||||
kqemu_ioctl(dev, cmd, cmdarg, flags, p)
|
||||
dev_t dev;
|
||||
unsigned long cmd;
|
||||
caddr_t cmdarg;
|
||||
int flags;
|
||||
struct proc *p;
|
||||
{
|
||||
#else
|
||||
kqemu_ioctl(dev, cmd, cmdarg, flags, td)
|
||||
struct cdev *dev;
|
||||
unsigned long cmd;
|
||||
caddr_t cmdarg;
|
||||
int flags;
|
||||
struct thread *td;
|
||||
{
|
||||
#endif
|
||||
struct kqemu_instance *ks = (struct kqemu_instance *) dev->si_drv1;
|
||||
struct kqemu_state *s = ks->state;
|
||||
long ret;
|
||||
int error = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case KQEMU_INIT:
|
||||
/*kqemu_log("KQEMU_INIT data=0x%08x\n",cmdarg);*/
|
||||
{
|
||||
if (s) {
|
||||
error = (EIO);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(s = kqemu_init((struct kqemu_init *)cmdarg, max_locked_pages))) {
|
||||
error = (ENOMEM);
|
||||
break;
|
||||
}
|
||||
|
||||
ks->state = s;
|
||||
break;
|
||||
}
|
||||
case KQEMU_EXEC:
|
||||
/*kqemu_log("KQEMU_EXEC data=0x%08x\n",cmdarg);*/
|
||||
{
|
||||
struct kqemu_cpu_state *ctx;
|
||||
|
||||
if (!s) {
|
||||
error = (EIO);
|
||||
break;
|
||||
}
|
||||
|
||||
ctx = kqemu_get_cpu_state(s);
|
||||
memcpy((void *)ctx, (void *)cmdarg, sizeof(struct kqemu_cpu_state));
|
||||
|
||||
ret = kqemu_exec(s);
|
||||
#if __FreeBSD_version > 500000
|
||||
td->td_retval[0] = ret;
|
||||
#else
|
||||
p->p_retval[0] = ret;
|
||||
#endif
|
||||
memcpy((void *)cmdarg, (void *)ctx, sizeof(struct kqemu_cpu_state));
|
||||
|
||||
break;
|
||||
}
|
||||
case KQEMU_GET_VERSION:
|
||||
/*kqemu_log("KQEMU_GET_VERSION data=0x%08x\n",cmdarg);*/
|
||||
{
|
||||
*(int *)cmdarg = KQEMU_VERSION;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/*kqemu_log("ioctl unknown 0x%08x\n",cmd);*/
|
||||
error = (ENXIO);
|
||||
}
|
||||
return(error);
|
||||
}
|
||||
|
||||
static int
|
||||
init_module(void)
|
||||
{
|
||||
#if __FreeBSD_version < 500000
|
||||
int rc;
|
||||
#endif
|
||||
printf("QEMU Accelerator Module version %d.%d.%d, Copyright (c) 2005 Fabrice Bellard\n"
|
||||
"FreeBSD wrapper port, Copyright (c) 2005 Antony T Curtis\n"
|
||||
"This is a proprietary product. Read the LICENSE file for more information\n"
|
||||
"Redistribution of this module is prohibited without authorization\n",
|
||||
(KQEMU_VERSION >> 16),
|
||||
(KQEMU_VERSION >> 8) & 0xff,
|
||||
(KQEMU_VERSION) & 0xff);
|
||||
|
||||
if (!(pagecache = (struct pagecache **)
|
||||
kqemu_vmalloc(1024 * sizeof(void *))))
|
||||
return(ENOMEM);
|
||||
memset(pagecache, 0, 1024 * sizeof(void *));
|
||||
|
||||
#if __FreeBSD_version > 500000
|
||||
mtx_init(&cache_lock, "pagecache lock", NULL, MTX_SPIN);
|
||||
#endif
|
||||
|
||||
max_locked_pages = physmem / (2 * KQEMU_MAX_INSTANCES);
|
||||
if (max_locked_pages > 32768)
|
||||
max_locked_pages = 32768;
|
||||
|
||||
#if __FreeBSD_version < 500000
|
||||
if ((rc = cdevsw_add(&kqemu_cdevsw))) {
|
||||
kqemu_log("error registering cdevsw, rc=%d\n", rc);
|
||||
return(ENOENT);
|
||||
}
|
||||
#endif
|
||||
|
||||
kqemu_dev = make_dev(&kqemu_cdevsw, 0, UID_ROOT, GID_WHEEL, 0660, "kqemu");
|
||||
|
||||
kqemu_log("KQEMU installed, max_instances=%d max_locked_mem=%dkB.\n",
|
||||
KQEMU_MAX_INSTANCES, max_locked_pages * 4);
|
||||
|
||||
kqemu_ref_count = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup_module(void)
|
||||
{
|
||||
#if __FreeBSD_version < 500000
|
||||
int rc;
|
||||
#endif
|
||||
|
||||
destroy_dev(kqemu_dev);
|
||||
#if __FreeBSD_version < 500000
|
||||
if ((rc = cdevsw_remove(&kqemu_cdevsw)))
|
||||
kqemu_log("error unregistering, rc=%d\n", rc);
|
||||
#endif
|
||||
|
||||
kqemu_vfree(pagecache);
|
||||
pagecache = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
kqemu_modevent(module_t mod, int type, void *data)
|
||||
{
|
||||
int err = 0;
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
err = init_module();
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
if (kqemu_ref_count > 0) {
|
||||
err = EBUSY;
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
case MOD_SHUTDOWN:
|
||||
cleanup_module();
|
||||
break;
|
||||
default:
|
||||
err = EINVAL;
|
||||
break;
|
||||
}
|
||||
return(err);
|
||||
}
|
||||
|
||||
static moduledata_t kqemu_mod = {
|
||||
"kqemu_driver",
|
||||
kqemu_modevent,
|
||||
NULL
|
||||
};
|
||||
|
||||
DECLARE_MODULE(kqemu, kqemu_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
|
||||
|
68
emulators/qemu/files/kqemu-patch
Normal file
68
emulators/qemu/files/kqemu-patch
Normal file
@ -0,0 +1,68 @@
|
||||
Index: qemu/kqemu/Makefile
|
||||
@@ -1,62 +1,5 @@
|
||||
-ifeq ($(PATCHLEVEL),)
|
||||
-# compile in kqemu directory
|
||||
+KMOD= kqemu
|
||||
+SRCS= kmod_bsd.c
|
||||
+OBJS= kqemu-mod-i386.o
|
||||
|
||||
--include ../config-host.mak
|
||||
-
|
||||
-ifdef CONFIG_KBUILD26
|
||||
-# 2.6 build
|
||||
-
|
||||
-all: kqemu.ko
|
||||
-
|
||||
-kqemu.ko:
|
||||
- make -C $(KERNEL_PATH) M=`pwd` modules
|
||||
-
|
||||
-else
|
||||
-# 2.4 build
|
||||
-
|
||||
-all: kqemu.o
|
||||
-
|
||||
-kqemu.o:
|
||||
- make -C $(KERNEL_PATH) SUBDIRS=`pwd` modules
|
||||
-
|
||||
-endif # !CONFIG_KBUILD26
|
||||
-
|
||||
-clean:
|
||||
- rm -f kqemu.o kqemu.ko kmod.o kqemu-mod.o kqemu.mod.c *~
|
||||
-
|
||||
-FILES=Makefile README LICENSE install.sh kmod.c kqemu.h kqemu-mod-i386.o \
|
||||
- kqemu-doc.texi kqemu-doc.html
|
||||
-VERSION=0.6.2
|
||||
-
|
||||
-tar:
|
||||
- cd .. ; tar zcvf /tmp/kqemu-$(VERSION).tar.gz $(addprefix kqemu/, $(FILES))
|
||||
-
|
||||
-# documentation
|
||||
-doc: kqemu-doc.html
|
||||
-
|
||||
-%.html: %.texi
|
||||
- texi2html -monolithic -number $<
|
||||
-
|
||||
-else
|
||||
-
|
||||
-ifeq ($(PATCHLEVEL),4)
|
||||
-# called from 2.4 kernel kbuild
|
||||
-
|
||||
-obj-m:= kqemu.o
|
||||
-kqemu-objs:= kmod.o kqemu-mod-i386.o
|
||||
-
|
||||
-include $(TOPDIR)/Rules.make
|
||||
-
|
||||
-kqemu.o: $(kqemu-objs)
|
||||
- $(LD) -r -o $@ $(kqemu-objs)
|
||||
-
|
||||
-else
|
||||
-# called from 2.6 kernel kbuild
|
||||
-
|
||||
-obj-m:= kqemu.o
|
||||
-kqemu-objs:= kmod.o kqemu-mod.o
|
||||
-
|
||||
-$(obj)/kqemu-mod.o: $(src)/kqemu-mod-i386.o
|
||||
- cp $< $@
|
||||
-endif
|
||||
-endif # PATCHLEVEL
|
||||
+.include <bsd.kmod.mk>
|
@ -8,14 +8,19 @@ Index: qemu/Makefile
|
||||
for d in $(TARGET_DIRS); do \
|
||||
$(MAKE) -C $$d $@ || exit 1 ; \
|
||||
done
|
||||
@@ -25,6 +25,9 @@
|
||||
@@ -21,10 +21,13 @@
|
||||
ifdef CONFIG_WIN32
|
||||
$(MAKE) -C kqemu -f Makefile.winnt
|
||||
else
|
||||
- $(MAKE) -C kqemu
|
||||
+ cd kqemu && $(BSD_MAKE)
|
||||
endif
|
||||
endif
|
||||
|
||||
+bsd/libmath.a:
|
||||
+ ( cd bsd ; $(BSD_MAKE) CC=$(CC) )
|
||||
+
|
||||
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 block-bochs.c block-vpc.c
|
||||
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 block-bochs.c block-vpc.c block-vvfat.c
|
||||
$(CC) -DQEMU_TOOL $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $@ $^ -lz $(LIBS)
|
||||
|
||||
@@ -33,6 +36,7 @@
|
||||
@ -26,6 +31,25 @@ Index: qemu/Makefile
|
||||
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
|
||||
@@ -40,7 +44,7 @@
|
||||
$(MAKE) -C $$d $@ || exit 1 ; \
|
||||
done
|
||||
ifdef CONFIG_KQEMU
|
||||
- $(MAKE) -C kqemu clean
|
||||
+ cd kqemu && $(BSD_MAKE) clean
|
||||
endif
|
||||
|
||||
distclean: clean
|
||||
@@ -73,9 +77,6 @@
|
||||
for d in $(TARGET_DIRS); do \
|
||||
$(MAKE) -C $$d $@ || exit 1 ; \
|
||||
done
|
||||
-ifdef CONFIG_KQEMU
|
||||
- cd kqemu ; ./install.sh
|
||||
-endif
|
||||
|
||||
# various test targets
|
||||
test speed test2: all
|
||||
Index: qemu/Makefile.target
|
||||
@@ -391,8 +391,8 @@
|
||||
VL_LDFLAGS+=-Wl,-G0 -Wl,-T,$(SRC_PATH)/ia64.ld
|
||||
|
40
emulators/qemu/files/patch-osdep.c
Normal file
40
emulators/qemu/files/patch-osdep.c
Normal file
@ -0,0 +1,40 @@
|
||||
Index: qemu/osdep.c
|
||||
@@ -323,7 +323,9 @@
|
||||
|
||||
#elif defined(USE_KQEMU)
|
||||
|
||||
+#ifndef __FreeBSD__
|
||||
#include <sys/vfs.h>
|
||||
+#endif
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
@@ -334,6 +336,7 @@
|
||||
const char *tmpdir;
|
||||
char phys_ram_file[1024];
|
||||
void *ptr;
|
||||
+#ifndef __FreeBSD__
|
||||
struct statfs stfs;
|
||||
|
||||
if (phys_ram_fd < 0) {
|
||||
@@ -389,12 +392,20 @@
|
||||
}
|
||||
unlink(phys_ram_file);
|
||||
}
|
||||
+#endif
|
||||
size = (size + 4095) & ~4095;
|
||||
+#ifndef __FreeBSD__
|
||||
ftruncate(phys_ram_fd, phys_ram_size + size);
|
||||
ptr = mmap(NULL,
|
||||
size,
|
||||
PROT_WRITE | PROT_READ, MAP_SHARED,
|
||||
phys_ram_fd, phys_ram_size);
|
||||
+#else
|
||||
+ ptr = mmap(NULL,
|
||||
+ size,
|
||||
+ PROT_WRITE | PROT_READ, MAP_PRIVATE|MAP_ANON,
|
||||
+ -1, 0);
|
||||
+#endif
|
||||
if (ptr == MAP_FAILED) {
|
||||
fprintf(stderr, "Could not map physical memory\n");
|
||||
exit(1);
|
@ -49,3 +49,5 @@ share/qemu/keymaps/tr
|
||||
@dirrm share/qemu/keymaps
|
||||
@dirrm share/qemu
|
||||
%%PORTDOCS%%@dirrm %%DOCSDIR%%
|
||||
@cwd /
|
||||
%%WITH_KQEMU%%%%KMODDIR%%/kqemu.ko
|
||||
|
Loading…
Reference in New Issue
Block a user