/***************************************************************************************\

Module Name:    MtxCpu0.H

Description:    x86 structures and constants.

References:     Pentium III Programmer's manual.

    Copyright (c) 2000, Matrox Graphics Inc.
    All Rights Reserved.

\***************************************************************************************/

#ifndef INC_MTXCPU0_H
#define INC_MTXCPU0_H

// --------------------------------------------------------------------------------------
//                      H E A D E R   F I L E S   R E Q U I R E D
// --------------------------------------------------------------------------------------

#include "MtxType.h"

// --------------------------------------------------------------------------------------
//                           T Y P E   D E F I N I T I O N S
// --------------------------------------------------------------------------------------

//
// Exported structures:
//      ST_EFLAGS
//          Structure for EFLAGS register
//
//      ST_CR0
//          Structure for CR0 register
//
//      ST_CR3
//          Structure for CR3 register
//
//      ST_CR4
//          Structure for CR4 register
//
//      ST_SELECTOR
//          GDT/LDT descriptor handle
//
//      ST_DTE
//          GDT/LDT descriptor
//
//      ST_PDE
//          Page directory entry
//
//      ST_PDE_4M
//          4M page directory entry
//
//      ST_PTE
//          4K page table entry
//
//      CPUID_REGS
//          CPUID output registers
//
//      CPUID_FUNCTION_0
//          CPUID output for eax == 0
//
//      CPUID_FUNCTION_1
//          CPUID output for eax == 1
//


//
// Structure: ST_EFLAGS_REG
//
// Description:
//      Fields for the EFLAGS register
//
// Fields:
//  TF <8> Trap
//      Set to enable single-step mode for debugging; clear to disable 
//      single-step mode.  In single-step mode, the processor generates a 
//      debug exception after each instruction, which allows the execution 
//      state of a program to be inspected after each instruction. If an 
//      application program sets the TF flag using a POPF, POPFD, or IRET
//      instruction, a debug exception is generated after the instruction 
//      that follows the POPF, POPFD, or IRET instruction.
//
//  IF <9> Interrupt enable
//      Controls the response of the processor to maskable hardware
//      interrupt requests.  Set to respond to maskable hardware interrupts; 
//      cleared to inhibit maskable hardware interrupts.  The IF flag does 
//      not affect the generation of exceptions or nonmaskable interrupts 
//      (NMI interrupts). The CPL, IOPL, and the state of the VME flag in 
//      control register CR4 determine whether the IF flag can be modified 
//      by the CLI, STI, POPF, POPFD, and IRET instructions.
//
//  IOPL <13:12> I/O privilege level field
//      Indicates the I/O privilege level (IOPL) of the currently running 
//      program or task. The CPL of the currently running program or task 
//      must be less than or equal to the IOPL to access the I/O address 
//      space. This field can only be modified by the POPF and IRET 
//      instructions when operating at a CPL of 0. The IOPL is also one of 
//      the mechanisms that controls the modification of the IF flag and 
//      the handling of interrupts in virtual-8086 mode when the virtual 
//      mode extensions are in effect (the VME flag in control register CR4 
//      is set).
//
//  NT <14> Nested task
//      Controls the chaining of interrupted and called tasks. The processor 
//      sets this flag on calls to a task initiated with a CALL instruction, 
//      an interrupt, or an exception. It examines and modifies this flag on 
//      returns from a task initiated with the IRET instruction. The flag 
//      can be explicitly set or cleared with the POPF/POPFD instructions; 
//      however, changing to the state of this flag can generate unexpected 
//      excep-tions in application programs.
//
//  RF <16> Resume
//      Controls the processor’s response to instruction-breakpoint condi-
//      tions.  When set, this flag temporarily disables debug exceptions 
//      (#DE) from being generated for instruction breakpoints; although, 
//      other exception conditions can cause an exception to be generated. 
//      When clear, instruction breakpoints will generate debug exceptions.
//      The primary function of the RF flag is to allow the restarting of an 
//      instruction following a debug exception that was caused by an 
//      instruction breakpoint condition. Here, debugger software must set 
//      this flag in the EFLAGS image on the stack just prior to returning 
//      to the interrupted program with the IRETD instruction, to prevent 
//      the instruction breakpoint from causing another debug exception. 
//      The processor then automatically clears this flag after the 
//      instruction returned to has been successfully executed, enabling 
//      instruction breakpoint faults again.
//
//  VM <17> Virtual-8086 mode
//      Set to enable virtual-8086 mode; clear to return to protected mode. 
//
//  AC <18> Alignment check
//      Set this flag and the AM flag in the CR0 register to enable alignment 
//      checking of memory references; clear the AC flag and/or the AM flag 
//      to disable alignment checking.  An alignment-check exception is 
//      generated when reference is made to an unaligned operand, such as a 
//      word at an odd byte address or a doubleword at an address which is 
//      not an integral multiple of four.  Alignment-check exceptions are 
//      generated only in user mode (privilege level 3).  Memory references 
//      that default to privilege level 0, such as segment descriptor loads, 
//      do not generate this exception even when caused by instructions 
//      executed in user-mode.  The alignment-check exception can be used to 
//      check alignment of data. This is useful when exchanging data with 
//      other processors, which require all data to be aligned. The alignment-
//      check exception can also be used by interpreters to flag some 
//      pointers as special by misaligning the pointer. This eliminates 
//      overhead of checking each pointer and only handles the special 
//      pointer when used.
//
//  VIF <19> Virtual Interrupt
//      Contains a virtual image of the IF flag. This flag is used in
//      conjunction with the VIP flag. The processor only recognizes the 
//      VIF flag when either the VME flag or the PVI flag in control 
//      register CR4 is set and the IOPL is less than 3.  (The VME flag 
//      enables the virtual-8086 mode extensions; the PVI flag enables the
//      protected-mode virtual interrupts.) 
//
//  VIP <20> Virtual interrupt pending 
//      Set by software to indicate that an interrupt is pending; cleared 
//      to indicate that no interrupt is pending. This flag is used in 
//      conjunction with the VIF flag.  The processor reads this flag but 
//      never modifies it.  The processor only recognizes the VIP flag when 
//      either the VME flag or the PVI flag in control register CR4 is set 
//      and the IOPL is less than 3. (The VME flag enables the virtual-8086 
//      mode extensions; the PVI flag enables the protected-mode virtual 
//      interrupts.)
//
//  ID <21> Identification
//      The ability of a program or procedure to set or clear this flag
//      indicates support for the CPUID instruction.
//
typedef union
{
    DWORD all;

    struct
    {
        DWORD CF            :1;  // <0>
        DWORD Rsvd1         :1;  // <1>
        DWORD PF            :1;  // <2>
        DWORD Rsvd2         :1;  // <3>
        DWORD AF            :1;  // <4>
        DWORD Rsvd3         :1;  // <5>
        DWORD ZF            :1;  // <6>
        DWORD SF            :1;  // <7>
        DWORD TF            :1;  // <8>
        DWORD IF            :1;  // <9>
        DWORD DF            :1;  // <10>
        DWORD OF            :1;  // <11>
        DWORD IOPL          :2;  // <13:12>
        DWORD NT            :1;  // <14>
        DWORD Rsvd4         :1;  // <15>
        DWORD RF            :1;  // <16>
        DWORD VM            :1;  // <17>
        DWORD AC            :1;  // <18>
        DWORD VIF           :1;  // <19>
        DWORD VIP           :1;  // <20>
        DWORD ID            :1;  // <21>
        DWORD Rsvd5         :10; // <31:22>
    };

} ST_EFLAGS;

