Index: /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 60663)
+++ /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 60664)
@@ -989,5 +989,6 @@
          * dead wrong on 8086 (see http://www.os2museum.com/wp/undocumented-8086-opcodes/).
          */
-        if (   bstr.equals("Intel 80286")
+        if (   bstr.equals("Intel 80386") /* just for now */
+            || bstr.equals("Intel 80286")
             || bstr.equals("Intel 80186")
             || bstr.equals("Nec V20")
Index: /trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp	(revision 60663)
+++ /trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp	(revision 60664)
@@ -715,5 +715,10 @@
         PGMCr0WpEnabled(pVCpu);
 
-    pVCpu->cpum.s.Guest.cr0 = cr0 | X86_CR0_ET;
+    /* The ET flag is settable on a 386 and hardwired on 486+. */
+    if (   !(cr0 & X86_CR0_ET)
+        && pVCpu->CTX_SUFF(pVM)->cpum.s.GuestFeatures.enmMicroarch != kCpumMicroarch_Intel_80386)
+        cr0 |= X86_CR0_ET;
+
+    pVCpu->cpum.s.Guest.cr0 = cr0;
     return VINF_SUCCESS;
 }
Index: /trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h	(revision 60663)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h	(revision 60664)
@@ -625,6 +625,8 @@
             }
 
-            fEflNew &=   X86_EFL_POPF_BITS & ~(X86_EFL_IOPL);
-            fEflNew |= ~(X86_EFL_POPF_BITS & ~(X86_EFL_IOPL)) & fEflOld;
+            const uint32_t fPopfBits = IEMCPU_TO_VM(pIemCpu)->cpum.ro.GuestFeatures.enmMicroarch != kCpumMicroarch_Intel_80386
+                                     ? X86_EFL_POPF_BITS : X86_EFL_POPF_BITS_386;
+            fEflNew &=   fPopfBits & ~(X86_EFL_IOPL);
+            fEflNew |= ~(fPopfBits & ~(X86_EFL_IOPL)) & fEflOld;
         }
         /*
@@ -711,19 +713,21 @@
 
         /* Merge them with the current flags. */
+        const uint32_t fPopfBits = IEMCPU_TO_VM(pIemCpu)->cpum.ro.GuestFeatures.enmMicroarch != kCpumMicroarch_Intel_80386
+                                 ? X86_EFL_POPF_BITS : X86_EFL_POPF_BITS_386;
         if (   (fEflNew & (X86_EFL_IOPL | X86_EFL_IF)) == (fEflOld & (X86_EFL_IOPL | X86_EFL_IF))
             || pIemCpu->uCpl == 0)
         {
-            fEflNew &=  X86_EFL_POPF_BITS;
-            fEflNew |= ~X86_EFL_POPF_BITS & fEflOld;
+            fEflNew &=  fPopfBits;
+            fEflNew |= ~fPopfBits & fEflOld;
         }
         else if (pIemCpu->uCpl <= X86_EFL_GET_IOPL(fEflOld))
         {
-            fEflNew &=   X86_EFL_POPF_BITS & ~(X86_EFL_IOPL);
-            fEflNew |= ~(X86_EFL_POPF_BITS & ~(X86_EFL_IOPL)) & fEflOld;
+            fEflNew &=   fPopfBits & ~(X86_EFL_IOPL);
+            fEflNew |= ~(fPopfBits & ~(X86_EFL_IOPL)) & fEflOld;
         }
         else
         {
-            fEflNew &=   X86_EFL_POPF_BITS & ~(X86_EFL_IOPL | X86_EFL_IF);
-            fEflNew |= ~(X86_EFL_POPF_BITS & ~(X86_EFL_IOPL | X86_EFL_IF)) & fEflOld;
+            fEflNew &=   fPopfBits & ~(X86_EFL_IOPL | X86_EFL_IF);
+            fEflNew |= ~(fPopfBits & ~(X86_EFL_IOPL | X86_EFL_IF)) & fEflOld;
         }
     }
@@ -2772,4 +2776,8 @@
                    | X86_EFL_RF /*| X86_EFL_VM*/ | X86_EFL_AC /*|X86_EFL_VIF*/ /*|X86_EFL_VIP*/
                    | X86_EFL_ID;
+#if IEM_CFG_TARGET_CPU == IEMTARGETCPU_DYNAMIC
+        if (pIemCpu->uTargetCpu <= IEMTARGETCPU_386)
+            uNewFlags &= ~(X86_EFL_AC | X86_EFL_ID | X86_EFL_VIF | X86_EFL_VIP);
+#endif
         uNewFlags |= Efl.u & (X86_EFL_VM | X86_EFL_VIF | X86_EFL_VIP | X86_EFL_1);
     }
