WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] vmx-mmio-ioemu.patch

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] vmx-mmio-ioemu.patch
From: Leendert van Doorn <leendert@xxxxxxxxxxxxxx>
Date: Fri, 02 Sep 2005 12:55:52 -0400
Cc: asit.k.mallick@xxxxxxxxx, arun.sharma@xxxxxxxxx
Delivery-date: Fri, 02 Sep 2005 17:09:21 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Organization: IBM T.J. Watson Research Center
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Attached are the patches for new ioemu communication mechanism. The new
mechanism provides richer I/O operation semantics, such as and,or,xor
operation on MMIO space. This is necessary for operating systems such
as Windows XP and Windows 2003.

This is the first part of a two part patch. This patch applies to ioemu.

(patches are against current xen-vt-testing tree)

Signed-Off-By: Leendert van Doorn <leendert@xxxxxxxxxxxxxx>


diff -r 04ca47c298b5 tools/ioemu/exec.c
--- a/tools/ioemu/exec.c        Thu Sep  1 21:30:51 2005
+++ b/tools/ioemu/exec.c        Fri Sep  2 11:49:51 2005
@@ -142,6 +142,10 @@
 #else
         setvbuf(logfile, NULL, _IOLBF, 0);
 #endif
+/*
+       stdout = logfile;
+       stderr = logfile;
+*/
     }
 }
 
@@ -386,9 +390,6 @@
                     io_mem_write[io_index][1](io_mem_opaque[io_index], addr, 
val);
                     l = 2;
                 } else {
-                    if (l!=1){
-                        fprintf(logfile, "ERROR 8 bit mmio\n");
-                    }
                     /* 8 bit access */
                     val = ldub_raw(buf);
                     io_mem_write[io_index][0](io_mem_opaque[io_index], addr, 
val);
diff -r 04ca47c298b5 tools/ioemu/target-i386-dm/helper2.c
--- a/tools/ioemu/target-i386-dm/helper2.c      Thu Sep  1 21:30:51 2005
+++ b/tools/ioemu/target-i386-dm/helper2.c      Fri Sep  2 11:49:51 2005
@@ -169,133 +169,217 @@
 unsigned long
 do_inp(CPUState *env, unsigned long addr, unsigned long size)
 {
-  switch(size) {
-      case 1:
-        return cpu_inb(env, addr);
-      case 2:
-        return cpu_inw(env, addr);
-      case 4:
-        return cpu_inl(env, addr);
-      default:
-       fprintf(logfile, "inp: bad size: %lx %lx\n", addr, size);
-        exit(-1);
-  }
+       switch(size) {
+       case 1:
+               return cpu_inb(env, addr);
+       case 2:
+               return cpu_inw(env, addr);
+       case 4:
+               return cpu_inl(env, addr);
+       default:
+               fprintf(logfile, "inp: bad size: %lx %lx\n", addr, size);
+               exit(-1);
+       }
 }
 
 void
 do_outp(CPUState *env, unsigned long addr, unsigned long size, 
         unsigned long val)
 {
-  switch(size) {
-      case 1:
-        return cpu_outb(env, addr, val);
-      case 2:
-        return cpu_outw(env, addr, val);
-      case 4:
-        return cpu_outl(env, addr, val);
-      default:
-       fprintf(logfile, "outp: bad size: %lx %lx\n", addr, size);
-        exit(-1);
-  }
+       switch(size) {
+       case 1:
+               return cpu_outb(env, addr, val);
+       case 2:
+               return cpu_outw(env, addr, val);
+       case 4:
+               return cpu_outl(env, addr, val);
+       default:
+               fprintf(logfile, "outp: bad size: %lx %lx\n", addr, size);
+               exit(-1);
+       }
 }
 
 extern void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, 
                                    int len, int is_write);
 
 static inline void
-read_physical(target_phys_addr_t addr, unsigned long size, void *val)
-{
-        return cpu_physical_memory_rw(addr, val, size, 0);
+read_physical(u64 addr, unsigned long size, void *val)
+{
+        return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 0);
 }
 
 static inline void