#define EFLAGS_CF_SHIFT         0L
#define EFLAGS_CF_MASK          (1L << EFLAGS_CF_SHIFT)
#define EFLAGS_CF_0             (0L << EFLAGS_CF_SHIFT)
#define EFLAGS_CF_1             (1L << EFLAGS_CF_SHIFT)
#define EFLAGS_PF_SHIFT         2L
#define EFLAGS_PF_MASK          (1L << EFLAGS_PF_SHIFT)
#define EFLAGS_PF_0             (0L << EFLAGS_PF_SHIFT)
#define EFLAGS_PF_1             (1L << EFLAGS_PF_SHIFT)
#define EFLAGS_AF_SHIFT         4L
#define EFLAGS_AF_MASK          (1L << EFLAGS_AF_SHIFT)
#define EFLAGS_AF_0             (0L << EFLAGS_AF_SHIFT)
#define EFLAGS_AF_1             (1L << EFLAGS_AF_SHIFT)
#define EFLAGS_ZF_SHIFT         6L
#define EFLAGS_ZF_MASK          (1L << EFLAGS_ZF_SHIFT)
#define EFLAGS_ZF_0             (0L << EFLAGS_ZF_SHIFT)
#define EFLAGS_ZF_1             (1L << EFLAGS_ZF_SHIFT)
#define EFLAGS_SF_SHIFT         7L
#define EFLAGS_SF_MASK          (1L << EFLAGS_SF_SHIFT)
#define EFLAGS_SF_0             (0L << EFLAGS_SF_SHIFT)
#define EFLAGS_SF_1             (1L << EFLAGS_SF_SHIFT)
#define EFLAGS_TF_SHIFT         8L
#define EFLAGS_TF_MASK          (1L << EFLAGS_TF_SHIFT)
#define EFLAGS_TF_0             (0L << EFLAGS_TF_SHIFT)
#define EFLAGS_TF_1             (1L << EFLAGS_TF_SHIFT)
#define EFLAGS_IF_SHIFT         9L
#define EFLAGS_IF_MASK          (1L << EFLAGS_IF_SHIFT)
#define EFLAGS_IF_0             (0L << EFLAGS_IF_SHIFT)
#define EFLAGS_IF_1             (1L << EFLAGS_IF_SHIFT)
#define EFLAGS_DF_SHIFT         10L
#define EFLAGS_DF_MASK          (1L << EFLAGS_DF_SHIFT)
#define EFLAGS_DF_0             (0L << EFLAGS_DF_SHIFT)
#define EFLAGS_DF_1             (1L << EFLAGS_DF_SHIFT)
#define EFLAGS_OF_SHIFT         11L
#define EFLAGS_OF_MASK          (1L << EFLAGS_OF_SHIFT)
#define EFLAGS_OF_0             (0L << EFLAGS_OF_SHIFT)
#define EFLAGS_OF_1             (1L << EFLAGS_OF_SHIFT)
#define EFLAGS_IOPL_SHIFT       12L
#define EFLAGS_IOPL_MASK        (3L << EFLAGS_IOPL_SHIFT)
#define EFLAGS_IOPL_0           (0L << EFLAGS_IOPL_SHIFT)
#define EFLAGS_IOPL_3           (3L << EFLAGS_IOPL_SHIFT)
#define EFLAGS_NT_SHIFT         14L
#define EFLAGS_NT_MASK          (1L << EFLAGS_NT_SHIFT)
#define EFLAGS_NT_0             (0L << EFLAGS_NT_SHIFT)
#define EFLAGS_NT_1             (1L << EFLAGS_NT_SHIFT)
#define EFLAGS_RF_SHIFT         16L
#define EFLAGS_RF_MASK          (1L << EFLAGS_RF_SHIFT)
#define EFLAGS_RF_0             (0L << EFLAGS_RF_SHIFT)
#define EFLAGS_RF_1             (1L << EFLAGS_RF_SHIFT)
#define EFLAGS_VM_SHIFT         17L
#define EFLAGS_VM_MASK          (1L << EFLAGS_VM_SHIFT)
#define EFLAGS_VM_0             (0L << EFLAGS_VM_SHIFT)
#define EFLAGS_VM_1             (1L << EFLAGS_VM_SHIFT)
#define EFLAGS_AC_SHIFT         18L
#define EFLAGS_AC_MASK          (1L << EFLAGS_AC_SHIFT)
#define EFLAGS_AC_0             (0L << EFLAGS_AC_SHIFT)
#define EFLAGS_AC_1             (1L << EFLAGS_AC_SHIFT)
#define EFLAGS_VIF_SHIFT        19L
#define EFLAGS_VIF_MASK         (1L << EFLAGS_VIF_SHIFT)
#define EFLAGS_VIF_0            (0L << EFLAGS_VIF_SHIFT)
#define EFLAGS_VIF_1            (1L << EFLAGS_VIF_SHIFT)
#define EFLAGS_VIP_SHIFT        20L
#define EFLAGS_VIP_MASK         (1L << EFLAGS_VIP_SHIFT)
#define EFLAGS_VIP_0            (0L << EFLAGS_VIP_SHIFT)
#define EFLAGS_VIP_1            (1L << EFLAGS_VIP_SHIFT)
#define EFLAGS_ID_SHIFT         21L
#define EFLAGS_ID_MASK          (1L << EFLAGS_ID_SHIFT)
#define EFLAGS_ID_0             (0L << EFLAGS_ID_SHIFT)
#define EFLAGS_ID_1             (1L << EFLAGS_ID_SHIFT)

