Commit in reactos/ntoskrnl on MAIN
include/internal/i386/ke.h+14-11.10 -> 1.11
mm/i386/page.c+84-381.73 -> 1.74
ke/i386/kernel.c+123-471.32 -> 1.33
+221-86
3 modified files
- Detect more cpu features.
- Implemented the noexecute protection for the AMD64 cpu.

reactos/ntoskrnl/include/internal/i386
ke.h 1.10 -> 1.11
diff -u -r1.10 -r1.11
--- ke.h	9 Sep 2004 20:42:32 -0000	1.10
+++ ke.h	26 Sep 2004 16:32:17 -0000	1.11
@@ -161,7 +161,20 @@
                                      __asm__("movl %%cr4,%0\n\t" :"=r" (__d)); \
                                      __d; \
                                  })
-#define Ke386SetCr4(X)           __asm__("movl %0,%%cr4": :"r" (X));
+#define Ke386SetCr4(X)           __asm__ __volatile__("movl %0,%%cr4": :"r" (X));
+
+static inline void Ki386Cpuid(ULONG Op, PULONG Eax, PULONG Ebx, PULONG Ecx, PULONG Edx)
+{
+    __asm__("cpuid"
+	    : "=a" (*Eax), "=b" (*Ebx), "=c" (*Ecx), "=d" (*Edx)
+	    : "0" (Op));
+}
+
+#define Ke386Rdmsr(msr,val1,val2) __asm__ __volatile__("rdmsr" : "=a" (val1), "=d" (val2) : "c" (msr))
+
+#define Ke386Wrmsr(msr,val1,val2) __asm__ __volatile__("wrmsr" : /* no outputs */ : "c" (msr), "a" (val1), "d" (val2))
+
+
 #elif defined(_MSC_VER)
 #define Ke386DisableInterrupts() __asm cli
 #define Ke386EnableInterrupts()  __asm sti

reactos/ntoskrnl/mm/i386
page.c 1.73 -> 1.74
diff -u -r1.73 -r1.74
--- page.c	9 Sep 2004 20:42:33 -0000	1.73
+++ page.c	26 Sep 2004 16:32:17 -0000	1.74
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: page.c,v 1.73 2004/09/09 20:42:33 hbirr Exp $
+/* $Id: page.c,v 1.74 2004/09/26 16:32:17 hbirr Exp $
  *
  * PROJECT:     ReactOS kernel
  * FILE:        ntoskrnl/mm/i386/page.c
@@ -78,7 +78,9 @@
 #endif
 
 extern ULONG Ke386CpuidFlags;
-static BOOLEAN PAE = FALSE;
+extern ULONG Ke386Cpuid;
+extern BOOLEAN Ke386Pae;
+extern BOOLEAN Ke386NoExecute;
 
 /* FUNCTIONS ***************************************************************/
 
@@ -112,7 +114,16 @@
       DPRINT1("Unknown main protection type.\n");
       KEBUGCHECK(0);
    }
-   if (!(flProtect & PAGE_SYSTEM))
+   if (Ke386NoExecute && 
+       !(flProtect & (PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE)))
+   {
+      Attributes = Attributes | 0x80000000;
+   }
+
+   if (flProtect & PAGE_SYSTEM)
+   {
+   }
+   else
    {
       Attributes = Attributes | PA_USER;
    }
@@ -172,7 +183,7 @@
       ExFreePool((PVOID) LdtBase);
    }
 