@@ -3255,4 +3263,8 @@
         else if (pIemCpu->uCpl <= pCtx->eflags.Bits.u2IOPL)
             fEFlagsMask |= X86_EFL_IF;
+#if IEM_CFG_TARGET_CPU == IEMTARGETCPU_DYNAMIC
+        if (pIemCpu->uTargetCpu <= IEMTARGETCPU_386)
+            fEFlagsMask &= ~(X86_EFL_AC | X86_EFL_ID | X86_EFL_VIF | X86_EFL_VIP);
+#endif
         uint32_t fEFlagsNew = IEMMISC_GET_EFL(pIemCpu, pCtx);
         fEFlagsNew         &= ~fEFlagsMask;
@@ -3327,4 +3339,8 @@
         else if (pIemCpu->uCpl <= NewEfl.Bits.u2IOPL)
             fEFlagsMask |= X86_EFL_IF;
+#if IEM_CFG_TARGET_CPU == IEMTARGETCPU_DYNAMIC
+        if (pIemCpu->uTargetCpu <= IEMTARGETCPU_386)
+            fEFlagsMask &= ~(X86_EFL_AC | X86_EFL_ID | X86_EFL_VIF | X86_EFL_VIP);
+#endif
         NewEfl.u           &= ~fEFlagsMask;
         NewEfl.u           |= fEFlagsMask & uNewFlags;