//
// Structure: ST_CR0
//
// Description:
//      Fields for control register #0
//
// Fields:
//  PG <31> Paging
//      Enables paging when set; disables paging when clear. When paging is 
//      disabled, all linear addresses are treated as physical addresses. 
//      The PG flag has no effect if the PE flag (bit 0 of register CR0) is 
//      not also set; in fact, setting the PG flag when the PE flag is clear 
//      causes a general-protection exception (#GP) to be generated.
//
//  CD <30> Cache Disable
//      When the CD and NW flags are clear, caching of memory locations for 
//      the whole of physical memory in the processor’s internal (and 
//      external) caches is enabled. When the CD flag is set, caching is 
//      restricted as described in Table 9-4, in Chapter 9, Memory Cache 
//      Control.  To prevent the processor from accessing and updating its 
//      caches, the CD flag must be set and the caches must be invalidated 
//      so that no cache hits can occur.
//
//  NW <29> Not Write-through. 
//      When the NW and CD flags are clear, write-back (for Pentium ® and 
//      P6 family processors) or write-through (for Intel486™ processors)
//      is enabled for writes that hit the cache and invalidation cycles are 
//      enabled.
//
//  AM <18> Alignment Mask 
//      Enables automatic alignment checking when set; disables alignment 
//      checking when clear. Alignment checking is performed only when
//      the AM flag is set, the AC flag in the EFLAGS register is set, the 
//      CPL is 3, and the processor is operating in either protected or 
//      virtual-8086 mode.
//
//  WP <16> Write Protect
//      Inhibits supervisor-level procedures from writing into user-level 
//      read-only pages when set; allows supervisor-level procedures to write 
//      into user-level read-only pages when clear. This flag facilitates 
//      implementation of the copy-on-write method of creating a new process 
//      (forking) used by operating systems such as UNIX*.
//
//  NE <5> Numeric Error
//      Enables the native (internal) mechanism for reporting FPU errors 
//      when set; enables the PC-style FPU error reporting mechanism when 
//      clear.  When the NE flag is clear and the IGNNE# input is asserted, 
//      FPU errors are ignored.  When the NE flag is clear and the IGNNE# 
//      input is deasserted, an unmasked FPU error causes the processor to 
//      assert the FERR# pin to generate an external interrupt and to stop 
//      instruction execution immediately before executing the next waiting 
//      floating-point instruction or WAIT/FWAIT instruction. The FERR# pin 
//      is intended to drive an input to an external interrupt controller 
//      (the FERR# pin emulates the ERROR# pin of the Intel 287 and Intel 
//      387 DX math coprocessors). The NE flag, IGNNE# pin, and FERR# pin 
//      are used with external logic to implement PC-style error reporting. 
//
//  ET <4> Extension Type
//      Reserved in the P6 family and Pentium ® processors.  (In the P6 
//      family processors, this flag is hardcoded to 1.) In the Intel386™ and
//      Intel486™ processors, this flag indicates support of Intel 387 DX 
//      math coprocessor instructions when set.
//
//  TS <3> Task Switched
//      Allows the saving of FPU context on a task switch to be delayed 
//      until the FPU is actually accessed by the new task.  The processor 
//      sets this flag on every task switch and tests it when interpreting 
//      floating-point arithmetic instructions.
//
//  EM <2> Emulation
//      Indicates that the processor does not have an internal or external 
//      FPU when set; indicates an FPU is present when clear. When the EM 
//      flag is set, execution of a floating-point instruction generates a 
//      device-not-available exception (#NM). This flag must be set when the 
//      processor does not have an internal FPU or is not connected to a 
//      math coprocessor. If the processor does have an internal FPU, setting 
//      this flag would force all floating-point instructions to be handled 
//      by software emulation. 
//
//  MP <1> Monitor Coprocessor
//      Controls the interaction of the WAIT (or FWAIT) instruction with the 
//      TS flag (bit 3 of CR0). If the MP flag is set, a WAIT instruction 
//      generates a device-not-available exception (#NM) if the TS flag is 
//      set. If the MP flag is clear, the WAIT instruction ignores the 
//      setting of the TS flag. 
//
//  PE <0> Protection Enable 
//      Enables protected mode when set; enables real-address mode when 
//      clear. This flag does not enable paging directly. It only enables
//      segment-level protection. To enable paging, both the PE and PG flags 
//      must be set.
//
typedef union
{
    DWORD all;

    struct
    {
        DWORD PE            :1;     // <0>
        DWORD MP            :1;     // <1>
        DWORD EM            :1;     // <2>
        DWORD TS            :1;     // <3>
        DWORD ET            :1;     // <4>
        DWORD NE            :1;     // <5>
        DWORD Rsvd1         :10;    // <15:6>
        DWORD WP            :1;     // <16>
        DWORD Rsvd2         :1;     // <17>
        DWORD AM            :1;     // <18>
        DWORD Rsvd3         :10;    // <28:19>
        DWORD NW            :1;     // <29>
        DWORD CD            :1;     // <30>
        DWORD PG            :1;     // <31>
    };

} ST_CR0;

#define CR0_PE_SHIFT        0L
#define CR0_PE_MASK         (1L << CR0_PE_SHIFT)
#define CR0_PE_0            (0L << CR0_PE_SHIFT)
#define CR0_PE_1            (1L << CR0_PE_SHIFT)
#define CR0_MP_SHIFT        1L                
#define CR0_MP_MASK         (1L << CR0_MP_SHIFT)
#define CR0_MP_0            (0L << CR0_MP_SHIFT)
#define CR0_MP_1            (1L << CR0_MP_SHIFT)
#define CR0_EM_SHIFT        2L                
#define CR0_EM_MASK         (1L << CR0_EM_SHIFT)
#define CR0_EM_0            (0L << CR0_EM_SHIFT)
#define CR0_EM_1            (1L << CR0_EM_SHIFT)
#define CR0_RS_SHIFT        3L                
#define CR0_RS_MASK         (1L << CR0_RS_SHIFT)
#define CR0_RS_0            (0L << CR0_RS_SHIFT)
#define CR0_RS_1            (1L << CR0_RS_SHIFT)
#define CR0_ET_SHIFT        4L                
#define CR0_ET_MASK         (1L << CR0_ET_SHIFT)
#define CR0_ET_0            (0L << CR0_ET_SHIFT)
#define CR0_ET_1            (1L << CR0_ET_SHIFT)
#define CR0_NE_SHIFT        5L                
#define CR0_NE_MASK         (1L << CR0_NE_SHIFT)
#define CR0_NE_0            (0L << CR0_NE_SHIFT)
#define CR0_NE_1            (1L << CR0_NE_SHIFT)
#define CR0_WP_SHIFT        16L                
#define CR0_WP_MASK         (1L << CR0_WP_SHIFT)
#define CR0_WP_0            (0L << CR0_WP_SHIFT)
#define CR0_WP_1            (1L << CR0_WP_SHIFT)
#define CR0_AM_SHIFT        18L                
#define CR0_AM_MASK         (1L << CR0_AM_SHIFT)
#define CR0_AM_0            (0L << CR0_AM_SHIFT)
#define CR0_AM_1            (1L << CR0_AM_SHIFT)
#define CR0_NW_SHIFT        29L                
#define CR0_NW_MASK         (1L << CR0_NW_SHIFT)
#define CR0_NW_0            (0L << CR0_NW_SHIFT)
#define CR0_NW_1            (1L << CR0_NW_SHIFT)
#define CR0_CD_SHIFT        30L                
#define CR0_CD_MASK         (1L << CR0_CD_SHIFT)
#define CR0_CD_0            (0L << CR0_CD_SHIFT)
#define CR0_CD_1            (1L << CR0_CD_SHIFT)
#define CR0_PG_SHIFT        31L                
#define CR0_PG_MASK         (1L << CR0_PG_SHIFT)
#define CR0_PG_0            (0L << CR0_PG_SHIFT)
#define CR0_PG_1            (1L << CR0_PG_SHIFT)

//
// Structure: ST_CR3
//
// Description:
//      Fields for control register #3
//
typedef union
{
    DWORD all;

    struct
    {
        DWORD Rsvd1         :3;  // <2:0>
        DWORD PWT           :1;  // <3>
        DWORD PCD           :1;  // <4>
        DWORD Rsvd2         :7;  // <11:5>
        DWORD Base          :20; // <31:12>
    };

} ST_CR3;