-   if (PAE)
+   if (Ke386Pae)
    {
       PULONGLONG PageDirTable;
       PULONGLONG PageDir;
@@ -276,7 +287,7 @@
 
    DPRINT("MmCopyMmInfo(Src %x, Dest %x)\n", Src, Dest);
 
-   if (PAE)
+   if (Ke386Pae)
    {
       PULONGLONG PageDirTable;
       PULONGLONG PageDir;
@@ -359,7 +370,7 @@
       KeAttachProcess(Process);
    }
 
-   if (PAE)
+   if (Ke386Pae)
    {
       ULONGLONG ZeroPde = 0LL;
       ExfpInterlockedExchange64(PAE_ADDR_TO_PDE(Address), &ZeroPde);
@@ -391,7 +402,7 @@
    {
       KeAttachProcess(Process);
    }
-   if (PAE)
+   if (Ke386Pae)
    {
       PULONGLONG PageTable;
       ULONGLONG ZeroPte = 0LL;
@@ -653,7 +664,7 @@
 
 BOOLEAN MmUnmapPageTable(PULONG Pt)
 {
-   if (PAE)
+   if (Ke386Pae)
    {
       if ((PULONGLONG)Pt >= (PULONGLONG)PAGETABLE_MAP && (PULONGLONG)Pt < (PULONGLONG)PAGETABLE_MAP + 4*512*512)
       {
@@ -709,7 +720,7 @@
                    PVOID Address)
 {
 
-   if (PAE)
+   if (Ke386Pae)
    {
       ULONGLONG Entry;
       Entry = MmGetPageEntryForProcessForPAE(Process, Address);
@@ -738,7 +749,7 @@
  */
 {
    BOOLEAN WasValid;
-   if (PAE)
+   if (Ke386Pae)
    {
       ULONGLONG Pte;
       ULONGLONG tmpPte;
@@ -825,7 +836,7 @@
 VOID
 MmRawDeleteVirtualMapping(PVOID Address)
 {
-   if (PAE)
+   if (Ke386Pae)
    {
       PULONGLONG Pt;
       ULONGLONG ZeroPte = 0LL;
@@ -867,7 +878,7 @@
 
    DPRINT("MmDeleteVirtualMapping(%x, %x, %d, %x, %x)\n",
           Process, Address, FreePage, WasDirty, Page);
-   if (PAE)
+   if (Ke386Pae)
    {
       ULONGLONG Pte;
       PULONGLONG Pt;
@@ -994,7 +1005,7 @@
       ULONG Idx;
       
       Ptrc = Process->AddressSpace.PageTableRefCountTable;
-      Idx = PAE ? PAE_ADDR_TO_PAGE_TABLE(Address) : ADDR_TO_PAGE_TABLE(Address);
+      Idx = Ke386Pae ? PAE_ADDR_TO_PAGE_TABLE(Address) : ADDR_TO_PAGE_TABLE(Address);
 
       Ptrc[Idx]--;
       if (Ptrc[Idx] == 0)
@@ -1011,7 +1022,7 @@
  * FUNCTION: Delete a virtual mapping 
  */
 {
-   if (PAE)
+   if (Ke386Pae)
    {
       ULONGLONG Pte;
       PULONGLONG Pt;
@@ -1110,7 +1121,7 @@
 BOOLEAN
 Mmi386MakeKernelPageTableGlobal(PVOID PAddress)
 {
-   if (PAE)
+   if (Ke386Pae)
    {
       PULONGLONG Pt;
       PULONGLONG Pde;
@@ -1150,7 +1161,7 @@
 
 BOOLEAN MmIsDirtyPage(PEPROCESS Process, PVOID Address)
 {
-   if (PAE)
+   if (Ke386Pae)
    {
       return MmGetPageEntryForProcessForPAE(Process, Address) & PA_DIRTY ? TRUE : FALSE;
    }
@@ -1168,7 +1179,7 @@
       DPRINT1("MmIsAccessedAndResetAccessPage is called for user space without a process.\n");
       KEBUGCHECK(0);
    }
-   if (PAE)
+   if (Ke386Pae)
    {
       PULONGLONG Pt;
       ULONGLONG Pte;
@@ -1239,7 +1250,7 @@
       DPRINT1("MmSetCleanPage is called for user space without a process.\n");
       KEBUGCHECK(0);
    }
-   if (PAE)
+   if (Ke386Pae)
    {
       PULONGLONG Pt;
       ULONGLONG Pte;
@@ -1308,7 +1319,7 @@
       DPRINT1("MmSetDirtyPage is called for user space without a process.\n");
       KEBUGCHECK(0);
    }
-   if (PAE)
+   if (Ke386Pae)
    {
       PULONGLONG Pt;
       ULONGLONG Pte;
@@ -1368,7 +1379,7 @@
 
 VOID MmEnableVirtualMapping(PEPROCESS Process, PVOID Address)
 {
-   if (PAE)
+   if (Ke386Pae)
    {
       PULONGLONG Pt;
       ULONGLONG Pte;
@@ -1428,7 +1439,7 @@
 
 BOOLEAN MmIsPagePresent(PEPROCESS Process, PVOID Address)
 {
-   if (PAE)
+   if (Ke386Pae)
    {
       return MmGetPageEntryForProcessForPAE(Process, Address) & PA_PRESENT ? TRUE : FALSE;
    }
@@ -1440,7 +1451,7 @@
 
 BOOLEAN MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
 {
-   if (PAE)
+   if (Ke386Pae)
    {
       ULONGLONG Entry;
       Entry = MmGetPageEntryForProcessForPAE(Process, Address);
@@ -1464,6 +1475,7 @@
    ULONG i;
    PVOID Addr;
    ULONG PdeOffset, oldPdeOffset;
+   BOOLEAN NoExecute = FALSE;
 
    DPRINT("MmCreateVirtualMappingForKernel(%x, %x, %x, %d)\n",
            Address, flProtect, Pages, PageCount);
@@ -1475,6 +1487,11 @@
    }
 
    Attributes = ProtectToPTE(flProtect);
+   if (Attributes & 0x80000000)
+   {
+      NoExecute = TRUE;
+   }
+   Attributes &= 0xfff;
    if (Ke386CpuidFlags & X86_FEATURE_PGE)
    {
       Attributes |= PA_GLOBAL;
@@ -1482,7 +1499,7 @@
 
    Addr = Address;
 
-   if (PAE)
+   if (Ke386Pae)
    {
       PULONGLONG Pt = NULL;
       ULONGLONG Pte;
@@ -1514,6 +1531,10 @@
          oldPdeOffset = PdeOffset;
 
 	 Pte = PFN_TO_PTE(Pages[i]) | Attributes;
+	 if (NoExecute)
+	 {
+	    Pte |= 0x8000000000000000LL;
+	 }
          Pte = ExfpInterlockedExchange64(Pt, &Pte);
          if (Pte != 0LL)
          {
@@ -1591,7 +1612,7 @@
       KEBUGCHECK(0);
    }
 
-   if (PAE)
+   if (Ke386Pae)
    {
       PULONGLONG Pt;
       ULONGLONG Pte;
@@ -1657,7 +1678,7 @@
      ULONG Idx;
 
      Ptrc = Process->AddressSpace.PageTableRefCountTable;
-     Idx = PAE ? PAE_ADDR_TO_PAGE_TABLE(Address) : ADDR_TO_PAGE_TABLE(Address);
+     Idx = Ke386Pae ? PAE_ADDR_TO_PAGE_TABLE(Address) : ADDR_TO_PAGE_TABLE(Address);
      Ptrc[Idx]++;
    }
    return(STATUS_SUCCESS);
@@ -1675,9 +1696,10 @@
    PVOID Addr;
    ULONG i;
    ULONG oldPdeOffset, PdeOffset;
+   BOOLEAN NoExecute = FALSE;
 
-   DPRINT("MmCreateVirtualMappingUnsafe(%x, %x, %x, %x, %d)\n",
-          Process, Address, flProtect, Pages, PageCount);
+   DPRINT("MmCreateVirtualMappingUnsafe(%x, %x, %x, %x (%x), %d)\n",
+          Process, Address, flProtect, Pages, *Pages, PageCount);
    
    if (Process == NULL)
    {
@@ -1709,6 +1731,11 @@
    }
 
    Attributes = ProtectToPTE(flProtect);
+   if (Attributes & 0x80000000)
+   {
+      NoExecute = TRUE;
+   }
+   Attributes &= 0xfff;
    if (Address >= (PVOID)KERNEL_BASE)
    {
       Attributes &= ~PA_USER;
@@ -1724,7 +1751,7 @@
 
    Addr = Address;
 
-   if (PAE)
+   if (Ke386Pae)
    {
       ULONGLONG Pte, tmpPte;
       PULONGLONG Pt = NULL;
@@ -1757,6 +1784,10 @@
 
          MmMarkPageMapped(Pages[i]);
 	 tmpPte = PAE_PFN_TO_PTE(Pages[i]) | Attributes;
+	 if (NoExecute)
+	 {
+	    tmpPte |= 0x8000000000000000LL;
+	 }
          Pte = ExfpInterlockedExchange64(Pt, &tmpPte);
          if (PAE_PAGE_MASK((Pte)) != 0LL && !((Pte) & PA_PRESENT))
          {
@@ -1888,7 +1919,7 @@
 {
    ULONG Entry;
    ULONG Protect;
-   if (PAE)
+   if (Ke386Pae)
    {
       Entry = MmGetPageEntryForProcessForPAE(Process, Address);
    }
@@ -1932,11 +1963,17 @@
 MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
 {
    ULONG Attributes = 0;
+   BOOLEAN NoExecute = FALSE;
 
    DPRINT("MmSetPageProtect(Process %x  Address %x  flProtect %x)\n",
           Process, Address, flProtect);
 
    Attributes = ProtectToPTE(flProtect);
+   if (Attributes & 0x80000000)
+   {
+      NoExecute = TRUE;
+   }
+   Attributes &= 0xfff;
    if (Address >= (PVOID)KERNEL_BASE)
    {
       Attributes &= ~PA_USER;
@@ -1949,7 +1986,7 @@
    {
       Attributes |= PA_USER;
    }
-   if (PAE)
+   if (Ke386Pae)
    {
       PULONGLONG Pt;
       ULONGLONG tmpPte, Pte;
@@ -1957,12 +1994,21 @@
       Pt = MmGetPageTableForProcessForPAE(Process, Address, FALSE);
       if (Pt == NULL)
       {
+         DPRINT1("Address %x\n", Address);
          KEBUGCHECK(0);
       }
       do
       {
         Pte = *Pt;
 	tmpPte = PAE_PAGE_MASK(Pte) | Attributes | (Pte & (PA_ACCESSED|PA_DIRTY));
+	if (NoExecute)
+	{
+	   tmpPte |= 0x8000000000000000LL;
+	}
+	else
+	{
+	   tmpPte &= ~0x8000000000000000LL;
+	}
       } while (Pte != ExfInterlockedCompareExchange64(Pt, &tmpPte, &Pte));
 
       if (MmUnmapPageTable((PULONG)Pt) || Address > (PVOID)KERNEL_BASE)
@@ -1999,7 +2045,7 @@
    PHYSICAL_ADDRESS p;
 
    DPRINT("MmGetPhysicalAddress(vaddr %x)\n", vaddr);
-   if (PAE)
+   if (Ke386Pae)
    {
       ULONGLONG Pte;
       Pte = MmGetPageEntryForProcessForPAE(NULL, vaddr);
@@ -2038,7 +2084,7 @@
    {
       KEBUGCHECK(0);
    }
-   if (PAE)
+   if (Ke386Pae)
    {
       PULONGLONG PageDirTable;
       PULONGLONG Pde;
@@ -2098,7 +2144,7 @@
 MmInitGlobalKernelPageDirectory(VOID)
 {
    ULONG i;
-   if (PAE)
+   if (Ke386Pae)
    {
       PULONGLONG CurrentPageDirectory = (PULONGLONG)PAE_PAGEDIRECTORY_MAP + 3*512;
       for (i = 0; i < 512; i++)
@@ -2198,7 +2244,7 @@
    else
    {
       /* this is an application processor in a mp system */
-      if (PAE == FALSE)
+      if (!Ke386Pae)
       {
          return;
       }
@@ -2212,7 +2258,7 @@
    Ke386SetCr4(Ke386GetCr4() | X86_CR4_PAE);
    if (LastKernelAddress)
    {
-      PAE = TRUE;
+      Ke386Pae = TRUE;
    }
    Ke386RestoreFlags(Flags);
 }
@@ -2220,7 +2266,7 @@
 ULONG
 MiGetUserPageDirectoryCount(VOID)
 {
-   return PAE ? 1536 : 768;
+   return Ke386Pae ? 1536 : 768;
 }
 
 VOID INIT_FUNCTION
@@ -2231,12 +2277,12 @@
    PVOID BaseAddress;
 
    BoundaryAddressMultiple.QuadPart = 0;
-   BaseAddress = (PVOID)0xf0000000;
+   BaseAddress = (PVOID)PAGETABLE_MAP;
    MmCreateMemoryArea(NULL,
                       MmGetKernelAddressSpace(),
                       MEMORY_AREA_SYSTEM,
                       &BaseAddress,
-		      PAE ? 0x800000 : 0x400000,
+		      Ke386Pae ? 0x800000 : 0x400000,
                       0,
                       &kernel_map_desc,
                       TRUE,

reactos/ntoskrnl/ke/i386
kernel.c 1.32 -> 1.33
diff -u -r1.32 -r1.33
--- kernel.c	9 Sep 2004 20:42:33 -0000	1.32
+++ kernel.c	26 Sep 2004 16:32:18 -0000	1.33
@@ -38,61 +38,90 @@
 static PFN_TYPE PcrPages[MAXIMUM_PROCESSORS];
 ULONG Ke386CpuidFlags, Ke386CpuidFlags2, Ke386CpuidExFlags;
 ULONG Ke386Cpuid = 0x300;
+ULONG Ke386CacheAlignment;
+CHAR Ke386CpuidVendor[13] = {0,};
+CHAR Ke386CpuidModel[49] = {0,};
+ULONG Ke386L1CacheSize;
+ULONG Ke386L2CacheSize;
+BOOLEAN Ke386NoExecute = FALSE;
+BOOLEAN Ke386Pae = FALSE;
 
 /* FUNCTIONS *****************************************************************/
 
 VOID INIT_FUNCTION STATIC
 Ki386GetCpuId(VOID)
 {
-  ULONG OrigFlags, Flags, FinalFlags;
-  ULONG MaxCpuidLevel;
-
-  Ke386CpuidFlags = Ke386CpuidFlags2 =  Ke386CpuidExFlags = 0;
-
-  /* Try to toggle the id bit in eflags. */
-  __asm__ ("pushfl\n\t"
-	   "popl %0\n\t"
-	   : "=r" (OrigFlags));
-  Flags = OrigFlags ^ X86_EFLAGS_ID;
-  __asm__ ("pushl %1\n\t"
-	   "popfl\n\t"
-	   "pushfl\n\t"
-	   "popl %0\n\t"
-	   : "=r" (FinalFlags)
-	   : "r" (Flags));
+   ULONG OrigFlags, Flags, FinalFlags;
+   ULONG MaxCpuidLevel;
+   ULONG Dummy, Ebx, Ecx, Edx;
+
+   Ke386CpuidFlags = Ke386CpuidFlags2 =  Ke386CpuidExFlags = 0;
+   Ke386CacheAlignment = 32;
+
+   /* Try to toggle the id bit in eflags. */
+   __asm__ ("pushfl\n\t"
+	    "popl %0\n\t"
+	    : "=r" (OrigFlags));
+   Flags = OrigFlags ^ X86_EFLAGS_ID;
+   __asm__ ("pushl %1\n\t"
+	    "popfl\n\t"
+	    "pushfl\n\t"
+	    "popl %0\n\t"
+	    : "=r" (FinalFlags)
+	    : "r" (Flags));
    if ((OrigFlags & X86_EFLAGS_ID) == (FinalFlags & X86_EFLAGS_ID))
-    {
+   {
       /* No cpuid supported. */
       return;
-    }
-  
-  /* Get maximum cpuid level supported. */
-  __asm__("cpuid\n\t"
-	  : "=a" (MaxCpuidLevel)
-	  : "a" (0x00000000)
-	  : "ebx", "ecx", "edx");       
-  if (MaxCpuidLevel > 0)
-    {
+   }
+
+   /* Get the vendor name and the maximum cpuid level supported. */
+   Ki386Cpuid(0, &MaxCpuidLevel, (PULONG)&Ke386CpuidVendor[0], (PULONG)&Ke386CpuidVendor[8], (PULONG)&Ke386CpuidVendor[4]);
+   if (MaxCpuidLevel > 0)
+   { 
       /* Get the feature flags. */
-      __asm__("cpuid\n\t"
-	  : "=a" (Ke386Cpuid),"=d" (Ke386CpuidFlags), "=c" (Ke386CpuidFlags2)
-	  : "a" (0x00000001)
-	  : "ebx");       
-    }
-
-  /* Get the maximum extended cpuid level supported. */
-  __asm__("cpuid\n\t"
-	  : "=a" (MaxCpuidLevel)
-	  : "a" (0x80000000)
-	  : "ebx", "ecx", "edx");       
-  if (MaxCpuidLevel > 0)
-    {
+      Ki386Cpuid(1, &Ke386Cpuid, &Ebx, &Ke386CpuidFlags2, &Ke386CpuidFlags);
+      /* Get the cache alignment, if it is available */
+      if (Ke386CpuidFlags & (1<<19))
+      {
+         Ke386CacheAlignment = ((Ebx >> 8) & 0xff) * 8;
+      }
+   }
+
+   /* Get the maximum extended cpuid level supported. */
+   Ki386Cpuid(0x80000000, &MaxCpuidLevel, &Dummy, &Dummy, &Dummy);
+   if (MaxCpuidLevel > 0)
+   {
       /* Get the extended feature flags. */
-      __asm__("cpuid\n\t"
-	  : "=d" (Ke386CpuidExFlags)
-	  : "a" (0x80000001)
-	  : "ebx", "ecx");       
-    }
+      Ki386Cpuid(0x80000001, &Dummy, &Dummy, &Dummy, &Ke386CpuidExFlags);
+   }
+
+   /* Get the model name. */
+   if (MaxCpuidLevel >= 0x80000004)
+   {
+      PULONG v = (PULONG)&Ke386CpuidModel;
+      Ki386Cpuid(0x80000002, v, v + 1, v + 2, v + 3);
+      Ki386Cpuid(0x80000003, v + 4, v + 5, v + 6, v + 7);
+      Ki386Cpuid(0x80000004, v + 8, v + 9, v + 10, v + 11);
+   }
+
+   /* Get the L1 cache size */
+   if (MaxCpuidLevel >= 0x80000005)
+   {
+      Ki386Cpuid(0x80000005, &Dummy, &Dummy, &Ecx, &Edx);
+      Ke386L1CacheSize = (Ecx >> 24)+(Edx >> 24);
+      if ((Ecx & 0xff) > 0)
+      {
+         Ke386CacheAlignment = Ecx & 0xff;
+      }
+   }
+
+   /* Get the L2 cache size */
+   if (MaxCpuidLevel >= 0x80000006)
+   {
+      Ki386Cpuid(0x80000006, &Dummy, &Dummy, &Ecx, &Dummy);
+      Ke386L2CacheSize = Ecx >> 16;
+   }
 }
 
 VOID INIT_FUNCTION
@@ -236,9 +265,34 @@
       p1 = p2;
    }
 
+   /* 
+    * FIXME:
+    *   Make the detection of the noexecute feature more portable.
+    */
+   if(((Ke386Cpuid >> 8) & 0xf) == 0xf &&
+      0 == strcmp("AuthenticAMD", Ke386CpuidVendor))
+   {
+      if (NoExecute)
+      {
+         ULONG Flags, l, h;
+         Ke386SaveFlags(Flags);
+         Ke386DisableInterrupts();
+
+	 Ke386Rdmsr(0xc0000080, l, h);
+	 l |= (1 << 11);
+	 Ke386Wrmsr(0xc0000080, l, h);
+	 Ke386NoExecute = TRUE;
+         Ke386RestoreFlags(Flags);
+      }
+   }  
+   else
+   {
+      NoExecute=FALSE;
+   }
+
+      
    /* Enable PAE mode */
-   if ((Pae && (Ke386CpuidFlags & X86_FEATURE_PAE)) ||
-       (NoExecute && (Ke386CpuidFlags & X86_FEATURE_PAE) /* && (check for the non execution capabilities of the processor) */))
+   if ((Pae && (Ke386CpuidFlags & X86_FEATURE_PAE)) || NoExecute)
    {
       MiEnablePAE((PVOID*)LastKernelAddress);
    }
@@ -255,13 +309,35 @@
    if (Ke386CpuidFlags & X86_FEATURE_PAE)
    {
       DPRINT1("CPU supports PAE mode\n");
-      if (Ke386GetCr4() & X86_CR4_PAE)
+      if (Ke386Pae)
       {
          DPRINT1("CPU runs in PAE mode\n");
+         if (Ke386NoExecute)
+         {
+            DPRINT1("NoExecute is enabled\n");
+	 }
       }
       else
       {
          DPRINT1("CPU doesn't run in PAE mode\n");
       }
    }
+   if (Ke386CpuidVendor[0])
+   {
+      DPRINT1("CPU Vendor: %s\n", Ke386CpuidVendor);
+   }
+   if (Ke386CpuidModel[0])
+   {
+      DPRINT1("CPU Model:  %s\n", Ke386CpuidModel);
+   }
+
+   DPRINT1("Ke386CacheAlignment: %d\n", Ke386CacheAlignment);
+   if (Ke386L1CacheSize)
+   {
+      DPRINT1("Ke386L1CacheSize: %dkB\n", Ke386L1CacheSize);
+   }
+   if (Ke386L2CacheSize)
+   {
+      DPRINT1("Ke386L2CacheSize: %dkB\n", Ke386L2CacheSize);
+   }
 }
CVSspam 0.2.8