* [Qemu-devel] kqemu port to FreeBSD 5.x + qemu patch
@ 2005-03-23 19:29 Pierre Beyssac
2005-03-24 1:35 ` Antony T Curtis
0 siblings, 1 reply; 7+ messages in thread
From: Pierre Beyssac @ 2005-03-23 19:29 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 872 bytes --]
Hello,
I have written a kqemu wrapper for FreeBSD 5.x (attached). It seems
to work (I've had no crash at all) but it's alpha quality and it
currently lacks working kqemu_free_page() and kqemu_vfree() hooks
(which were never called by kqemu-mid-i386.o in my tests).
I would be interested in any comments. It's substantially different
from the code posted here by Antony T Curtis.
I have also attached a patch to qemu/osdep.c to replace the mmaped
"swap" file with a MAP_ANON area; using a file is unnecessary under
FreeBSD; perhaps it's been done this way due to Linux peculiarities,
but I don't see why. The patch doesn't help performance noticeably
but it saves some precious disk or ramdisk space.
--
A: Yes. Pierre Beyssac pb@freebsd.org
>Q: Are you sure?
>>A: Because it reverses the logical flow of conversation.
>>>Q: Why is top posting annoying in email?
[-- Attachment #2: kmod-freebsd.c --]
[-- Type: text/plain, Size: 7367 bytes --]
/* $Id: kmod-freebsd.c,v 1.3 2005/03/23 17:53:24 pb Exp $ */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/ioccom.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/sched.h>
#include <sys/signalvar.h>
#include <sys/kernel.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_extern.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
#include <vm/vm_kern.h>
#include <machine/vmparam.h>
#include <machine/stdarg.h>
#define __KERNEL__
#include "kqemu.h"
MALLOC_DECLARE(M_KQEMU);
MALLOC_DEFINE(M_KQEMU, "kqemu", "kqemu buffers");
#define USER_BASE 0x1000
/* quick and dirty convert a physical address to a virtual address */
static vm_offset_t pa_to_va(vm_paddr_t pa, vm_offset_t beg, vm_offset_t end)
{
struct vmspace *vm = curproc->p_vmspace;
vm_offset_t va;
pmap_t pmap;
pmap = vm_map_pmap(&vm->vm_map);
for (va = beg; va != end; va += PAGE_SIZE)
if (pa == pmap_extract(pmap, va))
return va;
printf("pa_to_va failed: pa=%08x\n", pa);
return -1;
}
/* lock the page at virtual address 'user_addr' and return its
physical page index. Return -1 if error */
unsigned long CDECL kqemu_lock_user_page(unsigned long user_addr)
{
struct vmspace *vm = curproc->p_vmspace;
vm_offset_t va = user_addr;
vm_paddr_t pa = 0;
int ret;
pmap_t pmap;
ret = vm_map_wire(&vm->vm_map, va, va+PAGE_SIZE, VM_MAP_WIRE_USER);
if (ret != KERN_SUCCESS) {
printf("kqemu_lock_user_page(%08lx) failed, ret=%d\n", user_addr, ret);
return -1;
}
pmap = vm_map_pmap(&vm->vm_map);
pa = pmap_extract(pmap, va);
// printf("kqemu_lock_user_page(%08lx) va=%08x pa=%08x\n", user_addr, va, pa);
return pa >> PAGE_SHIFT;
}
void CDECL kqemu_unlock_user_page(unsigned long page_index)
{
struct vmspace *vm = curproc->p_vmspace;
vm_offset_t va;
int ret;
// printf("kqemu_unlock_user_page(%08lx)\n", page_index);
va = pa_to_va(page_index << PAGE_SHIFT, USER_BASE, KERNBASE);
ret = vm_map_unwire(&vm->vm_map, va, va+PAGE_SIZE, VM_MAP_WIRE_USER);
if (ret != KERN_SUCCESS) {
printf("kqemu_unlock_user_page(%08lx) failed, ret=%d\n", page_index, ret);
}
}
/*
* Allocate a new page. The page must be mapped in the kernel space.
* Return the page_index or -1 if error.
*/
unsigned long CDECL kqemu_alloc_zeroed_page(void)
{
pmap_t pmap;
vm_offset_t va;
vm_paddr_t pa;
va = kmem_alloc(kernel_map, PAGE_SIZE);
if (va == 0) {
printf("kqemu_alloc_zeroed_page: NULL\n");
return -1;
}
pmap = vm_map_pmap(kernel_map);
pa = pmap_extract(pmap, va);
// printf("kqemu_alloc_zeroed_page: %08x\n", pa);
return pa >> PAGE_SHIFT;
}
void CDECL kqemu_free_page(unsigned long page_index)
{
printf("kqemu_free_page(%08lx)\n", page_index);
}
/* return kernel address of the physical page page_index */
void *CDECL kqemu_page_kaddr(unsigned long page_index)
{
vm_offset_t va;
va = pa_to_va(page_index << PAGE_SHIFT, KERNBASE, 0);
if (va != -1) {
printf("kqemu_page_kaddr(%08lx)=%08x\n", page_index, va);
return (void *)va;
}
printf("kqemu_page_kaddr(%08lx)=NOT FOUND\n", page_index);
return NULL;
}
/* contraint: each page of the vmalloced area must be in the first 4
GB of physical memory */
void * CDECL kqemu_vmalloc(unsigned int size)
{
struct vmspace *vm = curproc->p_vmspace;
vm_offset_t va = USER_BASE;
int rv;
if (size % PAGE_SIZE != 0) {
printf("kqemu_vmalloc(%d) not a multiple of page size\n", size);
return NULL;
}
rv = vm_map_find(&vm->vm_map, NULL, 0, &va, size, 1,
VM_PROT_ALL, VM_PROT_ALL, 0);
if (rv != KERN_SUCCESS) {
printf("kqemu_vmalloc(%d) failed rv=%d\n", size, rv);
return NULL;
}
printf("kqemu_vmalloc(%d): %08x\n", size, va);
return (void *)va;
}
void CDECL kqemu_vfree(void *ptr)
{
printf("kqemu_vfree(%p)\n", ptr);
}
/* return the physical page index for a given virtual page */
unsigned long CDECL kqemu_vmalloc_to_phys(const void *vaddr)
{
struct vmspace *vm = curproc->p_vmspace;
vm_paddr_t pa;
pmap_t pmap;
pmap = vm_map_pmap(&vm->vm_map);
pa = pmap_extract(pmap, (vm_offset_t)vaddr);
if (pa == 0) {
printf("kqemu_vmalloc_to_phys(%p)->error\n", vaddr);
return -1;
}
printf("kqemu_vmalloc_to_phys(%p)->%08x\n", vaddr, pa);
return pa >> PAGE_SHIFT;
}
/* return TRUE if a signal is pending (i.e. the guest must stop
execution) */
int CDECL kqemu_schedule(void)
{
// printf("kqemu_schedule\n");
mtx_lock_spin(&sched_lock);
mi_switch(SW_VOL, NULL);
mtx_unlock_spin(&sched_lock);
return SIGPENDING(curthread);
}
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);
}
struct kqemu_instance {
// struct semaphore sem;
struct kqemu_state *state;
};
static d_close_t kqemu_close;
static d_open_t kqemu_open;
static d_ioctl_t kqemu_ioctl;
static struct cdevsw kqemu_cdevsw = {
.d_version = D_VERSION,
.d_flags = D_NEEDGIANT,
.d_open = kqemu_open,
.d_ioctl = kqemu_ioctl,
.d_close = kqemu_close,
.d_name = "kqemu"
};
/* For use with make_dev(9)/destroy_dev(9). */
static struct cdev *kqemu_dev;
/* ARGSUSED */
static int
kqemu_open(struct cdev *dev, int flags, int fmt __unused,
struct thread *td)
{
struct kqemu_instance *ks;
ks = malloc(sizeof(struct kqemu_instance), M_KQEMU, M_WAITOK);
if (ks == NULL) {
printf("malloc failed\n");
return ENOMEM;
}
ks->state = NULL;
dev->si_drv1 = ks;
return 0;
}
/* ARGSUSED */
static int
kqemu_ioctl(struct cdev *dev, u_long cmd, caddr_t addr,
int flags __unused, struct thread *td)
{
int error = 0;
int ret;
struct kqemu_instance *ks = dev->si_drv1;
struct kqemu_state *s = ks->state;
switch(cmd) {
case KQEMU_INIT: {
struct kqemu_init d1, *d = &d1;
if (s != NULL) {
error = EIO;
break;
}
d1 = *(struct kqemu_init *)addr;
printf("ram_base=%p ram_size=%ld\n", d1.ram_base, d1.ram_size);
s = kqemu_init(d, 16000);
if (s == NULL) {
error = ENOMEM;
break;
}
ks->state = s;
break;
}
case KQEMU_EXEC: {
struct kqemu_cpu_state *ctx;
if (s == NULL) {
error = EIO;
break;
}
ctx = kqemu_get_cpu_state(s);
*ctx = *(struct kqemu_cpu_state *)addr;
DROP_GIANT();
ret = kqemu_exec(s);
PICKUP_GIANT();
td->td_retval[0] = ret;
*(struct kqemu_cpu_state *)addr = *ctx;
break;
}
case KQEMU_GET_VERSION:
*(int *)addr = KQEMU_VERSION;
break;
default:
error = EINVAL;
}
return error;
}
/* ARGSUSED */
static int
kqemu_close(struct cdev *dev __unused, int flags, int fmt __unused,
struct thread *td)
{
return 0;
}
/* ARGSUSED */
static int
kqemu_modevent(module_t mod __unused, int type, void *data __unused)
{
int error = 0;
switch (type) {
case MOD_LOAD:
printf("kqemu version 0x%08x\n", KQEMU_VERSION);
kqemu_dev = make_dev(&kqemu_cdevsw, 0,
UID_ROOT, GID_WHEEL, 0666, "kqemu");
break;
case MOD_UNLOAD:
destroy_dev(kqemu_dev);
break;
case MOD_SHUTDOWN:
break;
default:
error = EOPNOTSUPP;
break;
}
return (error);
}
DEV_MODULE(kqemu, kqemu_modevent, NULL);
MODULE_VERSION(kqemu, 1);
[-- Attachment #3: Makefile --]
[-- Type: text/plain, Size: 135 bytes --]
# $Id: Makefile,v 1.1.1.1 2005/03/23 12:29:35 pb Exp $
KMOD= kqemu
SRCS= kmod-freebsd.c
OBJS= kqemu-mod-i386.o
.include <bsd.kmod.mk>
[-- Attachment #4: patch-osdep.c --]
[-- Type: text/plain, Size: 820 bytes --]
--- osdep.c.orig Mon Feb 21 21:10:36 2005
+++ osdep.c Wed Mar 23 18:10:33 2005
@@ -321,6 +321,7 @@
char phys_ram_file[1024];
void *ptr;
+#if 0
if (phys_ram_fd < 0) {
tmpdir = getenv("QEMU_TMPDIR");
if (!tmpdir)
@@ -349,12 +350,20 @@
}
unlink(phys_ram_file);
}
+#endif
size = (size + 4095) & ~4095;
+#if 0
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);
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] kqemu port to FreeBSD 5.x + qemu patch 2005-03-23 19:29 [Qemu-devel] kqemu port to FreeBSD 5.x + qemu patch Pierre Beyssac @ 2005-03-24 1:35 ` Antony T Curtis 2005-03-24 1:51 ` Antony T Curtis 0 siblings, 1 reply; 7+ messages in thread From: Antony T Curtis @ 2005-03-24 1:35 UTC (permalink / raw) To: qemu-devel On Wed, 2005-03-23 at 20:29 +0100, Pierre Beyssac wrote: > Hello, > > I have written a kqemu wrapper for FreeBSD 5.x (attached). It seems > to work (I've had no crash at all) but it's alpha quality and it > currently lacks working kqemu_free_page() and kqemu_vfree() hooks > (which were never called by kqemu-mid-i386.o in my tests). <snip> This is the great thing about opensource - theres often more than one way to do things. The latest iteration of my code is attached and it does work on both FreeBSD 4.9 and FreeBSD 5.3 - except that OS/2 Warp 4 doesn't seem to like running with kqemu. This version seems a lot more stable, I guess someone is going to have to decide which is the better wrapper. -- Antony T Curtis, BSc. UNIX, Linux, *BSD, Networking antony.t.curtis@ntlworld.com C++, J2EE, Perl, MySQL, Apache IT Consultancy. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] kqemu port to FreeBSD 5.x + qemu patch 2005-03-24 1:35 ` Antony T Curtis @ 2005-03-24 1:51 ` Antony T Curtis 0 siblings, 0 replies; 7+ messages in thread From: Antony T Curtis @ 2005-03-24 1:51 UTC (permalink / raw) To: qemu-devel [-- Attachment #1: Type: text/plain, Size: 1069 bytes --] On Thu, 2005-03-24 at 01:35 +0000, Antony T Curtis wrote: > On Wed, 2005-03-23 at 20:29 +0100, Pierre Beyssac wrote: > > Hello, > > > > I have written a kqemu wrapper for FreeBSD 5.x (attached). It seems > > to work (I've had no crash at all) but it's alpha quality and it > > currently lacks working kqemu_free_page() and kqemu_vfree() hooks > > (which were never called by kqemu-mid-i386.o in my tests). > > <snip> > > This is the great thing about opensource - theres often more than one > way to do things. > > The latest iteration of my code is attached and it does work on both > FreeBSD 4.9 and FreeBSD 5.3 - except that OS/2 Warp 4 doesn't seem to > like running with kqemu. > > This version seems a lot more stable, I guess someone is going to have > to decide which is the better wrapper. Heh,,, I guess it would actually help if I attached the file. -- Antony T Curtis, BSc. UNIX, Linux, *BSD, Networking antony.t.curtis@ntlworld.com C++, J2EE, Perl, MySQL, Apache IT Consultancy. [-- Attachment #2: kmod_bsd.c --] [-- Type: text/x-csrc, Size: 13055 bytes --] /* * 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); ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] kqemu port to FreeBSD 5.x + qemu patch
@ 2005-03-25 9:15 ecs user
2005-03-25 9:49 ` Antony T Curtis
0 siblings, 1 reply; 7+ messages in thread
From: ecs user @ 2005-03-25 9:15 UTC (permalink / raw)
To: qemu-devel
> From: Antony T Curtis <antony.t.curtis@ntlworld.com>
> The latest iteration of my code is attached and it
> does > work on both FreeBSD 4.9 and FreeBSD 5.3 -
> except that OS/2 Warp 4 doesn't seem to like
> running with kqemu.
Antony do you know how to fix the OS/2 Warp4 problems?
I have a several IBM OS2 Warp 4 MCP2 base images that
I can not get to run.
One is a test image of only 10MB put it still has OS/2
full WorkPlace Shell desktop. I could send you, or
anyone else that is interested, the image if you know
how to debug the QEMU issues.
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] kqemu port to FreeBSD 5.x + qemu patch 2005-03-25 9:15 ecs user @ 2005-03-25 9:49 ` Antony T Curtis 2005-03-25 11:48 ` Hetz Ben Hamo 0 siblings, 1 reply; 7+ messages in thread From: Antony T Curtis @ 2005-03-25 9:49 UTC (permalink / raw) To: qemu-devel On Fri, 2005-03-25 at 01:15 -0800, ecs user wrote: > > From: Antony T Curtis <antony.t.curtis@ntlworld.com> > > The latest iteration of my code is attached and it > > does > work on both FreeBSD 4.9 and FreeBSD 5.3 - > > except that OS/2 Warp 4 doesn't seem to like > > running with kqemu. > > Antony do you know how to fix the OS/2 Warp4 problems? > > I have a several IBM OS2 Warp 4 MCP2 base images that > I can not get to run. I have Warp 4 with full WPS running fine on current CVS of QEMU - but only in VGA mode - I cannot get the Cirrus Logic video drivers to recognise the emulated card - I'll try with SciTech's driver someday soon. Since OS/2 works without KQEMU, I figure that theres something in KQEMU which is causing the fault. > One is a test image of only 10MB put it still has OS/2 > full WorkPlace Shell desktop. I could send you, or > anyone else that is interested, the image if you know > how to debug the QEMU issues. > > > __________________________________________________ > Do You Yahoo!? > Tired of spam? Yahoo! Mail has the best spam protection around > http://mail.yahoo.com > > > _______________________________________________ > Qemu-devel mailing list > Qemu-devel@nongnu.org > http://lists.nongnu.org/mailman/listinfo/qemu-devel -- Antony T Curtis, BSc. UNIX, Linux, *BSD, Networking antony.t.curtis@ntlworld.com C++, J2EE, Perl, MySQL, Apache IT Consultancy. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] kqemu port to FreeBSD 5.x + qemu patch 2005-03-25 9:49 ` Antony T Curtis @ 2005-03-25 11:48 ` Hetz Ben Hamo 0 siblings, 0 replies; 7+ messages in thread From: Hetz Ben Hamo @ 2005-03-25 11:48 UTC (permalink / raw) To: qemu-devel I think that in this issue, it's KQEMU's fault, not your wrapper stuff, since it does have the same problems with windows 9x/ME. Thanks, Hetz On Fri, 25 Mar 2005 09:49:04 +0000, Antony T Curtis <antony.t.curtis@ntlworld.com> wrote: > On Fri, 2005-03-25 at 01:15 -0800, ecs user wrote: > > > From: Antony T Curtis <antony.t.curtis@ntlworld.com> > > > The latest iteration of my code is attached and it > > > does > work on both FreeBSD 4.9 and FreeBSD 5.3 - > > > except that OS/2 Warp 4 doesn't seem to like > > > running with kqemu. > > > > Antony do you know how to fix the OS/2 Warp4 problems? > > > > I have a several IBM OS2 Warp 4 MCP2 base images that > > I can not get to run. > > I have Warp 4 with full WPS running fine on current CVS of QEMU - but > only in VGA mode - I cannot get the Cirrus Logic video drivers to > recognise the emulated card - I'll try with SciTech's driver someday > soon. > > Since OS/2 works without KQEMU, I figure that theres something in KQEMU > which is causing the fault. > > > One is a test image of only 10MB put it still has OS/2 > > full WorkPlace Shell desktop. I could send you, or > > anyone else that is interested, the image if you know > > how to debug the QEMU issues. > > > > > > __________________________________________________ > > Do You Yahoo!? > > Tired of spam? Yahoo! Mail has the best spam protection around > > http://mail.yahoo.com > > > > > > _______________________________________________ > > Qemu-devel mailing list > > Qemu-devel@nongnu.org > > http://lists.nongnu.org/mailman/listinfo/qemu-devel > -- > Antony T Curtis, BSc. UNIX, Linux, *BSD, Networking > antony.t.curtis@ntlworld.com C++, J2EE, Perl, MySQL, Apache > IT Consultancy. > > _______________________________________________ > Qemu-devel mailing list > Qemu-devel@nongnu.org > http://lists.nongnu.org/mailman/listinfo/qemu-devel > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] kqemu port to FreeBSD 5.x + qemu patch @ 2005-03-25 13:50 ecs user 0 siblings, 0 replies; 7+ messages in thread From: ecs user @ 2005-03-25 13:50 UTC (permalink / raw) To: qemu-devel > From: Antony T Curtis <antony.t.curtis@ntlworld.com> > I have Warp 4 with full WPS running fine on current > CVS of QEMU - but only in VGA mode - I cannot get the > Cirrus Logic video drivers to recognise the emulated > card - I'll try with SciTech's driver someday soon. My image had the video working at 1024x768 resolution Could you test my image? thanks __________________________________ Do you Yahoo!? Make Yahoo! your home page http://www.yahoo.com/r/hs ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2005-03-25 14:08 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2005-03-23 19:29 [Qemu-devel] kqemu port to FreeBSD 5.x + qemu patch Pierre Beyssac 2005-03-24 1:35 ` Antony T Curtis 2005-03-24 1:51 ` Antony T Curtis -- strict thread matches above, loose matches on Subject: below -- 2005-03-25 9:15 ecs user 2005-03-25 9:49 ` Antony T Curtis 2005-03-25 11:48 ` Hetz Ben Hamo 2005-03-25 13:50 ecs user
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).