#define CR3_PWT_SHIFT       3L
#define CR3_PWT_MASK        (1L << CR3_PWT_SHIFT)
#define CR3_PWT_0           (0L << CR3_PWT_SHIFT)
#define CR3_PWT_1           (1L << CR3_PWT_SHIFT)
#define CR3_PCD_SHIFT       4L
#define CR3_PCD_MASK        (1L << CR3_PCD_SHIFT)
#define CR3_PCD_0           (0L << CR3_PCD_SHIFT)
#define CR3_PCD_1           (1L << CR3_PCD_SHIFT)
#define CR3_BASE_SHIFT      12L
#define CR3_BASE_MASK       (0xFFFFFL << CR3_BASE_SHIFT)

//
// Structure: ST_CR4
//
// Description:
//      Fields for control register #4
//
// Fields:
//  VME <0>
//      Virtual-8086 Mode Extensions. Enables interrupt and exception-
//      handling extensions in virtual-8086 mode when set; disables the 
//      extensions when clear. Use of the virtual mode extensions can improve 
//      the performance of virtual-8086 applications by eliminating the 
//      overhead of calling the virtual-8086 monitor to handle interrupts
//      and exceptions that occur while executing an 8086 program and, instead,
//      redirecting the interrupts and exceptions back to the 8086 program’s 
//      handlers. It also provides hardware support for a virtual interrupt 
//      flag (VIF) to improve reliability of running 8086 programs in 
//      multitasking and multiple-processor environments. 
//
//  PVI <1>
//      Protected-Mode Virtual Interrupts.  Enables hardware support for a
//      virtual interrupt flag (VIF) in protected mode when set; disables 
//      the VIF flag in protected mode when clear.  
//
//  TSD <2>
//      Time Stamp Disable.  Restricts the execution of the RDTSC instruction
//      to procedures running at privilege level 0 when set; allows RDTSC 
//      instruction to be executed at any privilege level when clear.
//
//  DE <3>
//      Debugging Extensions.  References to debug registers DR4 and DR5
//      cause an undefined opcode (#UD) exception to be generated when set; 
//      when clear, processor aliases references to registers DR4 and DR5 
//      for compatibility with software written to run on earlier Intel 
//      Architecture processors. 
//
//  PSE <4>
//      Page Size Extensions.  Enables 4-MByte pages when set; restricts pages
//      to 4 KBytes when clear.  
//
//  PAE <5>
//      Physical Address Extension.  Enables paging mechanism to reference
//      36-bit physical addresses when set; restricts physical addresses to 
//      32 bits when clear.
//
//  MCE <6>
//      Machine-Check Enable.  Enables the machine-check exception when
//      set; disables the machine-check exception when clear. 
//
//  PGE <7>
//      Page Global Enable.  (Introduced in the P6 family processors.)  
//      Enables the global page feature when set; disables the global page 
//      feature when clear. The global page feature allows frequently used 
//      or shared pages to be marked as global to all users (done with the 
//      global flag, bit 8, in a page-directory or page-table entry).
//      Global pages are not flushed from the translation-lookaside buffer 
//      (TLB) on a task switch or a write to register CR3. In addition, the 
//      bit must not be enabled before paging is enabled via CR0.PG. Program 
//      correctness may be affected by reversing this sequence, and processor 
//      performance will be impacted. 
//
//  PCE <8>
//      Performance-Monitoring Counter Enable.  Enables execution of the
//      RDPMC instruction for programs or procedures running at any 
//      protection level when set; RDPMC instruction can be executed only 
//      at protection level 0 when clear.
//
//  OSFXSR <9> Operating Sytsem FXSAVE/FXRSTOR Support.  
//      The operating system will set this bit if both the CPU and the OS 
//      support the use of FXSAVE/FXRSTOR for use during context switches.
//
//  OSXMMEXCPT <10> Operating System Unmasked Exception Support.  
//      The operating system will set this bit if it provides support for 
//      unmasked SIMD floating-point exceptions.
//
typedef union
{
    DWORD all;

    struct
    {
        DWORD VME           :1;     // <0>
        DWORD PVI           :1;     // <1>
        DWORD TSD           :1;     // <2>
        DWORD DE            :1;     // <3>
        DWORD PSE           :1;     // <4>
        DWORD PAE           :1;     // <5>
        DWORD MCE           :1;     // <6>
        DWORD PGE           :1;     // <7>
        DWORD PCE           :1;     // <8>
        DWORD OSFXSR        :1;     // <9>
        DWORD OSXMMEXCPT    :1;     // <10>
        DWORD Rsvd1         :21;    // <31:11>
    };

} ST_CR4;

#define CR4_VME_SHIFT           0L
#define CR4_VME_MASK            (1L << CR3_VME_SHIFT)
#define CR4_VME_0               (0L << CR3_VME_SHIFT)
#define CR4_VME_1               (1L << CR3_VME_SHIFT)
#define CR4_PVI_SHIFT           1L                
#define CR4_PVI_MASK            (1L << CR3_PVI_SHIFT)
#define CR4_PVI_0               (0L << CR3_PVI_SHIFT)
#define CR4_PVI_1               (1L << CR3_PVI_SHIFT)
#define CR4_TSD_SHIFT           2L                
#define CR4_TSD_MASK            (1L << CR3_TSD_SHIFT)
#define CR4_TSD_0               (0L << CR3_TSD_SHIFT)
#define CR4_TSD_1               (1L << CR3_TSD_SHIFT)
#define CR4_DS_SHIFT            3L                
#define CR4_DS_MASK             (1L << CR3_DS_SHIFT)
#define CR4_DS_0                (0L << CR3_DS_SHIFT)
#define CR4_DS_1                (1L << CR3_DS_SHIFT)
#define CR4_PSE_SHIFT           4L                
#define CR4_PSE_MASK            (1L << CR3_PSE_SHIFT)
#define CR4_PSE_0               (0L << CR3_PSE_SHIFT)
#define CR4_PSE_1               (1L << CR3_PSE_SHIFT)
#define CR4_PAE_SHIFT           5L                
#define CR4_PAE_MASK            (1L << CR3_PAE_SHIFT)
#define CR4_PAE_0               (0L << CR3_PAE_SHIFT)
#define CR4_PAE_1               (1L << CR3_PAE_SHIFT)
#define CR4_MCE_SHIFT           6L                
#define CR4_MCE_MASK            (1L << CR3_MCE_SHIFT)
#define CR4_MCE_0               (0L << CR3_MCE_SHIFT)
#define CR4_MCE_1               (1L << CR3_MCE_SHIFT)
#define CR4_PGE_SHIFT           7L                
#define CR4_PGE_MASK            (1L << CR3_PGE_SHIFT)
#define CR4_PGE_0               (0L << CR3_PGE_SHIFT)
#define CR4_PGE_1               (1L << CR3_PGE_SHIFT)
#define CR4_PCE_SHIFT           8L                
#define CR4_PCE_MASK            (1L << CR3_PCE_SHIFT)
#define CR4_PCE_0               (0L << CR3_PCE_SHIFT)
#define CR4_PCE_1               (1L << CR3_PCE_SHIFT)
#define CR4_OSFXSR_SHIFT        9L                
#define CR4_OSFXSR_MASK         (1L << CR3_OSFXSR_SHIFT)
#define CR4_OSFXSR_0            (0L << CR3_OSFXSR_SHIFT)
#define CR4_OSFXSR_1            (1L << CR3_OSFXSR_SHIFT)
#define CR4_OSXMMEXCPT_SHIFT    10L                
#define CR4_OSXMMEXCPT_MASK     (1L << CR3_OSXMMEXCPT_SHIFT)
#define CR4_OSXMMEXCPT_0        (0L << CR3_OSXMMEXCPT_SHIFT)
#define CR4_OSXMMEXCPT_1        (1L << CR3_OSXMMEXCPT_SHIFT)