-write_physical(target_phys_addr_t addr, unsigned long size, void *val)
-{
-        return cpu_physical_memory_rw(addr, val, size, 1);
-}
-
-//send the ioreq to device model
-void cpu_dispatch_ioreq(CPUState *env, ioreq_t *req)
-{
-       int i;
-       int sign;
-
-       sign = (req->df) ? -1 : 1;
-
-       if ((!req->pdata_valid) && (req->dir == IOREQ_WRITE)) {
-               if (req->size != 4) {
-                       // Bochs expects higher bits to be 0
-                       req->u.data &= (1UL << (8 * req->size))-1;
-               }
-       }
-
-       if (req->port_mm == 0){//port io
-               if(req->dir == IOREQ_READ){//read
-                       if (!req->pdata_valid) {
-                               req->u.data = do_inp(env, req->addr, req->size);
-                       } else {
-                               unsigned long tmp; 
-
-                               for (i = 0; i < req->count; i++) {
-                                       tmp = do_inp(env, req->addr, req->size);
-                                       
write_physical((target_phys_addr_t)req->u.pdata + (sign * i * req->size), 
-                                                      req->size, &tmp);
-                               }
-                       }
-               } else if(req->dir == IOREQ_WRITE) {
-                       if (!req->pdata_valid) {
-                               do_outp(env, req->addr, req->size, req->u.data);
-                       } else {
-                               for (i = 0; i < req->count; i++) {
-                                       unsigned long tmp;
-
-                                       
read_physical((target_phys_addr_t)req->u.pdata + (sign * i * req->size), 
req->size, 
-                                                     &tmp);
-                                       do_outp(env, req->addr, req->size, tmp);
-                               }
-                       }
-                       
-               }
-       } else if (req->port_mm == 1){//memory map io
+write_physical(u64 addr, unsigned long size, void *val)
+{
+        return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 1);
+}
+
+void
+cpu_ioreq_pio(CPUState *env, ioreq_t *req)
+{
+       int i, sign;
+
+       sign = req->df ? -1 : 1;
+
+       if (req->dir == IOREQ_READ) {
                if (!req->pdata_valid) {
-                       //handle stos
-                       if(req->dir == IOREQ_READ) { //read
-                               for (i = 0; i < req->count; i++) {
-                                       
read_physical((target_phys_addr_t)req->addr + (sign * i * req->size), 
req->size, &req->u.data);
-                               }
-                       } else if(req->dir == IOREQ_WRITE) { //write
-                               for (i = 0; i < req->count; i++) {
-                                       
write_physical((target_phys_addr_t)req->addr + (sign * i * req->size), 
req->size, &req->u.data);
-                               }
-                       }
+                       req->u.data = do_inp(env, req->addr, req->size);
                } else {
-                       //handle movs
-                       unsigned long tmp;
-                       if (req->dir == IOREQ_READ) {
-                               for (i = 0; i < req->count; i++) {
-                                       
read_physical((target_phys_addr_t)req->addr + (sign * i * req->size), 
req->size, &tmp);
-                                       
write_physical((target_phys_addr_t)req->u.pdata + (sign * i * req->size), 
req->size, &tmp);
-                               }
-                       } else if (req->dir == IOREQ_WRITE) {
-                               for (i = 0; i < req->count; i++) {
-                                       
read_physical((target_phys_addr_t)req->u.pdata + (sign * i * req->size), 
req->size, &tmp);
-                                       
write_physical((target_phys_addr_t)req->addr + (sign * i * req->size), 
req->size, &tmp);
-                               }
-                       }
-               }
-       }
-        /* No state change if state = STATE_IORESP_HOOK */
-        if (req->state == STATE_IOREQ_INPROCESS)
-                req->state = STATE_IORESP_READY;
-       env->send_event = 1;
+                       unsigned long tmp; 
+
+                       for (i = 0; i < req->count; i++) {
+                               tmp = do_inp(env, req->addr, req->size);
+                               write_physical((target_phys_addr_t) req->u.pdata
+                                               + (sign * i * req->size), 
+                                       req->size, &tmp);
+                       }
+               }
+       } else if (req->dir == IOREQ_WRITE) {
+               if (!req->pdata_valid) {
+                       do_outp(env, req->addr, req->size, req->u.data);
+               } else {
+                       for (i = 0; i < req->count; i++) {
+                               unsigned long tmp;
+
+                               read_physical((target_phys_addr_t) req->u.pdata
+                                               + (sign * i * req->size),
+                                       req->size, &tmp);
+                               do_outp(env, req->addr, req->size, tmp);
+                       }
+               }
+       }
+}
+
+void
+cpu_ioreq_move(CPUState *env, ioreq_t *req)
+{
+       int i, sign;
+
+       sign = req->df ? -1 : 1;
+
+       if (!req->pdata_valid) {
+               if (req->dir == IOREQ_READ) {
+                       for (i = 0; i < req->count; i++) {
+                               read_physical(req->addr
+                                               + (sign * i * req->size),
+                                       req->size, &req->u.data);
+                       }
+               } else if (req->dir == IOREQ_WRITE) {
+                       for (i = 0; i < req->count; i++) {
+                               write_physical(req->addr
+                                               + (sign * i * req->size),
+                                       req->size, &req->u.data);
+                       }
+               }
+       } else {
+               unsigned long tmp;
+
+               if (req->dir == IOREQ_READ) {
+                       for (i = 0; i < req->count; i++) {
+                               read_physical(req->addr
+                                               + (sign * i * req->size),
+                                       req->size, &tmp);
+                               write_physical((target_phys_addr_t )req->u.pdata
+                                               + (sign * i * req->size),
+                                       req->size, &tmp);
+                       }
+               } else if (req->dir == IOREQ_WRITE) {
+                       for (i = 0; i < req->count; i++) {
+                               read_physical((target_phys_addr_t) req->u.pdata
+                                               + (sign * i * req->size),
+                                       req->size, &tmp);
+                               write_physical(req->addr
+                                               + (sign * i * req->size),
+                                       req->size, &tmp);
+                       }
+               }
+       }
+}
+
+void
+cpu_ioreq_and(CPUState *env, ioreq_t *req)
+{
+       unsigned long tmp1, tmp2;
+
+       if (req->pdata_valid != 0)
+               hw_error("expected scalar value");
+
+       read_physical(req->addr, req->size, &tmp1);
+       if (req->dir == IOREQ_WRITE) {
+               tmp2 = tmp1 & (unsigned long) req->u.data;
+               write_physical(req->addr, req->size, &tmp2);
+       }
+       req->u.data = tmp1;
+}
+
+void
+cpu_ioreq_or(CPUState *env, ioreq_t *req)
+{
+       unsigned long tmp1, tmp2;
+
+       if (req->pdata_valid != 0)
+               hw_error("expected scalar value");
+
+       read_physical(req->addr, req->size, &tmp1);
+       if (req->dir == IOREQ_WRITE) {
+               tmp2 = tmp1 | (unsigned long) req->u.data;
+               write_physical(req->addr, req->size, &tmp2);
+       }
+       req->u.data = tmp1;
+}
+
+void
+cpu_ioreq_xor(CPUState *env, ioreq_t *req)
+{
+       unsigned long tmp1, tmp2;
+
+       if (req->pdata_valid != 0)
+               hw_error("expected scalar value");
+
+       read_physical(req->addr, req->size, &tmp1);
+       if (req->dir == IOREQ_WRITE) {
+               tmp2 = tmp1 ^ (unsigned long) req->u.data;
+               write_physical(req->addr, req->size, &tmp2);
+       }
+       req->u.data = tmp1;
 }
 
 void
 cpu_handle_ioreq(CPUState *env)
 {
        ioreq_t *req = cpu_get_ioreq();
-       if (req)
-               cpu_dispatch_ioreq(env, req);
+
+       if (req) {
+               if ((!req->pdata_valid) && (req->dir == IOREQ_WRITE)) {
+                       if (req->size != 4)
+                               req->u.data &= (1UL << (8 * req->size))-1;
+               }
+
+               switch (req->type) {
+               case IOREQ_TYPE_PIO:
+                       cpu_ioreq_pio(env, req);
+                       break;
+               case IOREQ_TYPE_COPY:
+                       cpu_ioreq_move(env, req);
+                       break;
+               case IOREQ_TYPE_AND:
+                       cpu_ioreq_and(env, req);
+                       break;
+               case IOREQ_TYPE_OR:
+                       cpu_ioreq_or(env, req);
+                       break;
+               case IOREQ_TYPE_XOR:
+                       cpu_ioreq_xor(env, req);
+                       break;
+               default:
+                       hw_error("Invalid ioreq type 0x%x", req->type);
+               }
+
+               /* No state change if state = STATE_IORESP_HOOK */
+               if (req->state == STATE_IOREQ_INPROCESS)
+                       req->state = STATE_IORESP_READY;
+               env->send_event = 1;
+       }
 }
 
 void
@@ -321,7 +405,7 @@
 
        // Send a message on the event channel. Add the vector to the shared mem
        // page.
-       intr = &(shared_page->sp_global.pic_intr[0]);
+       intr = (unsigned long *) &(shared_page->sp_global.pic_intr[0]);
        atomic_set_bit(vector, intr);
         if (loglevel & CPU_LOG_INT)
                 fprintf(logfile, "injecting vector: %x\n", vector);
diff -r 04ca47c298b5 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Thu Sep  1 21:30:51 2005
+++ b/tools/ioemu/vl.c  Fri Sep  2 11:49:51 2005
@@ -413,6 +413,11 @@
     fprintf(stderr, "qemu: hardware error: ");
     vfprintf(stderr, fmt, ap);
     fprintf(stderr, "\n");
+    if (logfile) {
+       fprintf(logfile, "qemu: hardware error: ");
+       vfprintf(logfile, fmt, ap);
+       fprintf(logfile, "\n");
+    }
     va_end(ap);
     abort();
 }

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>