blob: 797d2b1071218f2300e0254eca70232e07f850fb [file] [log] [blame]
Jason M. Bills7ef5a552020-04-06 14:58:44 -07001/*
2// Copyright (c) 2019 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#include <ctype.h>
Jason M. Billsff44e542021-04-05 08:11:52 -070017#include <errno.h>
Jason M. Bills7ef5a552020-04-06 14:58:44 -070018#include <inttypes.h>
Jason M. Billsff44e542021-04-05 08:11:52 -070019#include <limits.h>
Jason M. Bills7ef5a552020-04-06 14:58:44 -070020#include <peci.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <unistd.h>
25#ifndef ABS
26#define ABS(_v_) (((_v_) > 0) ? (_v_) : -(_v_))
27#endif
28
Jason M. Billsff44e542021-04-05 08:11:52 -070029#define CC_COUNT 256 // CC is a byte so only has 256 possible values
30
Jason M. Bills7ef5a552020-04-06 14:58:44 -070031extern EPECIStatus peci_GetDIB(uint8_t target, uint64_t* dib);
32
33void Usage(char* progname)
34{
35 printf("Usage:\n");
Jason M. Bills7b112802022-03-01 13:28:56 -080036 printf("%s [-h] [-v] [-a <addr>] [-i <domain id>] [-s <size>] [-l <count>] "
37 "<command> [parameters]\n",
Jason M. Billsff44e542021-04-05 08:11:52 -070038 progname);
Jason M. Bills7ef5a552020-04-06 14:58:44 -070039 printf("Options:\n");
Jason M. Billsff44e542021-04-05 08:11:52 -070040 printf("\t%-12s%s\n", "-h", "Display this help information");
41 printf("\t%-12s%s\n", "-v",
Jason M. Bills7ef5a552020-04-06 14:58:44 -070042 "Display additional information about the command");
Jason M. Billsff44e542021-04-05 08:11:52 -070043 printf("\t%-12s%s %lu\n", "-l <count>",
44 "Loop the command the given number of times. <count> is in the "
45 "range 1 to",
46 ULONG_MAX);
47 printf("\t%-12s%s\n", "-a <addr>",
Jason M. Bills7ef5a552020-04-06 14:58:44 -070048 "Address of the target. Accepted values are 48-55 (0x30-0x37). "
49 "Default is 48 (0x30)");
Jason M. Bills7b112802022-03-01 13:28:56 -080050 printf("\t%-12s%s\n", "-i <domain id>",
51 "Domain ID of the target. Accepted values are 0-127. Default is 0");
Jason M. Billsff44e542021-04-05 08:11:52 -070052 printf("\t%-12s%s\n", "-s <size>",
Jason M. Bills7ef5a552020-04-06 14:58:44 -070053 "Size of data to read or write in bytes. Accepted values are 1, 2, "
54 "4, 8, and 16. Default is 4");
Anna Platash03d7dae2021-02-05 13:52:05 +010055 printf("\t%-12s%s\n", "-d",
56 "Set PECI device name, for example \"-d /dev/peci-0\"");
Jason M. Bills7ef5a552020-04-06 14:58:44 -070057 printf("Commands:\n");
58 printf("\t%-28s%s\n", "Ping", "Ping the target");
59 printf("\t%-28s%s\n", "GetTemp", "Get the temperature");
60 printf("\t%-28s%s\n", "GetDIB", "Get the DIB");
61 printf("\t%-28s%s\n", "RdPkgConfig",
62 "Read Package Config <Index Parameter>");
63 printf("\t%-28s%s\n", "WrPkgConfig",
64 "Write Package Config <Index Parameter Data>");
65 printf("\t%-28s%s\n", "RdIAMSR", "MSR Read <Thread Address>");
66 printf("\t%-28s%s\n", "RdPCIConfig", "PCI Read <Bus Dev Func [Reg]>");
67 printf("\t%-28s%s\n", "RdPCIConfigLocal",
68 "Local PCI Read <Bus Dev Func [Reg]>");
69 printf("\t%-28s%s\n", "WrPCIConfigLocal",
70 "Local PCI Write <Bus Dev Func Reg Data>");
71 printf("\t%-28s%s\n", "RdEndpointConfigPCILocal",
72 "Endpoint Local PCI Config Read <Seg Bus Dev Func Reg>");
73 printf("\t%-28s%s\n", "WrEndpointConfigPCILocal",
74 "Endpoint Local PCI Config Write <Seg Bus Dev Func Reg Data>");
75 printf("\t%-28s%s\n", "RdEndpointConfigPCI",
76 "Endpoint PCI Config Read <Seg Bus Dev Func Reg>");
77 printf("\t%-28s%s\n", "WrEndpointConfigPCI",
78 "Endpoint PCI Config Write <Seg Bus Dev Func Reg Data>");
79 printf("\t%-28s%s\n", "RdEndpointConfigMMIO",
80 "Endpoint MMIO Read <AType Bar Seg Bus Dev Func Reg>");
81 printf("\t%-28s%s\n", "WrEndpointConfigMMIO",
82 "Endpoint MMIO Write <AType Bar Seg Bus Dev Func Reg Data>");
83 printf("\t%-28s%s\n", "raw", "Raw PECI command in bytes");
84 printf("\n");
85}
86
Jason M. Billsff44e542021-04-05 08:11:52 -070087static void printLoopSummary(uint32_t* ccCounts)
88{
89 printf("Completion code counts:\n");
90 for (uint32_t i = 0; i < CC_COUNT; i++)
91 {
92 if (ccCounts[i])
93 {
94 printf(" 0x%02x: %d\n", i, ccCounts[i]);
95 }
96 }
97}
98
Jason M. Bills7ef5a552020-04-06 14:58:44 -070099int main(int argc, char* argv[])
100{
101 int c;
102 int i = 0;
103 char* cmd = NULL;
104 EPECIStatus ret;
105 uint8_t address = 0x30; // use default address of 48d
Jason M. Bills7b112802022-03-01 13:28:56 -0800106 uint8_t domainId = 0; // use default domain ID of 0
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700107 uint8_t u8Size = 4; // default to a DWORD
108 uint32_t u32PciReadVal = 0;
109 uint8_t u8Seg = 0;
110 uint8_t u8Bar = 0;
111 uint8_t u8AddrType = 0;
112 uint8_t u8PciBus = 0;
113 uint8_t u8PciDev = 0;
114 uint8_t u8PciFunc = 0;
115 uint16_t u16PciReg = 0;
116 uint64_t u64Offset = 0;
117 uint32_t u32PciWriteVal = 0;
118 uint64_t u64MmioWriteVal = 0;
119 uint8_t u8PkgIndex = 0;
120 uint16_t u16PkgParam = 0;
121 uint32_t u32PkgValue = 0;
122 uint8_t u8MsrThread = 0;
123 uint16_t u16MsrAddr = 0;
124 uint64_t u64MsrVal = 0;
125 short temperature;
126 uint64_t dib;
127 int index = 0;
128 uint8_t cc = 0;
129 bool verbose = false;
Jason M. Billsff44e542021-04-05 08:11:52 -0700130 bool looped = false;
131 uint32_t loops = 1;
Nirav Shahfd5dfd52022-03-09 12:29:41 -0800132 uint32_t ccCounts[CC_COUNT] = {0};
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700133
134 //
135 // Parse arguments.
136 //
Jason M. Bills7b112802022-03-01 13:28:56 -0800137 while (-1 != (c = getopt(argc, argv, "hvl:a:i:s:d:")))
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700138 {
139 switch (c)
140 {
141 case 'h':
142 Usage(argv[0]);
143 return 0;
144 break;
145
146 case 'v':
147 verbose = true;
148 break;
149
Jason M. Billsff44e542021-04-05 08:11:52 -0700150 case 'l':
151 looped = true;
152 errno = 0;
153 if (optarg != NULL)
154 loops = (uint32_t)strtoul(optarg, NULL, 0);
155 if (!loops || errno)
156 {
157 printf("ERROR: Invalid loop count\n");
158 if (errno)
159 perror("");
160 goto ErrorExit;
161 }
162 break;
163
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700164 case 'a':
165 if (optarg != NULL)
166 address = (uint8_t)strtoul(optarg, NULL, 0);
167 if (address < MIN_CLIENT_ADDR || address > MAX_CLIENT_ADDR)
168 {
169 printf("ERROR: Invalid address \"0x%x\"\n", address);
170 goto ErrorExit;
171 }
172
173 break;
174
Jason M. Bills7b112802022-03-01 13:28:56 -0800175 case 'i':
176 if (optarg != NULL)
177 domainId = (uint8_t)strtoul(optarg, NULL, 0);
178 if (domainId >= 128) // Domain ID is only 7 bits
179 {
180 printf("ERROR: Invalid domain ID \"%d\"\n", domainId);
181 goto ErrorExit;
182 }
183 break;
184
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700185 case 's':
186 if (optarg != NULL)
187 u8Size = (uint8_t)strtoul(optarg, NULL, 0);
188 if (u8Size != 1 && u8Size != 2 && u8Size != 4 && u8Size != 8 &&
189 u8Size != 16)
190 {
191 printf("ERROR: Invalid size \"%d\"\n", u8Size);
192 goto ErrorExit;
193 }
194 break;
195
Anna Platash03d7dae2021-02-05 13:52:05 +0100196 case 'd':
197 peci_SetDevName(optarg);
198 break;
199
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700200 default:
201 printf("ERROR: Unrecognized option \"-%c\"\n", optopt);
202 goto ErrorExit;
203 break;
204 }
205 }
206
207 // Get the command from the first parameter
208 cmd = argv[optind++];
209 if (cmd == NULL)
210 {
211 Usage(argv[0]);
212 return 0;
213 }
214
215 // Allow any case
216 while (cmd[i])
217 {
218 cmd[i] = (char)tolower((int)cmd[i]);
219 i++;
220 }
221
222 //
223 // Execute the command
224 //
225 if (verbose)
226 {
227 printf("PECI target[0x%x]: ", address);
228 }
229 if (strcmp(cmd, "ping") == 0)
230 {
231 if (verbose)
232 {
233 printf("Pinging ... ");
234 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700235 while (loops--)
236 {
237 ret = peci_Ping(address);
238 if (verbose || loops == 0)
239 {
240 if (0 != ret)
241 {
242 printf("Failed\n");
243 }
244 else
245 {
246 printf("Succeeded\n");
247 }
248 }
249 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700250 }
251 else if (strcmp(cmd, "getdib") == 0)
252 {
253 if (verbose)
254 {
255 printf("GetDIB\n");
256 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700257 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700258 {
Jason M. Billsff44e542021-04-05 08:11:52 -0700259 ret = peci_GetDIB(address, &dib);
260 if (verbose || loops == 0)
261 {
262 if (0 != ret)
263 {
264 printf("ERROR %d: Retrieving DIB failed\n", ret);
265 }
266 else
267 {
268 printf(" 0x%" PRIx64 "\n", dib);
269 }
270 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700271 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700272 }
273
274 else if (strcmp(cmd, "gettemp") == 0)
275 {
276 if (verbose)
277 {
278 printf("GetTemp\n");
279 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700280 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700281 {
Jason M. Billsff44e542021-04-05 08:11:52 -0700282 ret = peci_GetTemp(address, &temperature);
283 if (verbose || loops == 0)
284 {
285 if (0 != ret)
286 {
287 printf("ERROR %d: Retrieving temperature failed\n", ret);
288 }
289 else
290 {
291 printf(" %04xh (%c%d.%02dC)\n",
292 (int)(unsigned int)(unsigned short)temperature,
293 (0 > temperature) ? '-' : '+',
294 (int)((unsigned int)ABS(temperature) / 64),
295 (int)(((unsigned int)ABS(temperature) % 64) * 100) /
296 64);
297 }
298 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700299 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700300 }
301
302 else if (strcmp(cmd, "rdpkgconfig") == 0)
303 {
304 index = argc;
305 switch (argc - optind)
306 {
307 case 2:
308 u16PkgParam = (uint16_t)strtoul(argv[--index], NULL, 0);
309 u8PkgIndex = (uint8_t)strtoul(argv[--index], NULL, 0);
310 break;
311 default:
312 printf("ERROR: Unsupported arguments for Pkg Read\n");
313 goto ErrorExit;
314 break;
315 }
316 if (verbose)
317 {
318 printf("Pkg Read of Index %02x Param %04x\n", u8PkgIndex,
319 u16PkgParam);
320 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700321 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700322 {
Jason M. Bills7b112802022-03-01 13:28:56 -0800323 ret =
324 peci_RdPkgConfig_dom(address, domainId, u8PkgIndex, u16PkgParam,
325 u8Size, (uint8_t*)&u32PkgValue, &cc);
Jason M. Billsff44e542021-04-05 08:11:52 -0700326 ccCounts[cc]++;
327
328 if (verbose || loops == 0)
329 {
330 if (0 != ret)
331 {
332 printf("ERROR %d: command failed\n", ret);
333 printf(" cc:0x%02x\n", cc);
334 }
335 else
336 {
337 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2,
338 u32PkgValue);
339 }
340 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700341 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700342 if (looped)
343 {
344 printLoopSummary(ccCounts);
345 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700346 }
347 else if (strcmp(cmd, "wrpkgconfig") == 0)
348 {
349 index = argc;
350 switch (argc - optind)
351 {
352 case 3:
Jason M. Bills62cbc712020-05-07 14:07:49 -0700353 u32PkgValue = (uint32_t)strtoul(argv[--index], NULL, 0);
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700354 u16PkgParam = (uint16_t)strtoul(argv[--index], NULL, 0);
355 u8PkgIndex = (uint8_t)strtoul(argv[--index], NULL, 0);
356 break;
357 default:
358 printf("ERROR: Unsupported arguments for Pkg Write\n");
359 goto ErrorExit;
360 break;
361 }
362 if (verbose)
363 {
364 printf("Pkg Write of Index %02x Param %04x: 0x%0*x\n", u8PkgIndex,
365 u16PkgParam, u8Size * 2, u32PkgValue);
366 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700367 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700368 {
Jason M. Bills7b112802022-03-01 13:28:56 -0800369 ret = peci_WrPkgConfig_dom(address, domainId, u8PkgIndex,
370 u16PkgParam, u32PkgValue, u8Size, &cc);
Jason M. Billsff44e542021-04-05 08:11:52 -0700371 ccCounts[cc]++;
372
373 if (verbose || loops == 0)
374 {
375 if (0 != ret)
376 {
377 printf("ERROR %d: command failed\n", ret);
378 }
379 printf(" cc:0x%02x\n", cc);
380 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700381 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700382 if (looped)
383 {
384 printLoopSummary(ccCounts);
385 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700386 }
387 else if (strcmp(cmd, "rdiamsr") == 0)
388 {
389 index = argc;
390 switch (argc - optind)
391 {
392 case 2:
393 u16MsrAddr = (uint16_t)strtoul(argv[--index], NULL, 0);
394 u8MsrThread = (uint8_t)strtoul(argv[--index], NULL, 0);
395 break;
396 default:
397 printf("ERROR: Unsupported arguments for MSR Read\n");
398 goto ErrorExit;
399 break;
400 }
401 if (verbose)
402 {
403 printf("MSR Read of Thread %02x MSR %04x\n", u8MsrThread,
404 u16MsrAddr);
405 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700406 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700407 {
Jason M. Bills7b112802022-03-01 13:28:56 -0800408 ret = peci_RdIAMSR_dom(address, domainId, u8MsrThread, u16MsrAddr,
409 &u64MsrVal, &cc);
Jason M. Billsff44e542021-04-05 08:11:52 -0700410 ccCounts[cc]++;
411
412 if (verbose || loops == 0)
413 {
414 if (0 != ret)
415 {
416 printf("ERROR %d: command failed\n", ret);
417 printf(" cc:0x%02x\n", cc);
418 }
419 else
420 {
421 printf(" cc:0x%02x 0x%0*llx\n", cc, u8Size * 2,
422 (unsigned long long)u64MsrVal);
423 }
424 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700425 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700426 if (looped)
427 {
428 printLoopSummary(ccCounts);
429 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700430 }
431 else if (strcmp(cmd, "rdpciconfig") == 0)
432 {
433 index = argc;
434 switch (argc - optind)
435 {
436 case 4:
437 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
438 /* FALLTHROUGH */
439 case 3:
440 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
441 /* FALLTHROUGH */
442 case 2:
443 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
444 /* FALLTHROUGH */
445 case 1:
446 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
447 break;
448 default:
449 printf("ERROR: Unsupported arguments for PCI Read\n");
450 goto ErrorExit;
451 break;
452 }
453 if (verbose)
454 {
455 printf("PCI Read of %02x:%02x:%02x Reg %02x\n", u8PciBus, u8PciDev,
456 u8PciFunc, u16PciReg);
457 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700458 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700459 {
Jason M. Bills7b112802022-03-01 13:28:56 -0800460 ret = peci_RdPCIConfig_dom(address, domainId, u8PciBus, u8PciDev,
461 u8PciFunc, u16PciReg,
462 (uint8_t*)&u32PciReadVal, &cc);
Jason M. Billsff44e542021-04-05 08:11:52 -0700463 ccCounts[cc]++;
464
465 if (verbose || loops == 0)
466 {
467 if (0 != ret)
468 {
469 printf("ERROR %d: command failed\n", ret);
470 printf(" cc:0x%02x\n", cc);
471 }
472 else
473 {
474 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2,
475 u32PciReadVal);
476 }
477 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700478 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700479 if (looped)
480 {
481 printLoopSummary(ccCounts);
482 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700483 }
484 else if (strcmp(cmd, "rdpciconfiglocal") == 0)
485 {
486 index = argc;
487 switch (argc - optind)
488 {
489 case 4:
490 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
491 /* FALLTHROUGH */
492 case 3:
493 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
494 /* FALLTHROUGH */
495 case 2:
496 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
497 /* FALLTHROUGH */
498 case 1:
499 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
500 break;
501 default:
502 printf("ERROR: Unsupported arguments for Local PCI Read\n");
503 goto ErrorExit;
504 break;
505 }
506 if (verbose)
507 {
508 printf("Local PCI Read of %02x:%02x:%02x Reg %02x\n", u8PciBus,
509 u8PciDev, u8PciFunc, u16PciReg);
510 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700511 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700512 {
Jason M. Bills7b112802022-03-01 13:28:56 -0800513 ret = peci_RdPCIConfigLocal_dom(
514 address, domainId, u8PciBus, u8PciDev, u8PciFunc, u16PciReg,
515 u8Size, (uint8_t*)&u32PciReadVal, &cc);
Jason M. Billsff44e542021-04-05 08:11:52 -0700516 ccCounts[cc]++;
517
518 if (verbose || loops == 0)
519 {
520 if (0 != ret)
521 {
522 printf("ERROR %d: command failed\n", ret);
523 printf(" cc:0x%02x\n", cc);
524 }
525 else
526 {
527 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2,
528 u32PciReadVal);
529 }
530 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700531 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700532 if (looped)
533 {
534 printLoopSummary(ccCounts);
535 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700536 }
537 else if (strcmp(cmd, "wrpciconfiglocal") == 0)
538 {
539 index = argc;
Jason M. Bills62cbc712020-05-07 14:07:49 -0700540 u32PciWriteVal = (uint32_t)strtoul(argv[--index], NULL, 0);
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700541 switch (argc - optind)
542 {
543 case 5:
544 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
545 /* FALLTHROUGH */
546 case 4:
547 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
548 /* FALLTHROUGH */
549 case 3:
550 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
551 /* FALLTHROUGH */
552 case 2:
553 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
554 break;
555 default:
556 printf("ERROR: Unsupported arguments for Local PCI Write\n");
557 goto ErrorExit;
558 break;
559 }
560 if (verbose)
561 {
562 printf("Local PCI Write of %02x:%02x:%02x Reg %02x: 0x%0*x\n",
563 u8PciBus, u8PciDev, u8PciFunc, u16PciReg, u8Size * 2,
564 u32PciWriteVal);
565 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700566 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700567 {
Jason M. Bills7b112802022-03-01 13:28:56 -0800568 ret = peci_WrPCIConfigLocal_dom(address, domainId, u8PciBus,
569 u8PciDev, u8PciFunc, u16PciReg,
570 u8Size, u32PciWriteVal, &cc);
Jason M. Billsff44e542021-04-05 08:11:52 -0700571 ccCounts[cc]++;
572
573 if (verbose || loops == 0)
574 {
575 if (0 != ret)
576 {
577 printf("ERROR %d: command failed\n", ret);
578 }
579 printf(" cc:0x%02x\n", cc);
580 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700581 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700582 if (looped)
583 {
584 printLoopSummary(ccCounts);
585 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700586 }
587 else if (strcmp(cmd, "rdendpointconfigpcilocal") == 0)
588 {
589 index = argc;
590 switch (argc - optind)
591 {
592 case 5:
593 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
594 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
595 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
596 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
597 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
598 break;
599
600 default:
601 printf("ERROR: Unsupported arguments for Endpoint Local PCI "
602 "Read\n");
603 goto ErrorExit;
604 }
605 if (verbose)
606 {
607 printf(
608 "Endpoint Local PCI Read of Seg:%02x %02x:%02x:%02x Reg %02x\n",
609 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg);
610 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700611 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700612 {
Jason M. Bills7b112802022-03-01 13:28:56 -0800613 ret = peci_RdEndPointConfigPciLocal_dom(
614 address, domainId, u8Seg, u8PciBus, u8PciDev, u8PciFunc,
615 u16PciReg, u8Size, (uint8_t*)&u32PciReadVal, &cc);
Jason M. Billsff44e542021-04-05 08:11:52 -0700616 ccCounts[cc]++;
617
618 if (verbose || loops == 0)
619 {
620 if (0 != ret)
621 {
622 printf("ERROR %d: command failed\n", ret);
623 printf(" cc:0x%02x\n", cc);
624 }
625 else
626 {
627 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2,
628 u32PciReadVal);
629 }
630 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700631 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700632 if (looped)
633 {
634 printLoopSummary(ccCounts);
635 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700636 }
637 else if (strcmp(cmd, "wrendpointconfigpcilocal") == 0)
638 {
639 index = argc;
640 switch (argc - optind)
641 {
642 case 6:
Jason M. Bills62cbc712020-05-07 14:07:49 -0700643 u32PciWriteVal = (uint32_t)strtoul(argv[--index], NULL, 0);
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700644 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
645 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
646 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
647 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
648 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
649 break;
650
651 default:
652 printf("ERROR: Unsupported arguments for Endpoint Local PCI "
653 "Write\n");
654 goto ErrorExit;
655 }
656 if (verbose)
657 {
658 printf("Endpoint Local PCI Write of Seg:%02x %02x:%02x:%02x Reg "
659 "%02x: 0x%0*x\n",
660 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg, u8Size * 2,
661 u32PciWriteVal);
662 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700663 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700664 {
Jason M. Bills7b112802022-03-01 13:28:56 -0800665 ret = peci_WrEndPointPCIConfigLocal_dom(
666 address, domainId, u8Seg, u8PciBus, u8PciDev, u8PciFunc,
667 u16PciReg, u8Size, u32PciWriteVal, &cc);
Jason M. Billsff44e542021-04-05 08:11:52 -0700668 ccCounts[cc]++;
669
670 if (verbose || loops == 0)
671 {
672 if (0 != ret)
673 {
674 printf("ERROR %d: command failed\n", ret);
675 }
676 printf(" cc:0x%02x\n", cc);
677 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700678 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700679 if (looped)
680 {
681 printLoopSummary(ccCounts);
682 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700683 }
684 else if (strcmp(cmd, "rdendpointconfigpci") == 0)
685 {
686 index = argc;
687 switch (argc - optind)
688 {
689 case 5:
690 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
691 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
692 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
693 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
694 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
695 break;
696
697 default:
698 printf("ERROR: Unsupported arguments for Endpoint PCI Read\n");
699 goto ErrorExit;
700 }
701 if (verbose)
702 {
703 printf("Endpoint PCI Read of Seg:%02x %02x:%02x:%02x Reg %02x\n",
704 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg);
705 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700706 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700707 {
Jason M. Bills7b112802022-03-01 13:28:56 -0800708 ret = peci_RdEndPointConfigPci_dom(
709 address, domainId, u8Seg, u8PciBus, u8PciDev, u8PciFunc,
710 u16PciReg, u8Size, (uint8_t*)&u32PciReadVal, &cc);
Jason M. Billsff44e542021-04-05 08:11:52 -0700711 ccCounts[cc]++;
712
713 if (verbose || loops == 0)
714 {
715 if (0 != ret)
716 {
717 printf("ERROR %d: command failed\n", ret);
718 printf(" cc:0x%02x\n", cc);
719 }
720 else
721 {
722 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2,
723 u32PciReadVal);
724 }
725 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700726 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700727 if (looped)
728 {
729 printLoopSummary(ccCounts);
730 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700731 }
732 else if (strcmp(cmd, "wrendpointconfigpci") == 0)
733 {
734 index = argc;
735 switch (argc - optind)
736 {
737 case 6:
Jason M. Bills62cbc712020-05-07 14:07:49 -0700738 u32PciWriteVal = (uint32_t)strtoul(argv[--index], NULL, 0);
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700739 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
740 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
741 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
742 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
743 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
744 break;
745
746 default:
747 printf("ERROR: Unsupported arguments for Endpoint PCI Write\n");
748 goto ErrorExit;
749 }
750 if (verbose)
751 {
752 printf("Endpoint PCI Write of Seg:%02x %02x:%02x:%02x Reg %02x: "
753 "0x%0*x\n",
754 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg, u8Size * 2,
755 u32PciWriteVal);
756 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700757 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700758 {
Jason M. Bills7b112802022-03-01 13:28:56 -0800759 ret = peci_WrEndPointPCIConfig_dom(
760 address, domainId, u8Seg, u8PciBus, u8PciDev, u8PciFunc,
761 u16PciReg, u8Size, u32PciWriteVal, &cc);
Jason M. Billsff44e542021-04-05 08:11:52 -0700762 ccCounts[cc]++;
763
764 if (verbose || loops == 0)
765 {
766 if (0 != ret)
767 {
768 printf("ERROR %d: command failed\n", ret);
769 }
770 printf(" cc:0x%02x\n", cc);
771 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700772 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700773 if (looped)
774 {
775 printLoopSummary(ccCounts);
776 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700777 }
778 else if (strcmp(cmd, "rdendpointconfigmmio") == 0)
779 {
780 index = argc;
781 switch (argc - optind)
782 {
783 case 7:
Jason M. Bills62cbc712020-05-07 14:07:49 -0700784 u64Offset = (uint64_t)strtoull(argv[--index], NULL, 0);
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700785 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
786 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
787 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
788 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
789 u8Bar = (uint8_t)strtoul(argv[--index], NULL, 0);
790 u8AddrType = (uint8_t)strtoul(argv[--index], NULL, 0);
791 break;
792
793 default:
794 printf("ERROR: Unsupported arguments for Endpoint MMIO Read\n");
795 goto ErrorExit;
796 }
797 if (verbose)
798 {
799 printf("Endpoint MMIO Read of Seg:%02x %02x:%02x:%02x AType:%02x "
800 "Bar:%02x Offset:0x%" PRIx64 "\n",
801 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u8AddrType, u8Bar,
802 u64Offset);
803 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700804 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700805 {
Jason M. Bills7b112802022-03-01 13:28:56 -0800806 ret = peci_RdEndPointConfigMmio_dom(
807 address, domainId, u8Seg, u8PciBus, u8PciDev, u8PciFunc, u8Bar,
Jason M. Billsff44e542021-04-05 08:11:52 -0700808 u8AddrType, u64Offset, u8Size, (uint8_t*)&u32PciReadVal, &cc);
809 ccCounts[cc]++;
810
811 if (verbose || loops == 0)
812 {
813 if (0 != ret)
814 {
815 printf("ERROR %d: command failed\n", ret);
816 printf(" cc:0x%02x\n", cc);
817 }
818 else
819 {
820 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2,
821 u32PciReadVal);
822 }
823 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700824 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700825 if (looped)
826 {
827 printLoopSummary(ccCounts);
828 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700829 }
830 else if (strcmp(cmd, "wrendpointconfigmmio") == 0)
831 {
832 index = argc;
833 switch (argc - optind)
834 {
835 case 8:
Jason M. Bills62cbc712020-05-07 14:07:49 -0700836 u64MmioWriteVal = (uint64_t)strtoull(argv[--index], NULL, 0);
837 u64Offset = (uint64_t)strtoull(argv[--index], NULL, 0);
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700838 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
839 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
840 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
841 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
842 u8Bar = (uint8_t)strtoul(argv[--index], NULL, 0);
843 u8AddrType = (uint8_t)strtoul(argv[--index], NULL, 0);
844 break;
845
846 default:
847 printf(
848 "ERROR: Unsupported arguments for Endpoint MMIO Write\n");
849 goto ErrorExit;
850 }
851 if (verbose)
852 {
853 printf("Endpoint MMIO Write of Seg:%02x %02x:%02x:%02x AType:%02x "
854 "Bar:%02x Offset:0x%" PRIx64 ": 0x%0*" PRIx64 "\n",
855 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u8AddrType, u8Bar,
856 u64Offset, u8Size * 2, u64MmioWriteVal);
857 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700858 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700859 {
Jason M. Bills7b112802022-03-01 13:28:56 -0800860 ret = peci_WrEndPointConfigMmio_dom(
861 address, domainId, u8Seg, u8PciBus, u8PciDev, u8PciFunc, u8Bar,
Jason M. Billsff44e542021-04-05 08:11:52 -0700862 u8AddrType, u64Offset, u8Size, u64MmioWriteVal, &cc);
863 ccCounts[cc]++;
864
865 if (verbose || loops == 0)
866 {
867 if (0 != ret)
868 {
869 printf("ERROR %d: command failed\n", ret);
870 }
871 printf(" cc:0x%02x\n", cc);
872 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700873 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700874 if (looped)
875 {
876 printLoopSummary(ccCounts);
877 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700878 }
879 else if (strcmp(cmd, "raw") == 0)
880 {
881 if ((argc - optind) < 3)
882 {
883 printf("ERROR: Unsupported arguments for raw command\n");
884 goto ErrorExit;
885 }
886
887 // Address is provided in the first byte of the PECI command
888 uint8_t rawAddr = (uint8_t)strtoul(argv[optind++], NULL, 0);
889 // Write length is provided in the second byte of the PECI command
890 uint8_t writeLength = (uint8_t)strtoul(argv[optind++], NULL, 0);
891 // Read length is provided in the third byte of the PECI command
892 uint8_t readLength = (uint8_t)strtoul(argv[optind++], NULL, 0);
893
Jason M. Billsc965e722020-07-06 15:49:14 -0700894 // remaining parameters should fit within write length
895 if ((argc - optind) > writeLength)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700896 {
897 printf("ERROR: Incorrect write length for raw command\n");
898 goto ErrorExit;
899 }
900 uint8_t* rawCmd = (uint8_t*)calloc(writeLength, sizeof(uint8_t));
901 if (rawCmd == NULL)
902 {
903 // calloc failed, abort the sequence
904 printf("Raw command memory allocation failed\n");
905 return 1;
906 }
Jason M. Billsc965e722020-07-06 15:49:14 -0700907 for (i = 0; i < (argc - optind); i++)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700908 {
909 rawCmd[i] = (uint8_t)strtoul(argv[i + optind], NULL, 0);
910 }
911 if (verbose)
912 {
913 printf("Raw command: %02x %02x %02x ", rawAddr, writeLength,
914 readLength);
915 for (i = 0; i < writeLength; i++)
916 {
917 printf("0x%02x ", rawCmd[i]);
918 }
919 printf("\n");
920 }
921
922 uint8_t* rawResp = (uint8_t*)calloc(readLength, sizeof(uint8_t));
923 if (rawResp == NULL)
924 {
925 // calloc failed, abort the sequence
926 printf("Raw command memory allocation failed\n");
927 free(rawCmd);
928 return 1;
929 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700930 while (loops--)
Jason M. Bills0e21dde2020-07-06 14:51:53 -0700931 {
Jason M. Billsff44e542021-04-05 08:11:52 -0700932 ret = peci_raw(rawAddr, readLength, rawCmd, writeLength, rawResp,
933 readLength);
934 if (verbose)
935 {
936 printf(" ");
937 for (i = 0; i < readLength; i++)
938 {
939 printf("0x%02x ", rawResp[i]);
940 }
941 printf("\n");
942 }
943 ccCounts[rawResp[0]]++;
944 }
945 if (!verbose)
946 {
947 if (0 != ret)
948 {
949 printf("ERROR %d: command failed\n", ret);
950 }
951 printf(" ");
Jason M. Bills0e21dde2020-07-06 14:51:53 -0700952 for (i = 0; i < readLength; i++)
953 {
954 printf("0x%02x ", rawResp[i]);
955 }
956 printf("\n");
957 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700958
959 if (looped)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700960 {
Jason M. Billsff44e542021-04-05 08:11:52 -0700961 printLoopSummary(ccCounts);
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700962 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700963
964 free(rawCmd);
965 free(rawResp);
966 }
967 else
968 {
969 printf("ERROR: Unrecognized command\n");
970 goto ErrorExit;
971 }
972
973 return 0;
974
975ErrorExit:
976 Usage(argv[0]);
977 return 1;
978}