//
// Structure: ST_SELECTOR
//
// Description:
//      Fields for LDT/GDT selector handle
//
typedef union
{
    WORD all;

    struct
    {
        WORD RPL            :2;     // <1:0> Requested Privilege Level
        WORD TI             :1;     // <2>   Table Indicator
        WORD Index          :13;    // <15:3>
    };

} ST_SELECTOR;

#define SELECTOR_RPL_SHIFT      0L
#define SELECTOR_RPL_MASK       (3L << SELECTOR_RPL_SHIFT)
#define SELECTOR_RPL_0          (0L << SELECTOR_RPL_SHIFT)
#define SELECTOR_RPL_1          (1L << SELECTOR_RPL_SHIFT)
#define SELECTOR_RPL_2          (2L << SELECTOR_RPL_SHIFT)
#define SELECTOR_RPL_3          (3L << SELECTOR_RPL_SHIFT)
#define SELECTOR_TI_SHIFT       2L
#define SELECTOR_TI_MASK        (1L << SELECTOR_TI_SHIFT)
#define SELECTOR_TI_GDT         (0L << SELECTOR_TI_SHIFT)
#define SELECTOR_TI_LDT         (1L << SELECTOR_TI_SHIFT)
#define SELECTOR_INDEX_SHIFT    3L
#define SELECTOR_INDEX_MASK     (0x1FFFL << SELECTOR_INDEX_SHIFT)

//
// Structure: ST_DESCRIPTOR
//
// Descriptor:
//      Fields for LDT and GDT entries.
//
typedef union
{
    struct
    {
        DWORD ulDescLo; // <31:0>
        DWORD ulDescHi; // <63:32>
    };

    struct
    {
        // Low dword
        DWORD Limit0    :16;    // <15:0>
        DWORD Base0     :16;    // <31:16>

        // High dword
        DWORD Base16    :8;     // <7:0>
        DWORD Type      :4;     // <11:8>
        DWORD S         :1;     // <12>
        DWORD DPL       :2;     // <14:13>
        DWORD P         :1;     // <15>
        DWORD Limit16   :4;     // <19:16>
        DWORD AVL       :1;     // <20>
        DWORD Rsvd1     :1;     // <21>
        DWORD DB        :1;     // <22>
        DWORD G         :1;     // <23>
        DWORD Base24    :8;     // <31:24>
    };

} ST_DTE;

// DTE Low fields
#define DTE_LIMIT0_SHIFT        0L
#define DTE_LIMIT0_MASK         (0xFFFFL << DTE_LIMIT0_SHIFT)
#define DTE_BASE0_SHIFT         16L
#define DTE_BASE0_MASK          (0xFFFFL << DTE_BASE0_SHIFT)

// DTE High fields
#define DTE_BASE16_SHIFT        0L
#define DTE_BASE16_MASK         (0x00FFL << DTE_BASE16_SHIFT)
#define DTE_TYPE_SHIFT          8L
#define DTE_TYPE_MASK           (0x000FL << DTE_TYPE_SHIFT)
#define DTE_S_SHIFT             12L
#define DTE_S_MASK              (1L << DTE_S_SHIFT)
#define DTE_DPL_SHIFT           13L
#define DTE_DPL_MASK            (3L << DTE_DPL_SHIFT)
#define DTE_P_SHIFT             15L
#define DTE_P_MASK              (1L << DTE_P_SHIFT)
#define DTE_LIMIT16_SHIFT       16L
#define DTE_LIMIT16_MASK        (0x000FL << DTE_LIMIT16_SHIFT)
#define DTE_AVL_SHIFT           20L
#define DTE_AVL_MASK            (1L << DTE_AVL_SHIFT)
#define DTE_DB_SHIFT            22L
#define DTE_DB_MASK             (1L << DTE_DB_SHIFT)
#define DTE_G_SHIFT             23L
#define DTE_G_MASK              (1L << DTE_G_SHIFT)
#define DTE_BASE24_SHIFT        24L
#define DTE_BASE24_MASK         (0x00FFL << DTE_BASE24_SHIFT)

//
// Structure: ST_PDE
//
// Description:
//      Page Directory Entry
//
// Fields:
//      P <0>
//          Present bit
//
//          0   not present
//          1   present
//
//      RW <1>
//          Read/Write
//
//          0   read only
//          1   read/write
//
//      US <2>
//          User/Supervisor
//
//          0   Supervisor
//          1   User
//
//      PWT <3>
//          etc.
//
typedef union
{
    DWORD all;

    struct
    {
        DWORD P         :1;     // <0>
        DWORD RW        :1;     // <1>
        DWORD US        :1;     // <2>
        DWORD PWT       :1;     // <3>
        DWORD PCD       :1;     // <4>
        DWORD A         :1;     // <5>
        DWORD Rsvd1     :1;     // <6>
        DWORD PS        :1;     // <7>
        DWORD G         :1;     // <8>
        DWORD Avail     :3;     // <11:9>
        DWORD Base      :20;    // <31:12>
    };

} ST_PDE;

typedef union
{
    DWORD all;

    struct
    {
        DWORD P         :1;     // <0>
        DWORD RW        :1;     // <1>
        DWORD US        :1;     // <2>
        DWORD PWT       :1;     // <3>
        DWORD PCD       :1;     // <4>
        DWORD A         :1;     // <5>
        DWORD D         :1;     // <6>
        DWORD PS        :1;     // <7>
        DWORD G         :1;     // <8>
        DWORD Avail     :3;     // <11:9>
        DWORD PAi       :1;     // <12>
        DWORD Rsvd1     :9;     // <21:13>
        DWORD Base      :10;    // <31:22>
    };

} ST_PDE_4M;