@@ -4790,5 +4806,11 @@
     switch (iCrReg)
     {
-        case 0: crX = pCtx->cr0; break;
+        case 0:
+            crX = pCtx->cr0;
+#if IEM_CFG_TARGET_CPU == IEMTARGETCPU_DYNAMIC
+            if (pIemCpu->uTargetCpu <= IEMTARGETCPU_386)
+                crX |= UINT32_C(0x7fffffe0); /* All reserved CR0 flags are set on a 386, just like MSW on 286. */
+#endif
+            break;
         case 2: crX = pCtx->cr2; break;
         case 3: crX = pCtx->cr3; break;
@@ -4843,5 +4865,15 @@
              */
             uint64_t const uOldCrX = pCtx->cr0;
-            uNewCrX |= X86_CR0_ET; /* hardcoded */
+
+            /* ET is hardcoded on 486 and later. */
+#if IEM_CFG_TARGET_CPU == IEMTARGETCPU_DYNAMIC
+            if (pIemCpu->uTargetCpu >= IEMTARGETCPU_486)
+#endif
+                uNewCrX |= X86_CR0_ET; /* hardcoded on 486+ */
+#if IEM_CFG_TARGET_CPU == IEMTARGETCPU_DYNAMIC
+            /* The 386 didn't #GP(0) on attempting to set reserved CR0 bits. ET was settable. */
+            else
+                uNewCrX &= X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS | X86_CR0_PG | X86_CR0_ET;
+#endif
 
             /* Check for reserved bits. */
Index: /trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h	(revision 60663)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h	(revision 60664)
@@ -977,6 +977,10 @@
                 IEM_MC_FETCH_CR0_U16(u16Tmp);
 #if IEM_CFG_TARGET_CPU == IEMTARGETCPU_DYNAMIC
-                if (pIemCpu->uTargetCpu == IEMTARGETCPU_286)
-                    IEM_MC_OR_LOCAL_U16(u16Tmp, 0xfff0); /* Reserved bits observed all set on real hw. */
+                if (pIemCpu->uTargetCpu > IEMTARGETCPU_386)
+                { /* likely */ }
+                else if (pIemCpu->uTargetCpu >= IEMTARGETCPU_386)
+                    IEM_MC_OR_LOCAL_U16(u16Tmp, 0xffe0);
+                else
+                    IEM_MC_OR_LOCAL_U16(u16Tmp, 0xfff0);
 #endif
                 IEM_MC_STORE_GREG_U16((bRm & X86_MODRM_RM_MASK) | pIemCpu->uRexB, u16Tmp);
@@ -1015,6 +1019,10 @@
         IEM_MC_FETCH_CR0_U16(u16Tmp);
 #if IEM_CFG_TARGET_CPU == IEMTARGETCPU_DYNAMIC
-        if (pIemCpu->uTargetCpu == IEMTARGETCPU_286)
-            IEM_MC_OR_LOCAL_U16(u16Tmp, 0xfff0); /* Reserved bits observed all set on real hw. */
+        if (pIemCpu->uTargetCpu > IEMTARGETCPU_386)
+        { /* likely */ }
+        else if (pIemCpu->uTargetCpu >= IEMTARGETCPU_386)
+            IEM_MC_OR_LOCAL_U16(u16Tmp, 0xffe0);
+        else
+            IEM_MC_OR_LOCAL_U16(u16Tmp, 0xfff0);
 #endif
         IEM_MC_STORE_MEM_U16(pIemCpu->iEffSeg, GCPtrEffDst, u16Tmp);
Index: /trunk/src/VBox/VMM/VMMR3/CPUMR3Db.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CPUMR3Db.cpp	(revision 60663)
+++ /trunk/src/VBox/VMM/VMMR3/CPUMR3Db.cpp	(revision 60664)
@@ -193,4 +193,5 @@
 #include "cpus/Intel_Pentium_4_3_00GHz.h"
 #include "cpus/Intel_Atom_330_1_60GHz.h"
+#include "cpus/Intel_80386.h"
 #include "cpus/Intel_80286.h"
 #include "cpus/Intel_80186.h"
Index: /trunk/src/VBox/VMM/VMMR3/cpus/Intel_80386.h
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/cpus/Intel_80386.h	(revision 60664)
+++ /trunk/src/VBox/VMM/VMMR3/cpus/Intel_80386.h	(revision 60664)
@@ -0,0 +1,71 @@
+/* $Id$ */
+/** @file
+ * CPU database entry "Intel 80386".
+ * Handcrafted.
+ */
+
+/*
+ * Copyright (C) 2013-2016 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef VBOX_CPUDB_Intel_80386
+#define VBOX_CPUDB_Intel_80386
+
+#ifndef CPUM_DB_STANDALONE
+/**
+ * Fake CPUID leaves for Intel(R) 80386.
+ *
+ * We fake these to keep the CPUM ignorant of CPUs wihtout CPUID leaves
+ * and avoid having to seed CPUM::GuestFeatures filling with bits from the
+ * CPUMDBENTRY.
+ */
+static CPUMCPUIDLEAF const g_aCpuIdLeaves_Intel_80386[] =
+{
+    { 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x756e6547, 0x6c65746e, 0x49656e69, 0 },
+    { 0x00000001, 0x00000000, 0x00000000, 0x00000300, 0x00000100, 0x00000000, 0x00000000, 0 },
+    { 0x80000000, 0x00000000, 0x00000000, 0x80000008, 0x00000000, 0x00000000, 0x00000000, 0 },
+    { 0x80000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
+    { 0x80000002, 0x00000000, 0x00000000, 0x65746e49, 0x2952286c, 0x33303820, 0x20203638, 0 },
+    { 0x80000003, 0x00000000, 0x00000000, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0 },
+    { 0x80000004, 0x00000000, 0x00000000, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0 },
+    { 0x80000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
+    { 0x80000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
+    { 0x80000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0 },
+    { 0x80000008, 0x00000000, 0x00000000, 0x00001818, 0x00000000, 0x00000000, 0x00000000, 0 },
+};
+#endif /* !CPUM_DB_STANDALONE */
+
+/**
+ * Database entry for Intel(R) 80386.
+ */
+static CPUMDBENTRY const g_Entry_Intel_80386 =
+{
+    /*.pszName          = */ "Intel 80386",
+    /*.pszFullName      = */ "Intel(R) 80386",
+    /*.enmVendor        = */ CPUMCPUVENDOR_INTEL,
+    /*.uFamily          = */ 3,
+    /*.uModel           = */ 0,
+    /*.uStepping        = */ 0,
+    /*.enmMicroarch     = */ kCpumMicroarch_Intel_80386,
+    /*.uScalableBusFreq = */ CPUM_SBUSFREQ_UNKNOWN,
+    /*.fFlags           = */ CPUDB_F_EXECUTE_ALL_IN_IEM,
+    /*.cMaxPhysAddrWidth= */ 24,
+    /*.paCpuIdLeaves    = */ NULL_ALONE(g_aCpuIdLeaves_Intel_80386),
+    /*.cCpuIdLeaves     = */ ZERO_ALONE(RT_ELEMENTS(g_aCpuIdLeaves_Intel_80386)),
+    /*.enmUnknownCpuId  = */ CPUMUNKNOWNCPUID_DEFAULTS,
+    /*.DefUnknownCpuId  = */ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    /*.fMsrMask         = */ 0,
+    /*.cMsrRanges       = */ 0,
+    /*.paMsrRanges      = */ NULL,
+};
+
+#endif /* !VBOX_CPUDB_Intel_80386 */
+
