/// <summary>
 /// Send Raw PECI request to power cap CPU.
 /// </summary>
 internal SendRawPeciRequest(PeciTargetCpu Cpu, MsrTargetPowerLimit powerlimit, ushort watts, byte correctionTime)
 {
     this.peciAddress = (byte)Cpu;                                        // PECI Client Address and interface selection
     this.writeLenght = 0x0A;                                             // Write Length (part of PECI standard header)
     this.readLenght  = 0x01;                                             // Read Length (part of PECI standard header)
     this.peciCommand = GetMsrPayload(powerlimit, watts, correctionTime); // PECI Payload.
 }
 /// <summary>
 /// Send Raw PECI request to power cap CPU.
 /// </summary>
 internal SendRawPeciRequest(PeciTargetCpu Cpu, MsrTargetPowerLimit powerlimit, ushort watts, byte correctionTime)
 {
     this.peciAddress = (byte)Cpu; // PECI Client Address and interface selection
     this.writeLenght = 0x0A;      // Write Length (part of PECI standard header)
     this.readLenght = 0x01;       // Read Length (part of PECI standard header)
     this.peciCommand = GetMsrPayload(powerlimit, watts, correctionTime); // PECI Payload.
 }
        /// <summary>
        /// Returns the PECI Power Load for MSR Power Capping
        /// </summary>
        /// <param name="targetLimit">Power Limit number</param>
        /// <param name="watts">Power Limit value</param>
        /// <param name="correctionTime">Time Window</param>
        private byte[] GetMsrPayload(MsrTargetPowerLimit targetLimit, ushort watts, byte correctionTime)
        {
            byte lockval = 0x7F;

            byte[] PeciPayload = new byte[9];

            PeciPayload[0] = 0xA5;              // codes understood by Intel ME FW
            PeciPayload[1] = 0x00;              // only domain zero supported.
            PeciPayload[2] = (byte)targetLimit; // target limit (PL1 or PL2)
            PeciPayload[3] = 0x00;
            PeciPayload[4] = 0x00;

            Buffer.BlockCopy(PowerLimitMsr(watts, correctionTime), 0, PeciPayload, 5, 4);

            if (targetLimit == MsrTargetPowerLimit.PowerLimt2)
            {
                PeciPayload[8] = (byte)(PeciPayload[8] & lockval);
            }

            return(PeciPayload);
        }
        /// <summary>
        /// Returns the PECI Power Load for MSR Power Capping
        /// </summary>
        /// <param name="targetLimit">Power Limit number</param>
        /// <param name="watts">Power Limit value</param>
        /// <param name="correctionTime">Time Window</param>
        private byte[] GetMsrPayload(MsrTargetPowerLimit targetLimit, ushort watts, byte correctionTime)
        {
            byte lockval = 0x7F;

            byte[] PeciPayload = new byte[9];

            PeciPayload[0] = 0xA5; // codes understood by Intel ME FW
            PeciPayload[1] = 0x00; // only domain zero supported.
            PeciPayload[2] = (byte)targetLimit; // target limit (PL1 or PL2)
            PeciPayload[3] = 0x00;
            PeciPayload[4] = 0x00;

            Buffer.BlockCopy(PowerLimitMsr(watts, correctionTime), 0, PeciPayload, 5, 4);

            if (targetLimit == MsrTargetPowerLimit.PowerLimt2)
                PeciPayload[8] = (byte)(PeciPayload[8] & lockval);

            return PeciPayload;
        }