#define PDE_P_SHIFT             0L
#define PDE_P_MASK              (1L << PDE_P_SHIFT)
#define PDE_P_NO                (0L << PDE_P_SHIFT)
#define PDE_P_YES               (1L << PDE_P_SHIFT)
#define PDE_RW_SHIFT            1L
#define PDE_RW_MASK             (1L << PDE_RW_SHIFT)
#define PDE_RW_READONLY         (0L << PDE_RW_SHIFT)
#define PDE_RW_READWRITE        (1L << PDE_RW_SHIFT)
#define PDE_US_SHIFT            2L
#define PDE_US_MASK             (1L << PDE_US_SHIFT)
#define PDE_US_SYSTEM           (0L << PDE_US_SHIFT)
#define PDE_US_USER             (1L << PDE_US_SHIFT)
#define PDE_PWT_SHIFT           3L
#define PDE_PWT_MASK            (1L << PDE_PWT_SHIFT)
#define PDE_PWT_0               (0L << PDE_PWT_SHIFT)
#define PDE_PWT_1               (1L << PDE_PWT_SHIFT)
#define PDE_PCD_SHIFT           4L
#define PDE_PCD_MASK            (1L << PDE_PCD_SHIFT)
#define PDE_PCD_0               (0L << PDE_PCD_SHIFT)
#define PDE_PCD_1               (1L << PDE_PCD_SHIFT)
#define PDE_A_SHIFT             5L
#define PDE_A_MASK              (1L << PDE_A_SHIFT)
#define PDE_A_NO                (0L << PDE_A_SHIFT)
#define PDE_A_YES               (1L << PDE_A_SHIFT)
#define PDE_D_SHIFT             6L
#define PDE_D_MASK              (1L << PDE_D_SHIFT)
#define PDE_D_CLEAN             (0L << PDE_D_SHIFT)
#define PDE_D_DIRTY             (1L << PDE_D_SHIFT)
#define PDE_PS_SHIFT            7L
#define PDE_PS_MASK             (1L << PDE_PS_SHIFT)
#define PDE_PS_4KB              (0L << PDE_PS_SHIFT)
#define PDE_PS_4MB              (1L << PDE_PS_SHIFT)
#define PDE_G_SHIFT             8L
#define PDE_G_MASK              (1L << PDE_G_SHIFT)
#define PDE_G_0                 (0L << PDE_G_SHIFT)
#define PDE_G_1                 (1L << PDE_G_SHIFT)
#define PDE_AVAIL_SHIFT         9L
#define PDE_AVAIL_MASK          (0x7L << PDE_AVAIL_SHIFT)
#define PDE_ADDR_SHIFT          12L
#define PDE_ADDR_MASK           (0xFFFFFL << PDE_ADDR_SHIFT)
#define PDE_ADDR4MB_SHIFT       22L
#define PDE_ADDR4MB_MASK        (0xFFCL << PDE_ADDR4MB_SHIFT)

typedef union
{
    DWORD all;

    struct
    {
        DWORD P         :1;     // <0>
        DWORD RW        :1;     // <1>
        DWORD US        :1;     // <2>
        DWORD PWT       :1;     // <3>
        DWORD PCD       :1;     // <4>
        DWORD A         :1;     // <5>
        DWORD D         :1;     // <6>
        DWORD PAi       :1;     // <7>
        DWORD G         :1;     // <8>
        DWORD Avail     :3;     // <11:9>
        DWORD Base      :20;    // <31:12>
    };

} ST_PTE;

#define PTE_P_SHIFT             0L
#define PTE_P_MASK              (0x1L << PTE_P_SHIFT)
#define PTE_P_NO                (0x0L << PTE_P_SHIFT)
#define PTE_P_YES               (0x1L << PTE_P_SHIFT)
#define PTE_RW_SHIFT            1L
#define PTE_RW_MASK             (0x1L << PTE_RW_SHIFT)
#define PTE_RW_READONLY         (0x0L << PTE_RW_SHIFT)
#define PTE_RW_READWRITE        (0x1L << PTE_RW_SHIFT)
#define PTE_US_SHIFT            2L
#define PTE_US_MASK             (0x1L << PTE_US_SHIFT)
#define PTE_US_SYSTEM           (0x0L << PTE_US_SHIFT)
#define PTE_US_USER             (0x1L << PTE_US_SHIFT)
#define PTE_PWT_SHIFT           3L
#define PTE_PWT_MASK            (0x1L << PTE_PWT_SHIFT)
#define PTE_PWT_0               (0x0L << PTE_PWT_SHIFT)
#define PTE_PWT_1               (0x1L << PTE_PWT_SHIFT)
#define PTE_PCD_SHIFT           4L
#define PTE_PCD_MASK            (0x1L << PTE_PCD_SHIFT)
#define PTE_PCD_0               (0x0L << PTE_PCD_SHIFT)
#define PTE_PCD_1               (0x1L << PTE_PCD_SHIFT)
#define PTE_A_SHIFT             5L
#define PTE_A_MASK              (0x1L << PTE_A_SHIFT)
#define PTE_A_NO                (0x0L << PTE_A_SHIFT)
#define PTE_A_YES               (0x1L << PTE_A_SHIFT)
#define PTE_D_SHIFT             6L
#define PTE_D_MASK              (0x1L << PTE_D_SHIFT)
#define PTE_D_CLEAN             (0x0L << PTE_D_SHIFT)
#define PTE_D_DIRTY             (0x1L << PTE_D_SHIFT)
#define PTE_G_SHIFT             8L
#define PTE_G_MASK              (0x1L << PTE_G_SHIFT)
#define PTE_G_0                 (0x0L << PTE_G_SHIFT)
#define PTE_G_1                 (0x1L << PTE_G_SHIFT)
#define PTE_AVAIL_SHIFT         9L
#define PTE_AVAIL_MASK          (0x7L << PTE_AVAIL_SHIFT)
#define PTE_ADDR_SHIFT          12L
#define PTE_ADDR_MASK           (0xFFFFF << PTE_ADDR_SHIFT)

//---------------------------------------------------------------------------
// Function: CPUID_GetProcessorSignature
//
// Description:
//      Get the processor signature dword.
//
//       31                       12 11   8 7    4 3    0
//      +---------------------------+------+------+------+
//      |///////////////////////////|      |      |      |
//      +---------------------------+------+------+------+
//                                     ^      ^      ^
//                                     |      |      |
//                      Family --------/      |      |
//                       Model ---------------/      |
//                    Stepping ----------------------/
//
//                  Family  Model   Stepping
//      Amx86       4       X       X
//      AMD-K5      5       0-3     X
//      AMD-K6      5       6-7     X
//      AMD-K6-2    5       8       0-7
//      AMD-K6-2*   5       8       8-F
//      AMD-K6-3    5       9       X
//
//      (*) Support for WC
//---------------------------------------------------------------------------


typedef struct
{
    DWORD regEAX;
    DWORD regEBX;
    DWORD regECX;
    DWORD regEDX;

} CPUID_REGS;


typedef union
{
    CPUID_REGS regs;

    struct
    {
        DWORD ulMaxInput;           // EAX
        DWORD ulVendorString0;      // EBX
        DWORD ulVendorString2;      // ECX
        DWORD ulVendorString1;      // EDX
    };

} CPUID_FUNCTION_0;

