peci_cmds: add loop option
This adds an option to loop a command multiple times and report
the results.
This option allows for stress testing and performance measurements
on PECI commands.
Tested:
Confirmed that each command still works as expected and can be
looped.
Change-Id: If307bb0aec154028bf91453bfe9d091868cda587
Signed-off-by: Jason M. Bills <jason.m.bills@linux.intel.com>
diff --git a/peci_cmds.c b/peci_cmds.c
index 1e83ef0..a2f709b 100644
--- a/peci_cmds.c
+++ b/peci_cmds.c
@@ -14,7 +14,9 @@
// limitations under the License.
*/
#include <ctype.h>
+#include <errno.h>
#include <inttypes.h>
+#include <limits.h>
#include <peci.h>
#include <stdio.h>
#include <stdlib.h>
@@ -24,20 +26,28 @@
#define ABS(_v_) (((_v_) > 0) ? (_v_) : -(_v_))
#endif
+#define CC_COUNT 256 // CC is a byte so only has 256 possible values
+
extern EPECIStatus peci_GetDIB(uint8_t target, uint64_t* dib);
void Usage(char* progname)
{
printf("Usage:\n");
- printf("%s [-a <addr>] [-s <size>] <command> [parameters]\n", progname);
+ printf("%s [-h] [-v] [-a <addr>] [-s <size>] [-l <count>] <command> "
+ "[parameters]\n",
+ progname);
printf("Options:\n");
- printf("\t%-6s%s\n", "-h", "Display this help information");
- printf("\t%-6s%s\n", "-v",
+ printf("\t%-12s%s\n", "-h", "Display this help information");
+ printf("\t%-12s%s\n", "-v",
"Display additional information about the command");
- printf("\t%-6s%s\n", "-a",
+ printf("\t%-12s%s %lu\n", "-l <count>",
+ "Loop the command the given number of times. <count> is in the "
+ "range 1 to",
+ ULONG_MAX);
+ printf("\t%-12s%s\n", "-a <addr>",
"Address of the target. Accepted values are 48-55 (0x30-0x37). "
"Default is 48 (0x30)");
- printf("\t%-6s%s\n", "-s",
+ printf("\t%-12s%s\n", "-s <size>",
"Size of data to read or write in bytes. Accepted values are 1, 2, "
"4, 8, and 16. Default is 4");
printf("Commands:\n");
@@ -70,6 +80,18 @@
printf("\n");
}
+static void printLoopSummary(uint32_t* ccCounts)
+{
+ printf("Completion code counts:\n");
+ for (uint32_t i = 0; i < CC_COUNT; i++)
+ {
+ if (ccCounts[i])
+ {
+ printf(" 0x%02x: %d\n", i, ccCounts[i]);
+ }
+ }
+}
+
int main(int argc, char* argv[])
{
int c;
@@ -100,11 +122,14 @@
int index = 0;
uint8_t cc = 0;
bool verbose = false;
+ bool looped = false;
+ uint32_t loops = 1;
+ uint32_t ccCounts[CC_COUNT] = {};
//
// Parse arguments.
//
- while (-1 != (c = getopt(argc, argv, "hva:s:")))
+ while (-1 != (c = getopt(argc, argv, "hvl:a:s:")))
{
switch (c)
{
@@ -117,6 +142,20 @@
verbose = true;
break;
+ case 'l':
+ looped = true;
+ errno = 0;
+ if (optarg != NULL)
+ loops = (uint32_t)strtoul(optarg, NULL, 0);
+ if (!loops || errno)
+ {
+ printf("ERROR: Invalid loop count\n");
+ if (errno)
+ perror("");
+ goto ErrorExit;
+ }
+ break;
+
case 'a':
if (optarg != NULL)
address = (uint8_t)strtoul(optarg, NULL, 0);
@@ -174,7 +213,21 @@
{
printf("Pinging ... ");
}
- (0 == peci_Ping(address)) ? printf("Succeeded\n") : printf("Failed\n");
+ while (loops--)
+ {
+ ret = peci_Ping(address);
+ if (verbose || loops == 0)
+ {
+ if (0 != ret)
+ {
+ printf("Failed\n");
+ }
+ else
+ {
+ printf("Succeeded\n");
+ }
+ }
+ }
}
else if (strcmp(cmd, "getdib") == 0)
{
@@ -182,13 +235,21 @@
{
printf("GetDIB\n");
}
- ret = peci_GetDIB(address, &dib);
- if (0 != ret)
+ while (loops--)
{
- printf("ERROR %d: Retrieving DIB failed\n", ret);
- return 1;
+ ret = peci_GetDIB(address, &dib);
+ if (verbose || loops == 0)
+ {
+ if (0 != ret)
+ {
+ printf("ERROR %d: Retrieving DIB failed\n", ret);
+ }
+ else
+ {
+ printf(" 0x%" PRIx64 "\n", dib);
+ }
+ }
}
- printf(" 0x%" PRIx64 "\n", dib);
}
else if (strcmp(cmd, "gettemp") == 0)
@@ -197,17 +258,26 @@
{
printf("GetTemp\n");
}
- ret = peci_GetTemp(address, &temperature);
- if (0 != ret)
+ while (loops--)
{
- printf("ERROR %d: Retrieving temperature failed\n", ret);
- return 1;
+ ret = peci_GetTemp(address, &temperature);
+ if (verbose || loops == 0)
+ {
+ if (0 != ret)
+ {
+ printf("ERROR %d: Retrieving temperature failed\n", ret);
+ }
+ else
+ {
+ printf(" %04xh (%c%d.%02dC)\n",
+ (int)(unsigned int)(unsigned short)temperature,
+ (0 > temperature) ? '-' : '+',
+ (int)((unsigned int)ABS(temperature) / 64),
+ (int)(((unsigned int)ABS(temperature) % 64) * 100) /
+ 64);
+ }
+ }
}
- printf(" %04xh (%c%d.%02dC)\n",
- (int)(unsigned int)(unsigned short)temperature,
- (0 > temperature) ? '-' : '+',
- (int)((unsigned int)ABS(temperature) / 64),
- (int)(((unsigned int)ABS(temperature) % 64) * 100) / 64);
}
else if (strcmp(cmd, "rdpkgconfig") == 0)
@@ -229,15 +299,30 @@
printf("Pkg Read of Index %02x Param %04x\n", u8PkgIndex,
u16PkgParam);
}
- ret = peci_RdPkgConfig(address, u8PkgIndex, u16PkgParam, u8Size,
- (uint8_t*)&u32PkgValue, &cc);
- if (0 != ret)
+ while (loops--)
{
- printf("ERROR %d: command failed\n", ret);
- printf(" cc:0x%02x\n", cc);
- return 1;
+ ret = peci_RdPkgConfig(address, u8PkgIndex, u16PkgParam, u8Size,
+ (uint8_t*)&u32PkgValue, &cc);
+ ccCounts[cc]++;
+
+ if (verbose || loops == 0)
+ {
+ if (0 != ret)
+ {
+ printf("ERROR %d: command failed\n", ret);
+ printf(" cc:0x%02x\n", cc);
+ }
+ else
+ {
+ printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2,
+ u32PkgValue);
+ }
+ }
}
- printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2, u32PkgValue);
+ if (looped)
+ {
+ printLoopSummary(ccCounts);
+ }
}
else if (strcmp(cmd, "wrpkgconfig") == 0)
{
@@ -259,15 +344,25 @@
printf("Pkg Write of Index %02x Param %04x: 0x%0*x\n", u8PkgIndex,
u16PkgParam, u8Size * 2, u32PkgValue);
}
- ret = peci_WrPkgConfig(address, u8PkgIndex, u16PkgParam, u32PkgValue,
- u8Size, &cc);
- if (0 != ret)
+ while (loops--)
{
- printf("ERROR %d: command failed\n", ret);
- printf(" cc:0x%02x\n", cc);
- return 1;
+ ret = peci_WrPkgConfig(address, u8PkgIndex, u16PkgParam,
+ u32PkgValue, u8Size, &cc);
+ ccCounts[cc]++;
+
+ if (verbose || loops == 0)
+ {
+ if (0 != ret)
+ {
+ printf("ERROR %d: command failed\n", ret);
+ }
+ printf(" cc:0x%02x\n", cc);
+ }
}
- printf(" cc:0x%02x\n", cc);
+ if (looped)
+ {
+ printLoopSummary(ccCounts);
+ }
}
else if (strcmp(cmd, "rdiamsr") == 0)
{
@@ -288,15 +383,30 @@
printf("MSR Read of Thread %02x MSR %04x\n", u8MsrThread,
u16MsrAddr);
}
- ret = peci_RdIAMSR(address, u8MsrThread, u16MsrAddr, &u64MsrVal, &cc);
- if (0 != ret)
+ while (loops--)
{
- printf("ERROR %d: command failed\n", ret);
- printf(" cc:0x%02x\n", cc);
- return 1;
+ ret =
+ peci_RdIAMSR(address, u8MsrThread, u16MsrAddr, &u64MsrVal, &cc);
+ ccCounts[cc]++;
+
+ if (verbose || loops == 0)
+ {
+ if (0 != ret)
+ {
+ printf("ERROR %d: command failed\n", ret);
+ printf(" cc:0x%02x\n", cc);
+ }
+ else
+ {
+ printf(" cc:0x%02x 0x%0*llx\n", cc, u8Size * 2,
+ (unsigned long long)u64MsrVal);
+ }
+ }
}
- printf(" cc:0x%02x 0x%0*llx\n", cc, u8Size * 2,
- (unsigned long long)u64MsrVal);
+ if (looped)
+ {
+ printLoopSummary(ccCounts);
+ }
}
else if (strcmp(cmd, "rdpciconfig") == 0)
{
@@ -325,15 +435,30 @@
printf("PCI Read of %02x:%02x:%02x Reg %02x\n", u8PciBus, u8PciDev,
u8PciFunc, u16PciReg);
}
- ret = peci_RdPCIConfig(address, u8PciBus, u8PciDev, u8PciFunc,
- u16PciReg, (uint8_t*)&u32PciReadVal, &cc);
- if (0 != ret)
+ while (loops--)
{
- printf("ERROR %d: command failed\n", ret);
- printf(" cc:0x%02x\n", cc);
- return 1;
+ ret = peci_RdPCIConfig(address, u8PciBus, u8PciDev, u8PciFunc,
+ u16PciReg, (uint8_t*)&u32PciReadVal, &cc);
+ ccCounts[cc]++;
+
+ if (verbose || loops == 0)
+ {
+ if (0 != ret)
+ {
+ printf("ERROR %d: command failed\n", ret);
+ printf(" cc:0x%02x\n", cc);
+ }
+ else
+ {
+ printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2,
+ u32PciReadVal);
+ }
+ }
}
- printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2, u32PciReadVal);
+ if (looped)
+ {
+ printLoopSummary(ccCounts);
+ }
}
else if (strcmp(cmd, "rdpciconfiglocal") == 0)
{
@@ -362,16 +487,31 @@
printf("Local PCI Read of %02x:%02x:%02x Reg %02x\n", u8PciBus,
u8PciDev, u8PciFunc, u16PciReg);
}
- ret = peci_RdPCIConfigLocal(address, u8PciBus, u8PciDev, u8PciFunc,
- u16PciReg, u8Size, (uint8_t*)&u32PciReadVal,
- &cc);
- if (0 != ret)
+ while (loops--)
{
- printf("ERROR %d: command failed\n", ret);
- printf(" cc:0x%02x\n", cc);
- return 1;
+ ret = peci_RdPCIConfigLocal(address, u8PciBus, u8PciDev, u8PciFunc,
+ u16PciReg, u8Size,
+ (uint8_t*)&u32PciReadVal, &cc);
+ ccCounts[cc]++;
+
+ if (verbose || loops == 0)
+ {
+ if (0 != ret)
+ {
+ printf("ERROR %d: command failed\n", ret);
+ printf(" cc:0x%02x\n", cc);
+ }
+ else
+ {
+ printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2,
+ u32PciReadVal);
+ }
+ }
}
- printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2, u32PciReadVal);
+ if (looped)
+ {
+ printLoopSummary(ccCounts);
+ }
}
else if (strcmp(cmd, "wrpciconfiglocal") == 0)
{
@@ -402,15 +542,25 @@
u8PciBus, u8PciDev, u8PciFunc, u16PciReg, u8Size * 2,
u32PciWriteVal);
}
- ret = peci_WrPCIConfigLocal(address, u8PciBus, u8PciDev, u8PciFunc,
- u16PciReg, u8Size, u32PciWriteVal, &cc);
- if (0 != ret)
+ while (loops--)
{
- printf("ERROR %d: command failed\n", ret);
- printf(" cc:0x%02x\n", cc);
- return 1;
+ ret = peci_WrPCIConfigLocal(address, u8PciBus, u8PciDev, u8PciFunc,
+ u16PciReg, u8Size, u32PciWriteVal, &cc);
+ ccCounts[cc]++;
+
+ if (verbose || loops == 0)
+ {
+ if (0 != ret)
+ {
+ printf("ERROR %d: command failed\n", ret);
+ }
+ printf(" cc:0x%02x\n", cc);
+ }
}
- printf(" cc:0x%02x\n", cc);
+ if (looped)
+ {
+ printLoopSummary(ccCounts);
+ }
}
else if (strcmp(cmd, "rdendpointconfigpcilocal") == 0)
{
@@ -436,16 +586,31 @@
"Endpoint Local PCI Read of Seg:%02x %02x:%02x:%02x Reg %02x\n",
u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg);
}
- ret = peci_RdEndPointConfigPciLocal(address, u8Seg, u8PciBus, u8PciDev,
- u8PciFunc, u16PciReg, u8Size,
- (uint8_t*)&u32PciReadVal, &cc);
- if (0 != ret)
+ while (loops--)
{
- printf("ERROR %d: command failed\n", ret);
- printf(" cc:0x%02x\n", cc);
- return 1;
+ ret = peci_RdEndPointConfigPciLocal(
+ address, u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg,
+ u8Size, (uint8_t*)&u32PciReadVal, &cc);
+ ccCounts[cc]++;
+
+ if (verbose || loops == 0)
+ {
+ if (0 != ret)
+ {
+ printf("ERROR %d: command failed\n", ret);
+ printf(" cc:0x%02x\n", cc);
+ }
+ else
+ {
+ printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2,
+ u32PciReadVal);
+ }
+ }
}
- printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2, u32PciReadVal);
+ if (looped)
+ {
+ printLoopSummary(ccCounts);
+ }
}
else if (strcmp(cmd, "wrendpointconfigpcilocal") == 0)
{
@@ -473,16 +638,26 @@
u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg, u8Size * 2,
u32PciWriteVal);
}
- ret = peci_WrEndPointPCIConfigLocal(address, u8Seg, u8PciBus, u8PciDev,
- u8PciFunc, u16PciReg, u8Size,
- u32PciWriteVal, &cc);
- if (0 != ret)
+ while (loops--)
{
- printf("ERROR %d: command failed\n", ret);
- printf(" cc:0x%02x\n", cc);
- return 1;
+ ret = peci_WrEndPointPCIConfigLocal(address, u8Seg, u8PciBus,
+ u8PciDev, u8PciFunc, u16PciReg,
+ u8Size, u32PciWriteVal, &cc);
+ ccCounts[cc]++;
+
+ if (verbose || loops == 0)
+ {
+ if (0 != ret)
+ {
+ printf("ERROR %d: command failed\n", ret);
+ }
+ printf(" cc:0x%02x\n", cc);
+ }
}
- printf(" cc:0x%02x\n", cc);
+ if (looped)
+ {
+ printLoopSummary(ccCounts);
+ }
}
else if (strcmp(cmd, "rdendpointconfigpci") == 0)
{
@@ -506,16 +681,31 @@
printf("Endpoint PCI Read of Seg:%02x %02x:%02x:%02x Reg %02x\n",
u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg);
}
- ret = peci_RdEndPointConfigPci(address, u8Seg, u8PciBus, u8PciDev,
- u8PciFunc, u16PciReg, u8Size,
- (uint8_t*)&u32PciReadVal, &cc);
- if (0 != ret)
+ while (loops--)
{
- printf("ERROR %d: command failed\n", ret);
- printf(" cc:0x%02x\n", cc);
- return 1;
+ ret = peci_RdEndPointConfigPci(address, u8Seg, u8PciBus, u8PciDev,
+ u8PciFunc, u16PciReg, u8Size,
+ (uint8_t*)&u32PciReadVal, &cc);
+ ccCounts[cc]++;
+
+ if (verbose || loops == 0)
+ {
+ if (0 != ret)
+ {
+ printf("ERROR %d: command failed\n", ret);
+ printf(" cc:0x%02x\n", cc);
+ }
+ else
+ {
+ printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2,
+ u32PciReadVal);
+ }
+ }
}
- printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2, u32PciReadVal);
+ if (looped)
+ {
+ printLoopSummary(ccCounts);
+ }
}
else if (strcmp(cmd, "wrendpointconfigpci") == 0)
{
@@ -542,16 +732,26 @@
u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg, u8Size * 2,
u32PciWriteVal);
}
- ret = peci_WrEndPointPCIConfig(address, u8Seg, u8PciBus, u8PciDev,
- u8PciFunc, u16PciReg, u8Size,
- u32PciWriteVal, &cc);
- if (0 != ret)
+ while (loops--)
{
- printf("ERROR %d: command failed\n", ret);
- printf(" cc:0x%02x\n", cc);
- return 1;
+ ret = peci_WrEndPointPCIConfig(address, u8Seg, u8PciBus, u8PciDev,
+ u8PciFunc, u16PciReg, u8Size,
+ u32PciWriteVal, &cc);
+ ccCounts[cc]++;
+
+ if (verbose || loops == 0)
+ {
+ if (0 != ret)
+ {
+ printf("ERROR %d: command failed\n", ret);
+ }
+ printf(" cc:0x%02x\n", cc);
+ }
}
- printf(" cc:0x%02x\n", cc);
+ if (looped)
+ {
+ printLoopSummary(ccCounts);
+ }
}
else if (strcmp(cmd, "rdendpointconfigmmio") == 0)
{
@@ -579,16 +779,31 @@
u8Seg, u8PciBus, u8PciDev, u8PciFunc, u8AddrType, u8Bar,
u64Offset);
}
- ret = peci_RdEndPointConfigMmio(address, u8Seg, u8PciBus, u8PciDev,
- u8PciFunc, u8Bar, u8AddrType, u64Offset,
- u8Size, (uint8_t*)&u32PciReadVal, &cc);
- if (0 != ret)
+ while (loops--)
{
- printf("ERROR %d: command failed\n", ret);
- printf(" cc:0x%02x\n", cc);
- return 1;
+ ret = peci_RdEndPointConfigMmio(
+ address, u8Seg, u8PciBus, u8PciDev, u8PciFunc, u8Bar,
+ u8AddrType, u64Offset, u8Size, (uint8_t*)&u32PciReadVal, &cc);
+ ccCounts[cc]++;
+
+ if (verbose || loops == 0)
+ {
+ if (0 != ret)
+ {
+ printf("ERROR %d: command failed\n", ret);
+ printf(" cc:0x%02x\n", cc);
+ }
+ else
+ {
+ printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2,
+ u32PciReadVal);
+ }
+ }
}
- printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2, u32PciReadVal);
+ if (looped)
+ {
+ printLoopSummary(ccCounts);
+ }
}
else if (strcmp(cmd, "wrendpointconfigmmio") == 0)
{
@@ -618,16 +833,26 @@
u8Seg, u8PciBus, u8PciDev, u8PciFunc, u8AddrType, u8Bar,
u64Offset, u8Size * 2, u64MmioWriteVal);
}
- ret = peci_WrEndPointConfigMmio(address, u8Seg, u8PciBus, u8PciDev,
- u8PciFunc, u8Bar, u8AddrType, u64Offset,
- u8Size, u64MmioWriteVal, &cc);
- if (0 != ret)
+ while (loops--)
{
- printf("ERROR %d: command failed\n", ret);
- printf(" cc:0x%02x\n", cc);
- return 1;
+ ret = peci_WrEndPointConfigMmio(
+ address, u8Seg, u8PciBus, u8PciDev, u8PciFunc, u8Bar,
+ u8AddrType, u64Offset, u8Size, u64MmioWriteVal, &cc);
+ ccCounts[cc]++;
+
+ if (verbose || loops == 0)
+ {
+ if (0 != ret)
+ {
+ printf("ERROR %d: command failed\n", ret);
+ }
+ printf(" cc:0x%02x\n", cc);
+ }
}
- printf(" cc:0x%02x\n", cc);
+ if (looped)
+ {
+ printLoopSummary(ccCounts);
+ }
}
else if (strcmp(cmd, "raw") == 0)
{
@@ -680,30 +905,39 @@
free(rawCmd);
return 1;
}
- ret = peci_raw(rawAddr, readLength, rawCmd, writeLength, rawResp,
- readLength);
- if (verbose)
+ while (loops--)
{
- printf("Raw response: ");
+ ret = peci_raw(rawAddr, readLength, rawCmd, writeLength, rawResp,
+ readLength);
+ if (verbose)
+ {
+ printf(" ");
+ for (i = 0; i < readLength; i++)
+ {
+ printf("0x%02x ", rawResp[i]);
+ }
+ printf("\n");
+ }
+ ccCounts[rawResp[0]]++;
+ }
+ if (!verbose)
+ {
+ if (0 != ret)
+ {
+ printf("ERROR %d: command failed\n", ret);
+ }
+ printf(" ");
for (i = 0; i < readLength; i++)
{
printf("0x%02x ", rawResp[i]);
}
printf("\n");
}
- if (0 != ret)
+
+ if (looped)
{
- printf("ERROR %d: command failed\n", ret);
- free(rawCmd);
- free(rawResp);
- return 1;
+ printLoopSummary(ccCounts);
}
- printf(" ");
- for (i = 0; i < readLength; i++)
- {
- printf("0x%02x ", rawResp[i]);
- }
- printf("\n");
free(rawCmd);
free(rawResp);