Next: , Up: A Complete Example


24.7.1 Check_CPU Procedure

     ---------------------------------------------------------------------
     --                                                                 --
     --  Uses the Intel_CPU package to identify the CPU the program is  --
     --  running on, and some of the features it supports.              --
     --                                                                 --
     ---------------------------------------------------------------------
     
     with Intel_CPU;                     --  Intel CPU detection functions
     with Ada.Text_IO;                   --  Standard text I/O
     with Ada.Command_Line;              --  To set the exit status
     
     procedure Check_CPU is
     
        Type_Found : Boolean := False;
        --  Flag to indicate that processor was identified
     
        Features   : Intel_CPU.Processor_Features;
        --  The processor features
     
        Signature  : Intel_CPU.Processor_Signature;
        --  The processor type signature
     
     begin
     
        -----------------------------------
        --  Display the program banner.  --
        -----------------------------------
     
        Ada.Text_IO.Put_Line (Ada.Command_Line.Command_Name &
                              ": check Intel CPU version and features, v1.0");
        Ada.Text_IO.Put_Line ("distribute freely, but no warranty whatsoever");
        Ada.Text_IO.New_Line;
     
        -----------------------------------------------------------------------
        --  We can safely start with the assumption that we are on at least  --
        --  a x386 processor. If the CPUID instruction is present, then we   --
        --  have a later processor type.                                     --
        -----------------------------------------------------------------------
     
        if Intel_CPU.Has_CPUID = False then
     
           --  No CPUID instruction, so we assume this is indeed a x386
           --  processor. We can still check if it has a FP co-processor.
           if Intel_CPU.Has_FPU then
              Ada.Text_IO.Put_Line
                ("x386-type processor with a FP co-processor");
           else
              Ada.Text_IO.Put_Line
                ("x386-type processor without a FP co-processor");
           end if;  --  check for FPU
     
           --  Program done
           Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Success);
           return;
     
        end if;  --  check for CPUID
     
        -----------------------------------------------------------------------
        --  If CPUID is supported, check if this is a true Intel processor,  --
        --  if it is not, display a warning.                                 --
        -----------------------------------------------------------------------
     
        if Intel_CPU.Vendor_ID /= Intel_CPU.Intel_Processor then
           Ada.Text_IO.Put_Line ("*** This is a Intel compatible processor");
           Ada.Text_IO.Put_Line ("*** Some information may be incorrect");
        end if;  --  check if Intel
     
        ----------------------------------------------------------------------
        --  With the CPUID instruction present, we can assume at least a    --
        --  x486 processor. If the CPUID support level is < 1 then we have  --
        --  to leave it at that.                                            --
        ----------------------------------------------------------------------
     
        if Intel_CPU.CPUID_Level < 1 then
     
           --  Ok, this is a x486 processor. we still can get the Vendor ID
           Ada.Text_IO.Put_Line ("x486-type processor");
           Ada.Text_IO.Put_Line ("Vendor ID is " & Intel_CPU.Vendor_ID);
     
           --  We can also check if there is a FPU present
           if Intel_CPU.Has_FPU then
              Ada.Text_IO.Put_Line ("Floating-Point support");
           else
              Ada.Text_IO.Put_Line ("No Floating-Point support");
           end if;  --  check for FPU
     
           --  Program done
           Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Success);
           return;
     
        end if;  --  check CPUID level
     
        ---------------------------------------------------------------------
        --  With a CPUID level of 1 we can use the processor signature to  --
        --  determine it's exact type.                                     --
        ---------------------------------------------------------------------
     
        Signature := Intel_CPU.Signature;
     
        ----------------------------------------------------------------------
        --  Ok, now we go into a lot of messy comparisons to get the        --
        --  processor type. For clarity, no attememt to try to optimize the --
        --  comparisons has been made. Note that since Intel_CPU does not   --
        --  support getting cache info, we cannot distinguish between P5    --
        --  and Celeron types yet.                                          --
        ----------------------------------------------------------------------
     
        --  x486SL
        if Signature.Processor_Type = 2#00#   and
          Signature.Family          = 2#0100# and
          Signature.Model           = 2#0100# then
           Type_Found := True;
           Ada.Text_IO.Put_Line ("x486SL processor");
        end if;
     
        --  x486DX2 Write-Back
        if Signature.Processor_Type = 2#00#   and
          Signature.Family          = 2#0100# and
          Signature.Model           = 2#0111# then
           Type_Found := True;
           Ada.Text_IO.Put_Line ("Write-Back Enhanced x486DX2 processor");
        end if;
     
        --  x486DX4
        if Signature.Processor_Type = 2#00#   and
          Signature.Family          = 2#0100# and
          Signature.Model           = 2#1000# then
           Type_Found := True;
           Ada.Text_IO.Put_Line ("x486DX4 processor");
        end if;
     
        --  x486DX4 Overdrive
        if Signature.Processor_Type = 2#01#   and
          Signature.Family          = 2#0100# and
          Signature.Model           = 2#1000# then
           Type_Found := True;
           Ada.Text_IO.Put_Line ("x486DX4 OverDrive processor");
        end if;
     
        --  Pentium (60, 66)
        if Signature.Processor_Type = 2#00#   and
          Signature.Family          = 2#0101# and
          Signature.Model           = 2#0001# then
           Type_Found := True;
           Ada.Text_IO.Put_Line ("Pentium processor (60, 66)");
        end if;
     
        --  Pentium (75, 90, 100, 120, 133, 150, 166, 200)
        if Signature.Processor_Type = 2#00#   and
          Signature.Family          = 2#0101# and
          Signature.Model           = 2#0010# then
           Type_Found := True;
           Ada.Text_IO.Put_Line
             ("Pentium processor (75, 90, 100, 120, 133, 150, 166, 200)");
        end if;
     
        --  Pentium OverDrive (60, 66)
        if Signature.Processor_Type = 2#01#   and
          Signature.Family          = 2#0101# and
          Signature.Model           = 2#0001# then
           Type_Found := True;
           Ada.Text_IO.Put_Line ("Pentium OverDrive processor (60, 66)");
        end if;
     
        --  Pentium OverDrive (75, 90, 100, 120, 133, 150, 166, 200)
        if Signature.Processor_Type = 2#01#   and
          Signature.Family          = 2#0101# and
          Signature.Model           = 2#0010# then
           Type_Found := True;
           Ada.Text_IO.Put_Line
             ("Pentium OverDrive cpu (75, 90, 100, 120, 133, 150, 166, 200)");
        end if;
     
        --  Pentium OverDrive processor for x486 processor-based systems
        if Signature.Processor_Type = 2#01#   and
          Signature.Family          = 2#0101# and
          Signature.Model           = 2#0011# then
           Type_Found := True;
           Ada.Text_IO.Put_Line
             ("Pentium OverDrive processor for x486 processor-based systems");
        end if;
     
        --  Pentium processor with MMX technology (166, 200)
        if Signature.Processor_Type = 2#00#   and
          Signature.Family          = 2#0101# and
          Signature.Model           = 2#0100# then
           Type_Found := True;
           Ada.Text_IO.Put_Line
             ("Pentium processor with MMX technology (166, 200)");
        end if;
     
        --  Pentium OverDrive with MMX for Pentium (75, 90, 100, 120, 133)
        if Signature.Processor_Type = 2#01#   and
          Signature.Family          = 2#0101# and
          Signature.Model           = 2#0100# then
           Type_Found := True;
           Ada.Text_IO.Put_Line
             ("Pentium OverDrive processor with MMX " &
              "technology for Pentium processor (75, 90, 100, 120, 133)");
        end if;
     
        --  Pentium Pro processor
        if Signature.Processor_Type = 2#00#   and
          Signature.Family          = 2#0110# and
          Signature.Model           = 2#0001# then
           Type_Found := True;
           Ada.Text_IO.Put_Line ("Pentium Pro processor");
        end if;
     
        --  Pentium II processor, model 3
        if Signature.Processor_Type = 2#00#   and
          Signature.Family          = 2#0110# and
          Signature.Model           = 2#0011# then
           Type_Found := True;
           Ada.Text_IO.Put_Line ("Pentium II processor, model 3");
        end if;
     
        --  Pentium II processor, model 5 or Celeron processor
        if Signature.Processor_Type = 2#00#   and
          Signature.Family          = 2#0110# and
          Signature.Model           = 2#0101# then
           Type_Found := True;
           Ada.Text_IO.Put_Line
             ("Pentium II processor, model 5 or Celeron processor");
        end if;
     
        --  Pentium Pro OverDrive processor
        if Signature.Processor_Type = 2#01#   and
          Signature.Family          = 2#0110# and
          Signature.Model           = 2#0011# then
           Type_Found := True;
           Ada.Text_IO.Put_Line ("Pentium Pro OverDrive processor");
        end if;
     
        --  If no type recognized, we have an unknown. Display what
        --  we _do_ know
        if Type_Found = False then
           Ada.Text_IO.Put_Line ("Unknown processor");
        end if;
     
        -----------------------------------------
        --  Display processor stepping level.  --
        -----------------------------------------
     
        Ada.Text_IO.Put_Line ("Stepping level:" & Signature.Stepping'Img);
     
        ---------------------------------
        --  Display vendor ID string.  --
        ---------------------------------
     
        Ada.Text_IO.Put_Line ("Vendor ID: " & Intel_CPU.Vendor_ID);
     
        ------------------------------------
        --  Get the processors features.  --
        ------------------------------------
     
        Features := Intel_CPU.Features;
     
        -----------------------------
        --  Check for a FPU unit.  --
        -----------------------------
     
        if Features.FPU = True then
           Ada.Text_IO.Put_Line ("Floating-Point unit available");
        else
           Ada.Text_IO.Put_Line ("no Floating-Point unit");
        end if;  --  check for FPU
     
        --------------------------------
        --  List processor features.  --
        --------------------------------
     
        Ada.Text_IO.Put_Line ("Supported features: ");
     
        --  Virtual Mode Extension
        if Features.VME = True then
           Ada.Text_IO.Put_Line ("    VME    - Virtual Mode Extension");
        end if;
     
        --  Debugging Extension
        if Features.DE = True then
           Ada.Text_IO.Put_Line ("    DE     - Debugging Extension");
        end if;
     
        --  Page Size Extension
        if Features.PSE = True then
           Ada.Text_IO.Put_Line ("    PSE    - Page Size Extension");
        end if;
     
        --  Time Stamp Counter
        if Features.TSC = True then
           Ada.Text_IO.Put_Line ("    TSC    - Time Stamp Counter");
        end if;
     
        --  Model Specific Registers
        if Features.MSR = True then
           Ada.Text_IO.Put_Line ("    MSR    - Model Specific Registers");
        end if;
     
        --  Physical Address Extension
        if Features.PAE = True then
           Ada.Text_IO.Put_Line ("    PAE    - Physical Address Extension");
        end if;
     
        --  Machine Check Extension
        if Features.MCE = True then
           Ada.Text_IO.Put_Line ("    MCE    - Machine Check Extension");
        end if;
     
        --  CMPXCHG8 instruction supported
        if Features.CX8 = True then
           Ada.Text_IO.Put_Line ("    CX8    - CMPXCHG8 instruction");
        end if;
     
        --  on-chip APIC hardware support
        if Features.APIC = True then
           Ada.Text_IO.Put_Line ("    APIC   - on-chip APIC hardware support");
        end if;
     
        --  Fast System Call
        if Features.SEP = True then
           Ada.Text_IO.Put_Line ("    SEP    - Fast System Call");
        end if;
     
        --  Memory Type Range Registers
        if Features.MTRR = True then
           Ada.Text_IO.Put_Line ("    MTTR   - Memory Type Range Registers");
        end if;
     
        --  Page Global Enable
        if Features.PGE = True then
           Ada.Text_IO.Put_Line ("    PGE    - Page Global Enable");
        end if;
     
        --  Machine Check Architecture
        if Features.MCA = True then
           Ada.Text_IO.Put_Line ("    MCA    - Machine Check Architecture");
        end if;
     
        --  Conditional Move Instruction Supported
        if Features.CMOV = True then
           Ada.Text_IO.Put_Line
             ("    CMOV   - Conditional Move Instruction Supported");
        end if;
     
        --  Page Attribute Table
        if Features.PAT = True then
           Ada.Text_IO.Put_Line ("    PAT    - Page Attribute Table");
        end if;
     
        --  36-bit Page Size Extension
        if Features.PSE_36 = True then
           Ada.Text_IO.Put_Line ("    PSE_36 - 36-bit Page Size Extension");
        end if;
     
        --  MMX technology supported
        if Features.MMX = True then
           Ada.Text_IO.Put_Line ("    MMX    - MMX technology supported");
        end if;
     
        --  Fast FP Save and Restore
        if Features.FXSR = True then
           Ada.Text_IO.Put_Line ("    FXSR   - Fast FP Save and Restore");
        end if;
     
        ---------------------
        --  Program done.  --
        ---------------------
     
        Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Success);
     
     exception
     
        when others =>
           Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);
           raise;
     
     end Check_CPU;