blob: 419ac783e7bc0a83f6d8b8db2fee6f37e2a88a8a [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. Billsff44e542021-04-05 08:11:52 -070036 printf("%s [-h] [-v] [-a <addr>] [-s <size>] [-l <count>] <command> "
37 "[parameters]\n",
38 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. Billsff44e542021-04-05 08:11:52 -070050 printf("\t%-12s%s\n", "-s <size>",
Jason M. Bills7ef5a552020-04-06 14:58:44 -070051 "Size of data to read or write in bytes. Accepted values are 1, 2, "
52 "4, 8, and 16. Default is 4");
Anna Platash03d7dae2021-02-05 13:52:05 +010053 printf("\t%-12s%s\n", "-d",
54 "Set PECI device name, for example \"-d /dev/peci-0\"");
Jason M. Bills7ef5a552020-04-06 14:58:44 -070055 printf("Commands:\n");
56 printf("\t%-28s%s\n", "Ping", "Ping the target");
57 printf("\t%-28s%s\n", "GetTemp", "Get the temperature");
58 printf("\t%-28s%s\n", "GetDIB", "Get the DIB");
59 printf("\t%-28s%s\n", "RdPkgConfig",
60 "Read Package Config <Index Parameter>");
61 printf("\t%-28s%s\n", "WrPkgConfig",
62 "Write Package Config <Index Parameter Data>");
63 printf("\t%-28s%s\n", "RdIAMSR", "MSR Read <Thread Address>");
64 printf("\t%-28s%s\n", "RdPCIConfig", "PCI Read <Bus Dev Func [Reg]>");
65 printf("\t%-28s%s\n", "RdPCIConfigLocal",
66 "Local PCI Read <Bus Dev Func [Reg]>");
67 printf("\t%-28s%s\n", "WrPCIConfigLocal",
68 "Local PCI Write <Bus Dev Func Reg Data>");
69 printf("\t%-28s%s\n", "RdEndpointConfigPCILocal",
70 "Endpoint Local PCI Config Read <Seg Bus Dev Func Reg>");
71 printf("\t%-28s%s\n", "WrEndpointConfigPCILocal",
72 "Endpoint Local PCI Config Write <Seg Bus Dev Func Reg Data>");
73 printf("\t%-28s%s\n", "RdEndpointConfigPCI",
74 "Endpoint PCI Config Read <Seg Bus Dev Func Reg>");
75 printf("\t%-28s%s\n", "WrEndpointConfigPCI",
76 "Endpoint PCI Config Write <Seg Bus Dev Func Reg Data>");
77 printf("\t%-28s%s\n", "RdEndpointConfigMMIO",
78 "Endpoint MMIO Read <AType Bar Seg Bus Dev Func Reg>");
79 printf("\t%-28s%s\n", "WrEndpointConfigMMIO",
80 "Endpoint MMIO Write <AType Bar Seg Bus Dev Func Reg Data>");
81 printf("\t%-28s%s\n", "raw", "Raw PECI command in bytes");
82 printf("\n");
83}
84
Jason M. Billsff44e542021-04-05 08:11:52 -070085static void printLoopSummary(uint32_t* ccCounts)
86{
87 printf("Completion code counts:\n");
88 for (uint32_t i = 0; i < CC_COUNT; i++)
89 {
90 if (ccCounts[i])
91 {
92 printf(" 0x%02x: %d\n", i, ccCounts[i]);
93 }
94 }
95}
96
Jason M. Bills7ef5a552020-04-06 14:58:44 -070097int main(int argc, char* argv[])
98{
99 int c;
100 int i = 0;
101 char* cmd = NULL;
102 EPECIStatus ret;
103 uint8_t address = 0x30; // use default address of 48d
104 uint8_t u8Size = 4; // default to a DWORD
105 uint32_t u32PciReadVal = 0;
106 uint8_t u8Seg = 0;
107 uint8_t u8Bar = 0;
108 uint8_t u8AddrType = 0;
109 uint8_t u8PciBus = 0;
110 uint8_t u8PciDev = 0;
111 uint8_t u8PciFunc = 0;
112 uint16_t u16PciReg = 0;
113 uint64_t u64Offset = 0;
114 uint32_t u32PciWriteVal = 0;
115 uint64_t u64MmioWriteVal = 0;
116 uint8_t u8PkgIndex = 0;
117 uint16_t u16PkgParam = 0;
118 uint32_t u32PkgValue = 0;
119 uint8_t u8MsrThread = 0;
120 uint16_t u16MsrAddr = 0;
121 uint64_t u64MsrVal = 0;
122 short temperature;
123 uint64_t dib;
124 int index = 0;
125 uint8_t cc = 0;
126 bool verbose = false;
Jason M. Billsff44e542021-04-05 08:11:52 -0700127 bool looped = false;
128 uint32_t loops = 1;
Nirav Shahfd5dfd52022-03-09 12:29:41 -0800129 uint32_t ccCounts[CC_COUNT] = {0};
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700130
131 //
132 // Parse arguments.
133 //
Anna Platash03d7dae2021-02-05 13:52:05 +0100134 while (-1 != (c = getopt(argc, argv, "hvl:a:s:d:")))
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700135 {
136 switch (c)
137 {
138 case 'h':
139 Usage(argv[0]);
140 return 0;
141 break;
142
143 case 'v':
144 verbose = true;
145 break;
146
Jason M. Billsff44e542021-04-05 08:11:52 -0700147 case 'l':
148 looped = true;
149 errno = 0;
150 if (optarg != NULL)
151 loops = (uint32_t)strtoul(optarg, NULL, 0);
152 if (!loops || errno)
153 {
154 printf("ERROR: Invalid loop count\n");
155 if (errno)
156 perror("");
157 goto ErrorExit;
158 }
159 break;
160
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700161 case 'a':
162 if (optarg != NULL)
163 address = (uint8_t)strtoul(optarg, NULL, 0);
164 if (address < MIN_CLIENT_ADDR || address > MAX_CLIENT_ADDR)
165 {
166 printf("ERROR: Invalid address \"0x%x\"\n", address);
167 goto ErrorExit;
168 }
169
170 break;
171
172 case 's':
173 if (optarg != NULL)
174 u8Size = (uint8_t)strtoul(optarg, NULL, 0);
175 if (u8Size != 1 && u8Size != 2 && u8Size != 4 && u8Size != 8 &&
176 u8Size != 16)
177 {
178 printf("ERROR: Invalid size \"%d\"\n", u8Size);
179 goto ErrorExit;
180 }
181 break;
182
Anna Platash03d7dae2021-02-05 13:52:05 +0100183 case 'd':
184 peci_SetDevName(optarg);
185 break;
186
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700187 default:
188 printf("ERROR: Unrecognized option \"-%c\"\n", optopt);
189 goto ErrorExit;
190 break;
191 }
192 }
193
194 // Get the command from the first parameter
195 cmd = argv[optind++];
196 if (cmd == NULL)
197 {
198 Usage(argv[0]);
199 return 0;
200 }
201
202 // Allow any case
203 while (cmd[i])
204 {
205 cmd[i] = (char)tolower((int)cmd[i]);
206 i++;
207 }
208
209 //
210 // Execute the command
211 //
212 if (verbose)
213 {
214 printf("PECI target[0x%x]: ", address);
215 }
216 if (strcmp(cmd, "ping") == 0)
217 {
218 if (verbose)
219 {
220 printf("Pinging ... ");
221 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700222 while (loops--)
223 {
224 ret = peci_Ping(address);
225 if (verbose || loops == 0)
226 {
227 if (0 != ret)
228 {
229 printf("Failed\n");
230 }
231 else
232 {
233 printf("Succeeded\n");
234 }
235 }
236 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700237 }
238 else if (strcmp(cmd, "getdib") == 0)
239 {
240 if (verbose)
241 {
242 printf("GetDIB\n");
243 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700244 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700245 {
Jason M. Billsff44e542021-04-05 08:11:52 -0700246 ret = peci_GetDIB(address, &dib);
247 if (verbose || loops == 0)
248 {
249 if (0 != ret)
250 {
251 printf("ERROR %d: Retrieving DIB failed\n", ret);
252 }
253 else
254 {
255 printf(" 0x%" PRIx64 "\n", dib);
256 }
257 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700258 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700259 }
260
261 else if (strcmp(cmd, "gettemp") == 0)
262 {
263 if (verbose)
264 {
265 printf("GetTemp\n");
266 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700267 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700268 {
Jason M. Billsff44e542021-04-05 08:11:52 -0700269 ret = peci_GetTemp(address, &temperature);
270 if (verbose || loops == 0)
271 {
272 if (0 != ret)
273 {
274 printf("ERROR %d: Retrieving temperature failed\n", ret);
275 }
276 else
277 {
278 printf(" %04xh (%c%d.%02dC)\n",
279 (int)(unsigned int)(unsigned short)temperature,
280 (0 > temperature) ? '-' : '+',
281 (int)((unsigned int)ABS(temperature) / 64),
282 (int)(((unsigned int)ABS(temperature) % 64) * 100) /
283 64);
284 }
285 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700286 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700287 }
288
289 else if (strcmp(cmd, "rdpkgconfig") == 0)
290 {
291 index = argc;
292 switch (argc - optind)
293 {
294 case 2:
295 u16PkgParam = (uint16_t)strtoul(argv[--index], NULL, 0);
296 u8PkgIndex = (uint8_t)strtoul(argv[--index], NULL, 0);
297 break;
298 default:
299 printf("ERROR: Unsupported arguments for Pkg Read\n");
300 goto ErrorExit;
301 break;
302 }
303 if (verbose)
304 {
305 printf("Pkg Read of Index %02x Param %04x\n", u8PkgIndex,
306 u16PkgParam);
307 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700308 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700309 {
Jason M. Billsff44e542021-04-05 08:11:52 -0700310 ret = peci_RdPkgConfig(address, u8PkgIndex, u16PkgParam, u8Size,
311 (uint8_t*)&u32PkgValue, &cc);
312 ccCounts[cc]++;
313
314 if (verbose || loops == 0)
315 {
316 if (0 != ret)
317 {
318 printf("ERROR %d: command failed\n", ret);
319 printf(" cc:0x%02x\n", cc);
320 }
321 else
322 {
323 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2,
324 u32PkgValue);
325 }
326 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700327 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700328 if (looped)
329 {
330 printLoopSummary(ccCounts);
331 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700332 }
333 else if (strcmp(cmd, "wrpkgconfig") == 0)
334 {
335 index = argc;
336 switch (argc - optind)
337 {
338 case 3:
Jason M. Bills62cbc712020-05-07 14:07:49 -0700339 u32PkgValue = (uint32_t)strtoul(argv[--index], NULL, 0);
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700340 u16PkgParam = (uint16_t)strtoul(argv[--index], NULL, 0);
341 u8PkgIndex = (uint8_t)strtoul(argv[--index], NULL, 0);
342 break;
343 default:
344 printf("ERROR: Unsupported arguments for Pkg Write\n");
345 goto ErrorExit;
346 break;
347 }
348 if (verbose)
349 {
350 printf("Pkg Write of Index %02x Param %04x: 0x%0*x\n", u8PkgIndex,
351 u16PkgParam, u8Size * 2, u32PkgValue);
352 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700353 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700354 {
Jason M. Billsff44e542021-04-05 08:11:52 -0700355 ret = peci_WrPkgConfig(address, u8PkgIndex, u16PkgParam,
356 u32PkgValue, u8Size, &cc);
357 ccCounts[cc]++;
358
359 if (verbose || loops == 0)
360 {
361 if (0 != ret)
362 {
363 printf("ERROR %d: command failed\n", ret);
364 }
365 printf(" cc:0x%02x\n", cc);
366 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700367 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700368 if (looped)
369 {
370 printLoopSummary(ccCounts);
371 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700372 }
373 else if (strcmp(cmd, "rdiamsr") == 0)
374 {
375 index = argc;
376 switch (argc - optind)
377 {
378 case 2:
379 u16MsrAddr = (uint16_t)strtoul(argv[--index], NULL, 0);
380 u8MsrThread = (uint8_t)strtoul(argv[--index], NULL, 0);
381 break;
382 default:
383 printf("ERROR: Unsupported arguments for MSR Read\n");
384 goto ErrorExit;
385 break;
386 }
387 if (verbose)
388 {
389 printf("MSR Read of Thread %02x MSR %04x\n", u8MsrThread,
390 u16MsrAddr);
391 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700392 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700393 {
Jason M. Billsff44e542021-04-05 08:11:52 -0700394 ret =
395 peci_RdIAMSR(address, u8MsrThread, u16MsrAddr, &u64MsrVal, &cc);
396 ccCounts[cc]++;
397
398 if (verbose || loops == 0)
399 {
400 if (0 != ret)
401 {
402 printf("ERROR %d: command failed\n", ret);
403 printf(" cc:0x%02x\n", cc);
404 }
405 else
406 {
407 printf(" cc:0x%02x 0x%0*llx\n", cc, u8Size * 2,
408 (unsigned long long)u64MsrVal);
409 }
410 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700411 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700412 if (looped)
413 {
414 printLoopSummary(ccCounts);
415 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700416 }
417 else if (strcmp(cmd, "rdpciconfig") == 0)
418 {
419 index = argc;
420 switch (argc - optind)
421 {
422 case 4:
423 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
424 /* FALLTHROUGH */
425 case 3:
426 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
427 /* FALLTHROUGH */
428 case 2:
429 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
430 /* FALLTHROUGH */
431 case 1:
432 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
433 break;
434 default:
435 printf("ERROR: Unsupported arguments for PCI Read\n");
436 goto ErrorExit;
437 break;
438 }
439 if (verbose)
440 {
441 printf("PCI Read of %02x:%02x:%02x Reg %02x\n", u8PciBus, u8PciDev,
442 u8PciFunc, u16PciReg);
443 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700444 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700445 {
Jason M. Billsff44e542021-04-05 08:11:52 -0700446 ret = peci_RdPCIConfig(address, u8PciBus, u8PciDev, u8PciFunc,
447 u16PciReg, (uint8_t*)&u32PciReadVal, &cc);
448 ccCounts[cc]++;
449
450 if (verbose || loops == 0)
451 {
452 if (0 != ret)
453 {
454 printf("ERROR %d: command failed\n", ret);
455 printf(" cc:0x%02x\n", cc);
456 }
457 else
458 {
459 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2,
460 u32PciReadVal);
461 }
462 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700463 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700464 if (looped)
465 {
466 printLoopSummary(ccCounts);
467 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700468 }
469 else if (strcmp(cmd, "rdpciconfiglocal") == 0)
470 {
471 index = argc;
472 switch (argc - optind)
473 {
474 case 4:
475 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
476 /* FALLTHROUGH */
477 case 3:
478 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
479 /* FALLTHROUGH */
480 case 2:
481 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
482 /* FALLTHROUGH */
483 case 1:
484 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
485 break;
486 default:
487 printf("ERROR: Unsupported arguments for Local PCI Read\n");
488 goto ErrorExit;
489 break;
490 }
491 if (verbose)
492 {
493 printf("Local PCI Read of %02x:%02x:%02x Reg %02x\n", u8PciBus,
494 u8PciDev, u8PciFunc, u16PciReg);
495 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700496 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700497 {
Jason M. Billsff44e542021-04-05 08:11:52 -0700498 ret = peci_RdPCIConfigLocal(address, u8PciBus, u8PciDev, u8PciFunc,
499 u16PciReg, u8Size,
500 (uint8_t*)&u32PciReadVal, &cc);
501 ccCounts[cc]++;
502
503 if (verbose || loops == 0)
504 {
505 if (0 != ret)
506 {
507 printf("ERROR %d: command failed\n", ret);
508 printf(" cc:0x%02x\n", cc);
509 }
510 else
511 {
512 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2,
513 u32PciReadVal);
514 }
515 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700516 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700517 if (looped)
518 {
519 printLoopSummary(ccCounts);
520 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700521 }
522 else if (strcmp(cmd, "wrpciconfiglocal") == 0)
523 {
524 index = argc;
Jason M. Bills62cbc712020-05-07 14:07:49 -0700525 u32PciWriteVal = (uint32_t)strtoul(argv[--index], NULL, 0);
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700526 switch (argc - optind)
527 {
528 case 5:
529 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
530 /* FALLTHROUGH */
531 case 4:
532 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
533 /* FALLTHROUGH */
534 case 3:
535 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
536 /* FALLTHROUGH */
537 case 2:
538 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
539 break;
540 default:
541 printf("ERROR: Unsupported arguments for Local PCI Write\n");
542 goto ErrorExit;
543 break;
544 }
545 if (verbose)
546 {
547 printf("Local PCI Write of %02x:%02x:%02x Reg %02x: 0x%0*x\n",
548 u8PciBus, u8PciDev, u8PciFunc, u16PciReg, u8Size * 2,
549 u32PciWriteVal);
550 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700551 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700552 {
Jason M. Billsff44e542021-04-05 08:11:52 -0700553 ret = peci_WrPCIConfigLocal(address, u8PciBus, u8PciDev, u8PciFunc,
554 u16PciReg, u8Size, u32PciWriteVal, &cc);
555 ccCounts[cc]++;
556
557 if (verbose || loops == 0)
558 {
559 if (0 != ret)
560 {
561 printf("ERROR %d: command failed\n", ret);
562 }
563 printf(" cc:0x%02x\n", cc);
564 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700565 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700566 if (looped)
567 {
568 printLoopSummary(ccCounts);
569 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700570 }
571 else if (strcmp(cmd, "rdendpointconfigpcilocal") == 0)
572 {
573 index = argc;
574 switch (argc - optind)
575 {
576 case 5:
577 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
578 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
579 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
580 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
581 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
582 break;
583
584 default:
585 printf("ERROR: Unsupported arguments for Endpoint Local PCI "
586 "Read\n");
587 goto ErrorExit;
588 }
589 if (verbose)
590 {
591 printf(
592 "Endpoint Local PCI Read of Seg:%02x %02x:%02x:%02x Reg %02x\n",
593 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg);
594 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700595 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700596 {
Jason M. Billsff44e542021-04-05 08:11:52 -0700597 ret = peci_RdEndPointConfigPciLocal(
598 address, u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg,
599 u8Size, (uint8_t*)&u32PciReadVal, &cc);
600 ccCounts[cc]++;
601
602 if (verbose || loops == 0)
603 {
604 if (0 != ret)
605 {
606 printf("ERROR %d: command failed\n", ret);
607 printf(" cc:0x%02x\n", cc);
608 }
609 else
610 {
611 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2,
612 u32PciReadVal);
613 }
614 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700615 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700616 if (looped)
617 {
618 printLoopSummary(ccCounts);
619 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700620 }
621 else if (strcmp(cmd, "wrendpointconfigpcilocal") == 0)
622 {
623 index = argc;
624 switch (argc - optind)
625 {
626 case 6:
Jason M. Bills62cbc712020-05-07 14:07:49 -0700627 u32PciWriteVal = (uint32_t)strtoul(argv[--index], NULL, 0);
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700628 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
629 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
630 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
631 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
632 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
633 break;
634
635 default:
636 printf("ERROR: Unsupported arguments for Endpoint Local PCI "
637 "Write\n");
638 goto ErrorExit;
639 }
640 if (verbose)
641 {
642 printf("Endpoint Local PCI Write of Seg:%02x %02x:%02x:%02x Reg "
643 "%02x: 0x%0*x\n",
644 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg, u8Size * 2,
645 u32PciWriteVal);
646 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700647 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700648 {
Jason M. Billsff44e542021-04-05 08:11:52 -0700649 ret = peci_WrEndPointPCIConfigLocal(address, u8Seg, u8PciBus,
650 u8PciDev, u8PciFunc, u16PciReg,
651 u8Size, u32PciWriteVal, &cc);
652 ccCounts[cc]++;
653
654 if (verbose || loops == 0)
655 {
656 if (0 != ret)
657 {
658 printf("ERROR %d: command failed\n", ret);
659 }
660 printf(" cc:0x%02x\n", cc);
661 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700662 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700663 if (looped)
664 {
665 printLoopSummary(ccCounts);
666 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700667 }
668 else if (strcmp(cmd, "rdendpointconfigpci") == 0)
669 {
670 index = argc;
671 switch (argc - optind)
672 {
673 case 5:
674 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
675 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
676 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
677 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
678 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
679 break;
680
681 default:
682 printf("ERROR: Unsupported arguments for Endpoint PCI Read\n");
683 goto ErrorExit;
684 }
685 if (verbose)
686 {
687 printf("Endpoint PCI Read of Seg:%02x %02x:%02x:%02x Reg %02x\n",
688 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg);
689 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700690 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700691 {
Jason M. Billsff44e542021-04-05 08:11:52 -0700692 ret = peci_RdEndPointConfigPci(address, u8Seg, u8PciBus, u8PciDev,
693 u8PciFunc, u16PciReg, u8Size,
694 (uint8_t*)&u32PciReadVal, &cc);
695 ccCounts[cc]++;
696
697 if (verbose || loops == 0)
698 {
699 if (0 != ret)
700 {
701 printf("ERROR %d: command failed\n", ret);
702 printf(" cc:0x%02x\n", cc);
703 }
704 else
705 {
706 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2,
707 u32PciReadVal);
708 }
709 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700710 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700711 if (looped)
712 {
713 printLoopSummary(ccCounts);
714 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700715 }
716 else if (strcmp(cmd, "wrendpointconfigpci") == 0)
717 {
718 index = argc;
719 switch (argc - optind)
720 {
721 case 6:
Jason M. Bills62cbc712020-05-07 14:07:49 -0700722 u32PciWriteVal = (uint32_t)strtoul(argv[--index], NULL, 0);
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700723 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
724 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
725 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
726 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
727 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
728 break;
729
730 default:
731 printf("ERROR: Unsupported arguments for Endpoint PCI Write\n");
732 goto ErrorExit;
733 }
734 if (verbose)
735 {
736 printf("Endpoint PCI Write of Seg:%02x %02x:%02x:%02x Reg %02x: "
737 "0x%0*x\n",
738 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg, u8Size * 2,
739 u32PciWriteVal);
740 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700741 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700742 {
Jason M. Billsff44e542021-04-05 08:11:52 -0700743 ret = peci_WrEndPointPCIConfig(address, u8Seg, u8PciBus, u8PciDev,
744 u8PciFunc, u16PciReg, u8Size,
745 u32PciWriteVal, &cc);
746 ccCounts[cc]++;
747
748 if (verbose || loops == 0)
749 {
750 if (0 != ret)
751 {
752 printf("ERROR %d: command failed\n", ret);
753 }
754 printf(" cc:0x%02x\n", cc);
755 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700756 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700757 if (looped)
758 {
759 printLoopSummary(ccCounts);
760 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700761 }
762 else if (strcmp(cmd, "rdendpointconfigmmio") == 0)
763 {
764 index = argc;
765 switch (argc - optind)
766 {
767 case 7:
Jason M. Bills62cbc712020-05-07 14:07:49 -0700768 u64Offset = (uint64_t)strtoull(argv[--index], NULL, 0);
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700769 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
770 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
771 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
772 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
773 u8Bar = (uint8_t)strtoul(argv[--index], NULL, 0);
774 u8AddrType = (uint8_t)strtoul(argv[--index], NULL, 0);
775 break;
776
777 default:
778 printf("ERROR: Unsupported arguments for Endpoint MMIO Read\n");
779 goto ErrorExit;
780 }
781 if (verbose)
782 {
783 printf("Endpoint MMIO Read of Seg:%02x %02x:%02x:%02x AType:%02x "
784 "Bar:%02x Offset:0x%" PRIx64 "\n",
785 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u8AddrType, u8Bar,
786 u64Offset);
787 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700788 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700789 {
Jason M. Billsff44e542021-04-05 08:11:52 -0700790 ret = peci_RdEndPointConfigMmio(
791 address, u8Seg, u8PciBus, u8PciDev, u8PciFunc, u8Bar,
792 u8AddrType, u64Offset, u8Size, (uint8_t*)&u32PciReadVal, &cc);
793 ccCounts[cc]++;
794
795 if (verbose || loops == 0)
796 {
797 if (0 != ret)
798 {
799 printf("ERROR %d: command failed\n", ret);
800 printf(" cc:0x%02x\n", cc);
801 }
802 else
803 {
804 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2,
805 u32PciReadVal);
806 }
807 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700808 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700809 if (looped)
810 {
811 printLoopSummary(ccCounts);
812 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700813 }
814 else if (strcmp(cmd, "wrendpointconfigmmio") == 0)
815 {
816 index = argc;
817 switch (argc - optind)
818 {
819 case 8:
Jason M. Bills62cbc712020-05-07 14:07:49 -0700820 u64MmioWriteVal = (uint64_t)strtoull(argv[--index], NULL, 0);
821 u64Offset = (uint64_t)strtoull(argv[--index], NULL, 0);
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700822 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
823 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
824 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
825 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
826 u8Bar = (uint8_t)strtoul(argv[--index], NULL, 0);
827 u8AddrType = (uint8_t)strtoul(argv[--index], NULL, 0);
828 break;
829
830 default:
831 printf(
832 "ERROR: Unsupported arguments for Endpoint MMIO Write\n");
833 goto ErrorExit;
834 }
835 if (verbose)
836 {
837 printf("Endpoint MMIO Write of Seg:%02x %02x:%02x:%02x AType:%02x "
838 "Bar:%02x Offset:0x%" PRIx64 ": 0x%0*" PRIx64 "\n",
839 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u8AddrType, u8Bar,
840 u64Offset, u8Size * 2, u64MmioWriteVal);
841 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700842 while (loops--)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700843 {
Jason M. Billsff44e542021-04-05 08:11:52 -0700844 ret = peci_WrEndPointConfigMmio(
845 address, u8Seg, u8PciBus, u8PciDev, u8PciFunc, u8Bar,
846 u8AddrType, u64Offset, u8Size, u64MmioWriteVal, &cc);
847 ccCounts[cc]++;
848
849 if (verbose || loops == 0)
850 {
851 if (0 != ret)
852 {
853 printf("ERROR %d: command failed\n", ret);
854 }
855 printf(" cc:0x%02x\n", cc);
856 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700857 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700858 if (looped)
859 {
860 printLoopSummary(ccCounts);
861 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700862 }
863 else if (strcmp(cmd, "raw") == 0)
864 {
865 if ((argc - optind) < 3)
866 {
867 printf("ERROR: Unsupported arguments for raw command\n");
868 goto ErrorExit;
869 }
870
871 // Address is provided in the first byte of the PECI command
872 uint8_t rawAddr = (uint8_t)strtoul(argv[optind++], NULL, 0);
873 // Write length is provided in the second byte of the PECI command
874 uint8_t writeLength = (uint8_t)strtoul(argv[optind++], NULL, 0);
875 // Read length is provided in the third byte of the PECI command
876 uint8_t readLength = (uint8_t)strtoul(argv[optind++], NULL, 0);
877
Jason M. Billsc965e722020-07-06 15:49:14 -0700878 // remaining parameters should fit within write length
879 if ((argc - optind) > writeLength)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700880 {
881 printf("ERROR: Incorrect write length for raw command\n");
882 goto ErrorExit;
883 }
884 uint8_t* rawCmd = (uint8_t*)calloc(writeLength, sizeof(uint8_t));
885 if (rawCmd == NULL)
886 {
887 // calloc failed, abort the sequence
888 printf("Raw command memory allocation failed\n");
889 return 1;
890 }
Jason M. Billsc965e722020-07-06 15:49:14 -0700891 for (i = 0; i < (argc - optind); i++)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700892 {
893 rawCmd[i] = (uint8_t)strtoul(argv[i + optind], NULL, 0);
894 }
895 if (verbose)
896 {
897 printf("Raw command: %02x %02x %02x ", rawAddr, writeLength,
898 readLength);
899 for (i = 0; i < writeLength; i++)
900 {
901 printf("0x%02x ", rawCmd[i]);
902 }
903 printf("\n");
904 }
905
906 uint8_t* rawResp = (uint8_t*)calloc(readLength, sizeof(uint8_t));
907 if (rawResp == NULL)
908 {
909 // calloc failed, abort the sequence
910 printf("Raw command memory allocation failed\n");
911 free(rawCmd);
912 return 1;
913 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700914 while (loops--)
Jason M. Bills0e21dde2020-07-06 14:51:53 -0700915 {
Jason M. Billsff44e542021-04-05 08:11:52 -0700916 ret = peci_raw(rawAddr, readLength, rawCmd, writeLength, rawResp,
917 readLength);
918 if (verbose)
919 {
920 printf(" ");
921 for (i = 0; i < readLength; i++)
922 {
923 printf("0x%02x ", rawResp[i]);
924 }
925 printf("\n");
926 }
927 ccCounts[rawResp[0]]++;
928 }
929 if (!verbose)
930 {
931 if (0 != ret)
932 {
933 printf("ERROR %d: command failed\n", ret);
934 }
935 printf(" ");
Jason M. Bills0e21dde2020-07-06 14:51:53 -0700936 for (i = 0; i < readLength; i++)
937 {
938 printf("0x%02x ", rawResp[i]);
939 }
940 printf("\n");
941 }
Jason M. Billsff44e542021-04-05 08:11:52 -0700942
943 if (looped)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700944 {
Jason M. Billsff44e542021-04-05 08:11:52 -0700945 printLoopSummary(ccCounts);
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700946 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700947
948 free(rawCmd);
949 free(rawResp);
950 }
951 else
952 {
953 printf("ERROR: Unrecognized command\n");
954 goto ErrorExit;
955 }
956
957 return 0;
958
959ErrorExit:
960 Usage(argv[0]);
961 return 1;
962}