? crx.diff
Index: kernel/emulation.c
===================================================================
RCS file: /cvsroot-freemware/plex86/kernel/emulation.c,v
retrieving revision 1.4
diff -u -r1.4 emulation.c
--- kernel/emulation.c	2000/04/11 19:04:05	1.4
+++ kernel/emulation.c	2000/04/12 07:08:16
@@ -39,8 +39,8 @@
 int emulate_lldt(vm_t *, Bit16u selector);
 int emulate_ltr(vm_t *, Bit16u selector);
 int emulate_lmsw(vm_t *);
-int emulate_mov_from_cr(vm_t *);
-int emulate_mov_to_cr(vm_t *);
+int emulate_mov_from_cr(vm_t *, guest_context_t *);
+int emulate_mov_to_cr(vm_t *, guest_context_t *);
 int emulate_mov_from_dr(vm_t *);
 int emulate_mov_to_dr(vm_t *);
 int emulate_in(vm_t *, guest_context_t *context, int op_size, int port);
@@ -729,6 +729,14 @@
 	  action = emulate_wbinvd(vm);
 	  break;
 
+	case 0x20: /* mov r32, CRx (CRx to register)*/
+	  action = emulate_mov_from_cr(vm, context);
+	  break;
+
+	case 0x22: /* mov CRx, r32 */
+	  action = emulate_mov_to_cr(vm, context);
+ 	  break;
+
         case 0xa1: /* pop FS */
             val = guest_stack_pop(vm, &esp, operand_size);
             action = emulate_load_fs(vm, context, val);
@@ -1368,7 +1376,124 @@
     return 4;
 }
 
+int 
+emulate_mov_from_cr(vm_t *vm, guest_context_t *context)
+     /* move from CRx into register */
+{
+  Bit8u data;
+  Bit32u eip;
+  Bit32u crx = 0;
+
+  eip = context->eip + 2;
+  data = read_guest_byte(vm, &eip);
+  switch ( FieldReg(data) )
+    {
+    case 0: /* control register */
+      crx = vm->common.guest_cpu_state.cr0;
+      break;
+
+    case 1: context->error=1;return 0; /* reserved */
+    case 2: context->error=2;return 0; /* linear page fault address; unsupported for now */
+
+    case 3: /* page table base register */
+      crx = vm->common.guest_cpu_state.cr3;
+      break;
+
+    case 4: /* pentium control register */
+      crx = vm->common.guest_cpu_state.cr4;
+      break;
+
+    default:
+      context->error = data;
+      return 0;
+      break;
+    }
+
+  switch( FieldRM(data))
+    {
+    case 0: /* eax */
+      context->eax = crx;break;
+    case 1: /* ecx */
+      context->ecx = crx;break;
+    case 2: /* edx */
+      context->edx = crx;break;
+    case 3: /* ebx */
+      context->ebx = crx;break;
+    case 4: /* esp */
+      context->esp = crx;break;
+    case 5: /* ebp */
+      context->ebp = crx;break;
+    case 6: /* esi */
+      context->esi = crx;break;
+    case 7: /* edi */
+      context->edi = crx;break;
+    }
+  context->eip += 3;
+  return 1;
+}
+
+int 
+emulate_mov_to_cr(vm_t *vm, guest_context_t *context)
+     /* move from register into virtual CRx
+      * FIXME: no emulation is done yet, add this ...*/
+{
+  Bit8u data;
+  Bit32u eip;
+  Bit32u crx = 0;
+
+  eip = context->eip + 2;
+  data = read_guest_byte(vm, &eip);
+
+  // fetch data from register
+  switch( FieldRM(data))
+    {
+    case 0: /* eax */
+      crx = context->eax;break;
+    case 1: /* ecx */
+      crx = context->ecx;break;
+    case 2: /* edx */
+      crx = context->edx;break;
+    case 3: /* ebx */
+      crx = context->ebx;break;
+    case 4: /* esp */
+      crx = context->esp;break;
+    case 5: /* ebp */
+      crx = context->ebp;break;
+    case 6: /* esi */
+      crx = context->esi;break;
+    case 7: /* edi */
+      crx = context->edi;break;
+    }
 
+  // store data in virtual control registers
+  switch ( FieldReg(data) )
+    {
+    case 0: /* control register */
+      vm->common.guest_cpu_state.cr0 = crx;
+      break;
+
+    case 1: context->error=1;return 0; /* reserved */
+    case 2: context->error=2;return 0; /* linear page fault address; unsupported for now */
+
+    case 3: /* page table base register */
+      vm->common.guest_cpu_state.cr3 = crx;
+      break;
+
+    case 4: /* pentium control register */
+      vm->common.guest_cpu_state.cr4 = crx;
+      break;
+
+    default:
+      context->error = data;
+      return 0;
+      break;
+    }
+
+  context->eip += 3;
+  return 1;
+}
+
+
 int
 emulate_ljmp(vm_t *vm, guest_context_t *context)
      /* ljmp may be an intersegment call
@@ -1394,3 +1519,4 @@
 
     return 1;
 }
+
Index: kernel/include/monitor.h
===================================================================
RCS file: /cvsroot-freemware/plex86/kernel/include/monitor.h,v
retrieving revision 1.4
diff -u -r1.4 monitor.h
--- kernel/include/monitor.h	2000/03/26 18:17:48	1.4
+++ kernel/include/monitor.h	2000/04/12 07:08:16
@@ -172,6 +172,7 @@
   Bit32u cr1;
   Bit32u cr2;
   Bit32u cr3;
+  Bit32u cr4;
   } guest_cpu_state_t;
 
 
 
