My investigation of hardware P-states. ACPI adventure

Discussion in 'Operating Systems' started by mbk1969, Feb 20, 2020.

  1. mbk1969

    mbk1969 Ancient Guru

    Messages:
    11,146
    Likes Received:
    8,666
    GPU:
    GF RTX 2070 Super
    Adventure started this weekend - I assembled new home rig. New hardware, firmware, new features to explore and use.
    Browsing the BIOS setup I noticed Intel SpeedShift (aka SST) setting with description like "Enabling will expose the CPPC v2 interface to allow for hardware controlled P-states". I went to read the internet about that CPPC interface and hardware P-states. And what I found sounds like the mode controlled by the Windows power plan setting "Processor performance autonomous mode" - controls whether autonomous mode is enabled on systems that implement version 2 of the CPPC interface, and determines whether desired performance requests should be provided to the platform.
    I launched HWiNFO app and went to power plan settings - to experiment. To my confusion I discovered that when SST is enabled in BIOS I can`t switch autonomous mode 'on'/'off' and all power plan settings related to P-states are ignored. It was time to dive deeper, so I went to ACPI specifications. I downloaded latest ACPI specification and found there:
    These 3 elements of _CPC package
    • AutonomousSelectionEnable (Integer or Buffer, Optional). If supported, contains a resource descriptor with a single Register() descriptor that describes a register to which OSPM writes a One to enable autonomous performance level selection. Platforms that exclusively support Autonomous Selection must populate this field as an Integer with a value of 1.
    • AutonomousActivityWindowRegister (Buffer, Optional). If supported, contains a resource descriptor with a single Register() descriptor that describes a register to which OSPM writes a time value that indicates a moving utilization sensitivity window for the autonomous selection policy.
    • EnergyPerformancePreferenceRegister (Buffer, Optional). If supported, contains a resource descriptor with a single Register() descriptor that describes a register to which OSPM writes a value to control the Energy vs. Performance preference of the platform's energy efficiency and performance optimization policies when Autonomous Selection is enabled.
    sounds exactly like these power plan settings:
    • Processor performance autonomous mode - controls whether autonomous mode is enabled on systems that implement version 2 of the CPPC interface, and determines whether desired performance requests should be provided to the platform.
    • Processor autonomous activity window - specifies the value to program in the autonomous activity window register on systems that implement version 2 of the CPPC interface and have autonomous mode enabled. Longer values indicate to the platform that it should be less sensitive to short duration spikes/dips in processor utilization.
    • Processor energy performance preference policy - specifies the value to program in the energy performance preference register on systems that implement version 2 of the CPPC interface.
    So now I need to read that ACPI info from ACPI firmware and to interpret that info. I found complete set of ACPI tools here https://www.acpica.org/downloads/binary-tools

    Step 1. Read ACPI information from firmware.
    Code:
    AcpiDump > apci_dump.txt
    - this command will create text file with ACPI dump (in hexadecimal ASCII format).

    Step 2. Convert dump to binary ACPI format.
    Code:
    AcpiXtract  -a apci_dump.txt
    - that command will create many dat-files - one per each ACPI table dumped into text file.

    Step 3. Disassemble binary dat-files to ACPI source language.
    Code:
    iasl -d *.dat
    - that command will disassemble each dat-file into dsl-file.

    Step 4. Browse dsl-files for _CPC packages.
    I found them in oem2.dsl file - meaning that ACPI table was named "oem2". Here is definition of one package (with "CPCP" name - "CPC Package" I guess):
    Code:
    Name (CPCP, Package (0x15)
            {
                0x15,
                0x02,
                ResourceTemplate ()
                {
                    Register (FFixedHW,
                        0x08,               // Bit Width
                        0x00,               // Bit Offset
                        0x0000000000000771, // Address
                        0x04,               // Access Size
                        )
                },
                0x00000021,
                ResourceTemplate ()
                {
                    Register (FFixedHW,
                        0x08,               // Bit Width
                        0x10,               // Bit Offset
                        0x0000000000000771, // Address
                        0x04,               // Access Size
                        )
                },
                ResourceTemplate ()
                {
                    Register (FFixedHW,
                        0x08,               // Bit Width
                        0x18,               // Bit Offset
                        0x0000000000000771, // Address
                        0x04,               // Access Size
                        )
                },
                ResourceTemplate ()
                {
                    Register (FFixedHW,
                        0x08,               // Bit Width
                        0x08,               // Bit Offset
                        0x0000000000000771, // Address
                        0x04,               // Access Size
                        )
                },
                ResourceTemplate ()
                {
                    Register (FFixedHW,
                        0x08,               // Bit Width
                        0x10,               // Bit Offset
                        0x0000000000000774, // Address
                        0x04,               // Access Size
                        )
                },
                ResourceTemplate ()
                {
                    Register (FFixedHW,
                        0x08,               // Bit Width
                        0x00,               // Bit Offset
                        0x0000000000000774, // Address
                        0x04,               // Access Size
                        )
                },
                ResourceTemplate ()
                {
                    Register (FFixedHW,
                        0x08,               // Bit Width
                        0x08,               // Bit Offset
                        0x0000000000000774, // Address
                        0x04,               // Access Size
                        )
                },
                ResourceTemplate ()
                {
                    Register (SystemMemory,
                        0x00,               // Bit Width
                        0x00,               // Bit Offset
                        0x0000000000000000, // Address
                        ,)
                },
                ResourceTemplate ()
                {
                    Register (SystemMemory,
                        0x00,               // Bit Width
                        0x00,               // Bit Offset
                        0x0000000000000000, // Address
                        ,)
                },
                ResourceTemplate ()
                {
                    Register (SystemMemory,
                        0x00,               // Bit Width
                        0x00,               // Bit Offset
                        0x0000000000000000, // Address
                        ,)
                },
                ResourceTemplate ()
                {
                    Register (FFixedHW,
                        0x40,               // Bit Width
                        0x00,               // Bit Offset
                        0x00000000000000E7, // Address
                        0x04,               // Access Size
                        )
                },
                ResourceTemplate ()
                {
                    Register (FFixedHW,
                        0x40,               // Bit Width
                        0x00,               // Bit Offset
                        0x00000000000000E8, // Address
                        0x04,               // Access Size
                        )
                },
                ResourceTemplate ()
                {
                    Register (FFixedHW,
                        0x01,               // Bit Width
                        0x02,               // Bit Offset
                        0x0000000000000777, // Address
                        0x04,               // Access Size
                        )
                },
                ResourceTemplate ()
                {
                    Register (FFixedHW,
                        0x01,               // Bit Width
                        0x00,               // Bit Offset
                        0x0000000000000770, // Address
                        0x04,               // Access Size
                        )
                },
                0x01,
                ResourceTemplate ()
                {
                    Register (FFixedHW,
                        0x0A,               // Bit Width
                        0x20,               // Bit Offset
                        0x0000000000000774, // Address
                        0x04,               // Access Size
                        )
                },
                ResourceTemplate ()
                {
                    Register (FFixedHW,
                        0x08,               // Bit Width
                        0x18,               // Bit Offset
                        0x0000000000000774, // Address
                        0x04,               // Access Size
                        )
                },
                ResourceTemplate ()
                {
                    Register (SystemMemory,
                        0x00,               // Bit Width
                        0x00,               // Bit Offset
                        0x0000000000000000, // Address
                        ,)
                }
            })
    

    After I noticed some difference with ACPI spec for the first element:
    NumEntries value in my case is 0x15 = 21, and package is shorter in two elements comparing to the 6.3 spec. After I downloaded several previous ACPI specifications, I found in 6.1 spec:
    So my rig firmware utilises ACPI 6.1.
    And after checking every element in the package I see that AutonomousSelectionEnable=0x01 - so I can`t switch autonomous mode on the fly, only statically in BIOS.
    Also I see some of the features are not implemented - "ResourceTemplate() {Register {(SystemMemory, 0, 0, 0, 0)}}".


    You can check the capabilities stored in ACPI tables in your rigs, regardless of CPU manufacturer because ACPI is an abstraction layer.

    PS ACPI specs https://uefi.org/specifications
     
    akbaar and fantaskarsef like this.
  2. EdKiefer

    EdKiefer Ancient Guru

    Messages:
    2,697
    Likes Received:
    283
    GPU:
    MSI 970 Gaming 4G
    Nice, so this CPPC v2 feature sets performance and P stats according to HW instead of OS, I guess this would be faster, less latency if HW does it?

    What CPU/MB are you running tests on?
     
  3. mbk1969

    mbk1969 Ancient Guru

    Messages:
    11,146
    Likes Received:
    8,666
    GPU:
    GF RTX 2070 Super
    https://www.anandtech.com/show/9582/intel-skylake-mobile-desktop-launch-architecture-analysis/7
    https://www.anandtech.com/show/9751/examining-intel-skylake-speed-shift-more-responsive-processors


    I am running x299 motherboard with SkyLake-X CPU. But that technology is implemented since SkyLake CPUs.
    And the same CPPC is implemented in AMD CPUs, as I take it.
     
  4. empleat

    empleat Member

    Messages:
    34
    Likes Received:
    0
    GPU:
    geforce 780
    Interesting, I completed step 1. successfully, but when I do step 2. I get this message:

    Code:
    Intel ACPI Component Architecture
    ACPI Binary Table Extraction Utility version 20210105
    Copyright (c) 2000 - 2021 Intel Corporation
    
    Found non-ascii char: FF at file offset 0 (0x0)
    File appears to be binary (contains non-text or non-ascii characters)
    
    There are no .dat files created, nor any .txt files...
     

  5. mbk1969

    mbk1969 Ancient Guru

    Messages:
    11,146
    Likes Received:
    8,666
    GPU:
    GF RTX 2070 Super
    Which confuses me because first successful step should create txt-file.

    PS

    Try to launch program AcpiDump without redirecting its output to txt-file
     
  6. empleat

    empleat Member

    Messages:
    34
    Likes Received:
    0
    GPU:
    geforce 780
    Yeah it was meant at step 2. as you said: it will create some .dat files and - one per each ACPI table dumped into text file. So I assumed there will be also .txt files created.

    But if I make no txt, from which file I xtract ACPI information?

    AcpiDump alone doesn't work. And I don't know if saving it to a variable would work. Or how to xtract it from it! I don't see any options for that here. https://manpages.ubuntu.com/manpages/precise/man1/acpixtract.1.html
     

Share This Page