//
//  0   FPU     Floating-point unit on-chip 
//              The processor contains an FPU that supports the Intel 387 
//              floating-point instruction set.
//
//  1   VME     Virtual Mode Extension 
//              The processor supports extensions to virtual-8086 mode.
//
//  2   DE      Debugging Extension 
//              The processor supports I/O breakpoints, 
//              including the CR4.DE bit for enabling debug extensions and 
//              optional trapping of access to the DR4 and DR5 registers.
//
//  3   PSE     Page Size Extension 
//              The processor supports 4-Mbyte pages.
//
//  4   TSC     Time Stamp Counter 
//              The RDTSC instruction is supported including the CR4.TSD bit 
//              for access/privilege control.
//
//  5   MSR     Model Specific Registers Model Specific Registers are 
//              implemented with the RDMSR, WRMSR instructions
//
//  6   PAE     Physical Address Extension
//              Physical addresses greater than 32 bits are supported.
//
//  7   MCE     Machine Check Exception 
//              Machine Check Exception, Exception 18, and the CR4.MCE 
//              enable bit are supported
//
//  8   CX8     CMPXCHG8 Instruction Supported
//              The compare and exchange 8 bytes instruction is supported.
//
//  9   APIC    On-chip APIC Hardware
//              Supported (1) The processor contains a local APIC.
//
//  11  SEP     Fast System Call 
//              Indicates whether the processor supports the Fast System
//              Call instructions, SYSENTER and SYSEXIT. NOTE: Refer to
//              Section 3.5 for further information regarding SYSENTER/
//              SYSEXIT feature and SEP feature bit.
//
//  12  MTRR    Memory Type Range Registers
//              The Processor supports the Memory Type Range Registers
//              specifically the MTRR_CAP register.
//
//  13  PGE     Page Global Enable 
//              The global bit in the PDEs and PTEs and the CR4.PGE enable 
//              bit are supported.
//
//  14  MCA     Machine Check Architecture
//              The Machine Check Architecture is supported, specifically 
//              the MCG_CAP register.
//
//  15  CMOV    Conditional Move Instruction Supported
//              The processor supports CMOVcc, and if the FPU feature flag
//              (bit 0) is also set, supports the FCMOVCC and FCOMI
//              instructions.
//
//  16  PAT     Page Attribute Table 
//              Indicates whether the processor supports the Page Attribute
//              Table. This feature augments the Memory Type Range
//              Registers (MTRRs), allowing an operating system to specify
//              attributes of memory on a 4K granularity through a linear
//              address.
//
//  17  PSE36   36-bit Page Size Extension
//              Indicates whether the processor supports 4-Mbyte pages that
//              are capable of addressing physical memory beyond 4GB. This
//              feature indicates that the upper four bits of the physical
//              address of the 4-Mbyte page is encoded by bits 13-16 of the
//              page directory entry.
//
//  23  MMX     Intel Architecture MMX™ technology supported
//              The processor supports the MMX technology instruction set
//              extensions to Intel Architecture.
//
//  24  FXSR    Fast floating-point save and restore
//              Indicates whether the processor supports the FXSAVE and
//              FXRSTOR instructions for fast save and restore of the
//              floating-point context. Presence of this bit also indicates that
//              CR4.OSFXSR is available for an operating system to indicate
//              that it uses the fast save/restore instructions.
//
typedef union
{
    CPUID_REGS regs;

    struct
    {
        struct
        {
            DWORD   stepping    :4;
            DWORD   model       :4;
            DWORD   family      :4;
            DWORD   type        :2;
            DWORD   Rsvd1       :18;
        };  // EAX

        DWORD Rsvd2; // EBX
        DWORD Rsvd3; // ECX

        struct
        {
            DWORD   FPU         :1;     // <0>
            DWORD   VME         :1;     // <1>
            DWORD   DE          :1;     // <2>
            DWORD   PSE         :1;     // <3>
            DWORD   TSC         :1;     // <4>
            DWORD   MSR         :1;     // <5>
            DWORD   PAE         :1;     // <6>
            DWORD   MCE         :1;     // <7>
            DWORD   CX8         :1;     // <8>
            DWORD   APIC        :1;     // <9>
            DWORD   Rsvd4       :1;     // <10>
            DWORD   SEP         :1;     // <11>
            DWORD   MTRR        :1;     // <12>
            DWORD   PGE         :1;     // <13>
            DWORD   MCA         :1;     // <14>
            DWORD   CMOV        :1;     // <15>
            DWORD   PAT         :1;     // <16>
            DWORD   PSE36       :1;     // <17>
            DWORD   Rsvd5       :5;     // <22:18>
            DWORD   MMX         :1;     // <23>
            DWORD   FXSR        :1;     // <24>
            DWORD   SIMD        :1;     // <25>
            DWORD   Rsvd6       :6;     // <31:26>
        };  // EDX

    };

} CPUID_FUNCTION_1;

#define CPUID_FEATURE_FPU_SHIFT     0L
#define CPUID_FEATURE_FPU_MASK      (1L << CPUID_FEATURE_FPU_SHIFT)
#define CPUID_FEATURE_FPU_0         (0L << CPUID_FEATURE_FPU_SHIFT)
#define CPUID_FEATURE_FPU_1         (1L << CPUID_FEATURE_FPU_SHIFT)
#define CPUID_FEATURE_VME_SHIFT     1L                          
#define CPUID_FEATURE_VME_MASK      (1L << CPUID_FEATURE_VME_SHIFT)
#define CPUID_FEATURE_VME_0         (0L << CPUID_FEATURE_VME_SHIFT)
#define CPUID_FEATURE_VME_1         (1L << CPUID_FEATURE_VME_SHIFT)
#define CPUID_FEATURE_DE_SHIFT      2L                          
#define CPUID_FEATURE_DE_MASK       (1L << CPUID_FEATURE_DE_SHIFT)
#define CPUID_FEATURE_DE_0          (0L << CPUID_FEATURE_DE_SHIFT)
#define CPUID_FEATURE_DE_1          (1L << CPUID_FEATURE_DE_SHIFT)
#define CPUID_FEATURE_PSE_SHIFT     3L                          
#define CPUID_FEATURE_PSE_MASK      (1L << CPUID_FEATURE_PSE_SHIFT)
#define CPUID_FEATURE_PSE_0         (0L << CPUID_FEATURE_PSE_SHIFT)
#define CPUID_FEATURE_PSE_1         (1L << CPUID_FEATURE_PSE_SHIFT)
#define CPUID_FEATURE_TSC_SHIFT     4L                          
#define CPUID_FEATURE_TSC_MASK      (1L << CPUID_FEATURE_TSC_SHIFT)
#define CPUID_FEATURE_TSC_0         (0L << CPUID_FEATURE_TSC_SHIFT)
#define CPUID_FEATURE_TSC_1         (1L << CPUID_FEATURE_TSC_SHIFT)
#define CPUID_FEATURE_MSR_SHIFT     5L                          
#define CPUID_FEATURE_MSR_MASK      (1L << CPUID_FEATURE_MSR_SHIFT)
#define CPUID_FEATURE_MSR_0         (0L << CPUID_FEATURE_MSR_SHIFT)
#define CPUID_FEATURE_MSR_1         (1L << CPUID_FEATURE_MSR_SHIFT)
#define CPUID_FEATURE_PAE_SHIFT     6L                          
#define CPUID_FEATURE_PAE_MASK      (1L << CPUID_FEATURE_PAE_SHIFT)
#define CPUID_FEATURE_PAE_0         (0L << CPUID_FEATURE_PAE_SHIFT)
#define CPUID_FEATURE_PAE_1         (1L << CPUID_FEATURE_PAE_SHIFT)
#define CPUID_FEATURE_MCE_SHIFT     7L                          
#define CPUID_FEATURE_MCE_MASK      (1L << CPUID_FEATURE_MCE_SHIFT)
#define CPUID_FEATURE_MCE_0         (0L << CPUID_FEATURE_MCE_SHIFT)
#define CPUID_FEATURE_MCE_1         (1L << CPUID_FEATURE_MCE_SHIFT)
#define CPUID_FEATURE_CX8_SHIFT     8L                          
#define CPUID_FEATURE_CX8_MASK      (1L << CPUID_FEATURE_CX8_SHIFT)
#define CPUID_FEATURE_CX8_0         (0L << CPUID_FEATURE_CX8_SHIFT)
#define CPUID_FEATURE_CX8_1         (1L << CPUID_FEATURE_CX8_SHIFT)
#define CPUID_FEATURE_APIC_SHIFT    9L                          
#define CPUID_FEATURE_APIC_MASK     (1L << CPUID_FEATURE_APIC_SHIFT)
#define CPUID_FEATURE_APIC_0        (0L << CPUID_FEATURE_APIC_SHIFT)
#define CPUID_FEATURE_APIC_1        (1L << CPUID_FEATURE_APIC_SHIFT)
#define CPUID_FEATURE_SEP_SHIFT     11L                          
#define CPUID_FEATURE_SEP_MASK      (1L << CPUID_FEATURE_SEP_SHIFT)
#define CPUID_FEATURE_SEP_0         (0L << CPUID_FEATURE_SEP_SHIFT)
#define CPUID_FEATURE_SEP_1         (1L << CPUID_FEATURE_SEP_SHIFT)
#define CPUID_FEATURE_MTRR_SHIFT    12L                          
#define CPUID_FEATURE_MTRR_MASK     (1L << CPUID_FEATURE_MTRR_SHIFT)
#define CPUID_FEATURE_MTRR_0        (0L << CPUID_FEATURE_MTRR_SHIFT)
#define CPUID_FEATURE_MTRR_1        (1L << CPUID_FEATURE_MTRR_SHIFT)
#define CPUID_FEATURE_PGE_SHIFT     13L                          
#define CPUID_FEATURE_PGE_MASK      (1L << CPUID_FEATURE_PGE_SHIFT)
#define CPUID_FEATURE_PGE_0         (0L << CPUID_FEATURE_PGE_SHIFT)
#define CPUID_FEATURE_PGE_1         (1L << CPUID_FEATURE_PGE_SHIFT)
#define CPUID_FEATURE_MCA_SHIFT     14L                          
#define CPUID_FEATURE_MCA_MASK      (1L << CPUID_FEATURE_MCA_SHIFT)
#define CPUID_FEATURE_MCA_0         (0L << CPUID_FEATURE_MCA_SHIFT)
#define CPUID_FEATURE_MCA_1         (1L << CPUID_FEATURE_MCA_SHIFT)
#define CPUID_FEATURE_CMOV_SHIFT    15L                          
#define CPUID_FEATURE_CMOV_MASK     (1L << CPUID_FEATURE_CMOV_SHIFT)
#define CPUID_FEATURE_CMOV_0        (0L << CPUID_FEATURE_CMOV_SHIFT)
#define CPUID_FEATURE_CMOV_1        (1L << CPUID_FEATURE_CMOV_SHIFT)
#define CPUID_FEATURE_PAT_SHIFT     16L                          
#define CPUID_FEATURE_PAT_MASK      (1L << CPUID_FEATURE_PAT_SHIFT)
#define CPUID_FEATURE_PAT_0         (0L << CPUID_FEATURE_PAT_SHIFT)
#define CPUID_FEATURE_PAT_1         (1L << CPUID_FEATURE_PAT_SHIFT)
#define CPUID_FEATURE_PSE36_SHIFT   17L                          
#define CPUID_FEATURE_PSE36_MASK    (1L << CPUID_FEATURE_PSE36_SHIFT)
#define CPUID_FEATURE_PSE36_0       (0L << CPUID_FEATURE_PSE36_SHIFT)
#define CPUID_FEATURE_PSE36_1       (1L << CPUID_FEATURE_PSE36_SHIFT)
#define CPUID_FEATURE_MMX_SHIFT     23L                          
#define CPUID_FEATURE_MMX_MASK      (1L << CPUID_FEATURE_MMX_SHIFT)
#define CPUID_FEATURE_MMX_0         (0L << CPUID_FEATURE_MMX_SHIFT)
#define CPUID_FEATURE_MMX_1         (1L << CPUID_FEATURE_MMX_SHIFT)
#define CPUID_FEATURE_FXSR_SHIFT    24L                          
#define CPUID_FEATURE_FXSR_MASK     (1L << CPUID_FEATURE_FXSR_SHIFT)
#define CPUID_FEATURE_FXSR_0        (0L << CPUID_FEATURE_FXSR_SHIFT)
#define CPUID_FEATURE_FXSR_1        (1L << CPUID_FEATURE_FXSR_SHIFT)
#define CPUID_FEATURE_SIMD_SHIFT    25L                          
#define CPUID_FEATURE_SIMD_MASK     (1L << CPUID_FEATURE_SIMD_SHIFT)
#define CPUID_FEATURE_SIMD_0        (0L << CPUID_FEATURE_SIMD_SHIFT)
#define CPUID_FEATURE_SIMD_1        (1L << CPUID_FEATURE_SIMD_SHIFT)

// CPU identificaiton string
#define VENDOR_STRING_INTEL     "GenuineIntel"
#define VENDOR_STRING_AMD       "AuthenticAMD"

// Constant for type field
#define CPUID_TYPE_OEM              0L
#define CPUID_TYPE_OVERDRIVE        1L
#define CPUID_TYPE_DUAL             2L

// Constants for family field
#define CPUID_FAMILY_486            4L
#define CPUID_FAMILY_PENTIUM        5L
#define CPUID_FAMILY_PENTIUM_PRO    6L

// Models for pentium family
#define CPUID_MODEL_PENTIUM_60      1L
#define CPUID_MODEL_PENTIUM_75      2L
#define CPUID_MODEL_PENTIUM_486     3L
#define CPUID_MODEL_PENTIUM_MMX     4L

// Models for pentium-pro family
#define CPUID_MODEL_PENTIUM_PRO     1L
#define CPUID_MODEL_PENTIUM_II      3L
#define CPUID_MODEL_CELERON         5L

// --------------------------------------------------------------------------------------
//                                  C O N S T A N T S
// --------------------------------------------------------------------------------------

// --------------------------------------------------------------------------------------
//                  G L O B A L   V A R I A B L E   R E F E R E N C E S
// --------------------------------------------------------------------------------------

// --------------------------------------------------------------------------------------
//               I N T E R F A C E   F U N C T I O N   P R O T O T Y P E S
// --------------------------------------------------------------------------------------

// --------------------------------------------------------------------------------------
//                           I N L I N E S   A N D   M A C R O S
// --------------------------------------------------------------------------------------

#endif  // #ifndef INC_MTXCPU0_H
