blob: ee23ccafee934875115d726d32bbc7c2c7aa4b59 [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>
17#include <inttypes.h>
18#include <peci.h>
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22#include <unistd.h>
23#ifndef ABS
24#define ABS(_v_) (((_v_) > 0) ? (_v_) : -(_v_))
25#endif
26
27extern EPECIStatus peci_GetDIB(uint8_t target, uint64_t* dib);
28
29void Usage(char* progname)
30{
31 printf("Usage:\n");
32 printf("%s [-a <addr>] [-s <size>] <command> [parameters]\n", progname);
33 printf("Options:\n");
34 printf("\t%-6s%s\n", "-h", "Display this help information");
35 printf("\t%-6s%s\n", "-v",
36 "Display additional information about the command");
37 printf("\t%-6s%s\n", "-a",
38 "Address of the target. Accepted values are 48-55 (0x30-0x37). "
39 "Default is 48 (0x30)");
40 printf("\t%-6s%s\n", "-s",
41 "Size of data to read or write in bytes. Accepted values are 1, 2, "
42 "4, 8, and 16. Default is 4");
43 printf("Commands:\n");
44 printf("\t%-28s%s\n", "Ping", "Ping the target");
45 printf("\t%-28s%s\n", "GetTemp", "Get the temperature");
46 printf("\t%-28s%s\n", "GetDIB", "Get the DIB");
47 printf("\t%-28s%s\n", "RdPkgConfig",
48 "Read Package Config <Index Parameter>");
49 printf("\t%-28s%s\n", "WrPkgConfig",
50 "Write Package Config <Index Parameter Data>");
51 printf("\t%-28s%s\n", "RdIAMSR", "MSR Read <Thread Address>");
52 printf("\t%-28s%s\n", "RdPCIConfig", "PCI Read <Bus Dev Func [Reg]>");
53 printf("\t%-28s%s\n", "RdPCIConfigLocal",
54 "Local PCI Read <Bus Dev Func [Reg]>");
55 printf("\t%-28s%s\n", "WrPCIConfigLocal",
56 "Local PCI Write <Bus Dev Func Reg Data>");
57 printf("\t%-28s%s\n", "RdEndpointConfigPCILocal",
58 "Endpoint Local PCI Config Read <Seg Bus Dev Func Reg>");
59 printf("\t%-28s%s\n", "WrEndpointConfigPCILocal",
60 "Endpoint Local PCI Config Write <Seg Bus Dev Func Reg Data>");
61 printf("\t%-28s%s\n", "RdEndpointConfigPCI",
62 "Endpoint PCI Config Read <Seg Bus Dev Func Reg>");
63 printf("\t%-28s%s\n", "WrEndpointConfigPCI",
64 "Endpoint PCI Config Write <Seg Bus Dev Func Reg Data>");
65 printf("\t%-28s%s\n", "RdEndpointConfigMMIO",
66 "Endpoint MMIO Read <AType Bar Seg Bus Dev Func Reg>");
67 printf("\t%-28s%s\n", "WrEndpointConfigMMIO",
68 "Endpoint MMIO Write <AType Bar Seg Bus Dev Func Reg Data>");
69 printf("\t%-28s%s\n", "raw", "Raw PECI command in bytes");
70 printf("\n");
71}
72
73int main(int argc, char* argv[])
74{
75 int c;
76 int i = 0;
77 char* cmd = NULL;
78 EPECIStatus ret;
79 uint8_t address = 0x30; // use default address of 48d
80 uint8_t u8Size = 4; // default to a DWORD
81 uint32_t u32PciReadVal = 0;
82 uint8_t u8Seg = 0;
83 uint8_t u8Bar = 0;
84 uint8_t u8AddrType = 0;
85 uint8_t u8PciBus = 0;
86 uint8_t u8PciDev = 0;
87 uint8_t u8PciFunc = 0;
88 uint16_t u16PciReg = 0;
89 uint64_t u64Offset = 0;
90 uint32_t u32PciWriteVal = 0;
91 uint64_t u64MmioWriteVal = 0;
92 uint8_t u8PkgIndex = 0;
93 uint16_t u16PkgParam = 0;
94 uint32_t u32PkgValue = 0;
95 uint8_t u8MsrThread = 0;
96 uint16_t u16MsrAddr = 0;
97 uint64_t u64MsrVal = 0;
98 short temperature;
99 uint64_t dib;
100 int index = 0;
101 uint8_t cc = 0;
102 bool verbose = false;
103
104 //
105 // Parse arguments.
106 //
107 while (-1 != (c = getopt(argc, argv, "hva:s:")))
108 {
109 switch (c)
110 {
111 case 'h':
112 Usage(argv[0]);
113 return 0;
114 break;
115
116 case 'v':
117 verbose = true;
118 break;
119
120 case 'a':
121 if (optarg != NULL)
122 address = (uint8_t)strtoul(optarg, NULL, 0);
123 if (address < MIN_CLIENT_ADDR || address > MAX_CLIENT_ADDR)
124 {
125 printf("ERROR: Invalid address \"0x%x\"\n", address);
126 goto ErrorExit;
127 }
128
129 break;
130
131 case 's':
132 if (optarg != NULL)
133 u8Size = (uint8_t)strtoul(optarg, NULL, 0);
134 if (u8Size != 1 && u8Size != 2 && u8Size != 4 && u8Size != 8 &&
135 u8Size != 16)
136 {
137 printf("ERROR: Invalid size \"%d\"\n", u8Size);
138 goto ErrorExit;
139 }
140 break;
141
142 default:
143 printf("ERROR: Unrecognized option \"-%c\"\n", optopt);
144 goto ErrorExit;
145 break;
146 }
147 }
148
149 // Get the command from the first parameter
150 cmd = argv[optind++];
151 if (cmd == NULL)
152 {
153 Usage(argv[0]);
154 return 0;
155 }
156
157 // Allow any case
158 while (cmd[i])
159 {
160 cmd[i] = (char)tolower((int)cmd[i]);
161 i++;
162 }
163
164 //
165 // Execute the command
166 //
167 if (verbose)
168 {
169 printf("PECI target[0x%x]: ", address);
170 }
171 if (strcmp(cmd, "ping") == 0)
172 {
173 if (verbose)
174 {
175 printf("Pinging ... ");
176 }
177 (0 == peci_Ping(address)) ? printf("Succeeded\n") : printf("Failed\n");
178 }
179 else if (strcmp(cmd, "getdib") == 0)
180 {
181 if (verbose)
182 {
183 printf("GetDIB\n");
184 }
185 ret = peci_GetDIB(address, &dib);
186 if (0 != ret)
187 {
188 printf("ERROR %d: Retrieving DIB failed\n", ret);
189 return 1;
190 }
191 printf(" 0x%" PRIx64 "\n", dib);
192 }
193
194 else if (strcmp(cmd, "gettemp") == 0)
195 {
196 if (verbose)
197 {
198 printf("GetTemp\n");
199 }
200 ret = peci_GetTemp(address, &temperature);
201 if (0 != ret)
202 {
203 printf("ERROR %d: Retrieving temperature failed\n", ret);
204 return 1;
205 }
206 printf(" %04xh (%c%d.%02dC)\n",
207 (int)(unsigned int)(unsigned short)temperature,
208 (0 > temperature) ? '-' : '+',
209 (int)((unsigned int)ABS(temperature) / 64),
210 (int)(((unsigned int)ABS(temperature) % 64) * 100) / 64);
211 }
212
213 else if (strcmp(cmd, "rdpkgconfig") == 0)
214 {
215 index = argc;
216 switch (argc - optind)
217 {
218 case 2:
219 u16PkgParam = (uint16_t)strtoul(argv[--index], NULL, 0);
220 u8PkgIndex = (uint8_t)strtoul(argv[--index], NULL, 0);
221 break;
222 default:
223 printf("ERROR: Unsupported arguments for Pkg Read\n");
224 goto ErrorExit;
225 break;
226 }
227 if (verbose)
228 {
229 printf("Pkg Read of Index %02x Param %04x\n", u8PkgIndex,
230 u16PkgParam);
231 }
232 ret = peci_RdPkgConfig(address, u8PkgIndex, u16PkgParam, u8Size,
233 (uint8_t*)&u32PkgValue, &cc);
234 if (0 != ret)
235 {
236 printf("ERROR %d: command failed\n", ret);
237 printf(" cc:0x%02x\n", cc);
238 return 1;
239 }
240 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2, u32PkgValue);
241 }
242 else if (strcmp(cmd, "wrpkgconfig") == 0)
243 {
244 index = argc;
245 switch (argc - optind)
246 {
247 case 3:
248 u32PkgValue = strtoul(argv[--index], NULL, 0);
249 u16PkgParam = (uint16_t)strtoul(argv[--index], NULL, 0);
250 u8PkgIndex = (uint8_t)strtoul(argv[--index], NULL, 0);
251 break;
252 default:
253 printf("ERROR: Unsupported arguments for Pkg Write\n");
254 goto ErrorExit;
255 break;
256 }
257 if (verbose)
258 {
259 printf("Pkg Write of Index %02x Param %04x: 0x%0*x\n", u8PkgIndex,
260 u16PkgParam, u8Size * 2, u32PkgValue);
261 }
262 ret = peci_WrPkgConfig(address, u8PkgIndex, u16PkgParam, u32PkgValue,
263 u8Size, &cc);
264 if (0 != ret)
265 {
266 printf("ERROR %d: command failed\n", ret);
267 printf(" cc:0x%02x\n", cc);
268 return 1;
269 }
270 printf(" cc:0x%02x\n", cc);
271 }
272 else if (strcmp(cmd, "rdiamsr") == 0)
273 {
274 index = argc;
275 switch (argc - optind)
276 {
277 case 2:
278 u16MsrAddr = (uint16_t)strtoul(argv[--index], NULL, 0);
279 u8MsrThread = (uint8_t)strtoul(argv[--index], NULL, 0);
280 break;
281 default:
282 printf("ERROR: Unsupported arguments for MSR Read\n");
283 goto ErrorExit;
284 break;
285 }
286 if (verbose)
287 {
288 printf("MSR Read of Thread %02x MSR %04x\n", u8MsrThread,
289 u16MsrAddr);
290 }
291 ret = peci_RdIAMSR(address, u8MsrThread, u16MsrAddr, &u64MsrVal, &cc);
292 if (0 != ret)
293 {
294 printf("ERROR %d: command failed\n", ret);
295 printf(" cc:0x%02x\n", cc);
296 return 1;
297 }
298 printf(" cc:0x%02x 0x%0*llx\n", cc, u8Size * 2, u64MsrVal);
299 }
300 else if (strcmp(cmd, "rdpciconfig") == 0)
301 {
302 index = argc;
303 switch (argc - optind)
304 {
305 case 4:
306 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
307 /* FALLTHROUGH */
308 case 3:
309 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
310 /* FALLTHROUGH */
311 case 2:
312 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
313 /* FALLTHROUGH */
314 case 1:
315 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
316 break;
317 default:
318 printf("ERROR: Unsupported arguments for PCI Read\n");
319 goto ErrorExit;
320 break;
321 }
322 if (verbose)
323 {
324 printf("PCI Read of %02x:%02x:%02x Reg %02x\n", u8PciBus, u8PciDev,
325 u8PciFunc, u16PciReg);
326 }
327 ret = peci_RdPCIConfig(address, u8PciBus, u8PciDev, u8PciFunc,
328 u16PciReg, (uint8_t*)&u32PciReadVal, &cc);
329 if (0 != ret)
330 {
331 printf("ERROR %d: command failed\n", ret);
332 printf(" cc:0x%02x\n", cc);
333 return 1;
334 }
335 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2, u32PciReadVal);
336 }
337 else if (strcmp(cmd, "rdpciconfiglocal") == 0)
338 {
339 index = argc;
340 switch (argc - optind)
341 {
342 case 4:
343 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
344 /* FALLTHROUGH */
345 case 3:
346 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
347 /* FALLTHROUGH */
348 case 2:
349 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
350 /* FALLTHROUGH */
351 case 1:
352 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
353 break;
354 default:
355 printf("ERROR: Unsupported arguments for Local PCI Read\n");
356 goto ErrorExit;
357 break;
358 }
359 if (verbose)
360 {
361 printf("Local PCI Read of %02x:%02x:%02x Reg %02x\n", u8PciBus,
362 u8PciDev, u8PciFunc, u16PciReg);
363 }
364 ret = peci_RdPCIConfigLocal(address, u8PciBus, u8PciDev, u8PciFunc,
365 u16PciReg, u8Size, (uint8_t*)&u32PciReadVal,
366 &cc);
367 if (0 != ret)
368 {
369 printf("ERROR %d: command failed\n", ret);
370 printf(" cc:0x%02x\n", cc);
371 return 1;
372 }
373 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2, u32PciReadVal);
374 }
375 else if (strcmp(cmd, "wrpciconfiglocal") == 0)
376 {
377 index = argc;
378 u32PciWriteVal = strtoul(argv[--index], NULL, 0);
379 switch (argc - optind)
380 {
381 case 5:
382 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
383 /* FALLTHROUGH */
384 case 4:
385 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
386 /* FALLTHROUGH */
387 case 3:
388 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
389 /* FALLTHROUGH */
390 case 2:
391 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
392 break;
393 default:
394 printf("ERROR: Unsupported arguments for Local PCI Write\n");
395 goto ErrorExit;
396 break;
397 }
398 if (verbose)
399 {
400 printf("Local PCI Write of %02x:%02x:%02x Reg %02x: 0x%0*x\n",
401 u8PciBus, u8PciDev, u8PciFunc, u16PciReg, u8Size * 2,
402 u32PciWriteVal);
403 }
404 ret = peci_WrPCIConfigLocal(address, u8PciBus, u8PciDev, u8PciFunc,
405 u16PciReg, u8Size, u32PciWriteVal, &cc);
406 if (0 != ret)
407 {
408 printf("ERROR %d: command failed\n", ret);
409 printf(" cc:0x%02x\n", cc);
410 return 1;
411 }
412 printf(" cc:0x%02x\n", cc);
413 }
414 else if (strcmp(cmd, "rdendpointconfigpcilocal") == 0)
415 {
416 index = argc;
417 switch (argc - optind)
418 {
419 case 5:
420 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
421 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
422 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
423 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
424 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
425 break;
426
427 default:
428 printf("ERROR: Unsupported arguments for Endpoint Local PCI "
429 "Read\n");
430 goto ErrorExit;
431 }
432 if (verbose)
433 {
434 printf(
435 "Endpoint Local PCI Read of Seg:%02x %02x:%02x:%02x Reg %02x\n",
436 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg);
437 }
438 ret = peci_RdEndPointConfigPciLocal(address, u8Seg, u8PciBus, u8PciDev,
439 u8PciFunc, u16PciReg, u8Size,
440 (uint8_t*)&u32PciReadVal, &cc);
441 if (0 != ret)
442 {
443 printf("ERROR %d: command failed\n", ret);
444 printf(" cc:0x%02x\n", cc);
445 return 1;
446 }
447 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2, u32PciReadVal);
448 }
449 else if (strcmp(cmd, "wrendpointconfigpcilocal") == 0)
450 {
451 index = argc;
452 switch (argc - optind)
453 {
454 case 6:
455 u32PciWriteVal = strtoul(argv[--index], NULL, 0);
456 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
457 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
458 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
459 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
460 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
461 break;
462
463 default:
464 printf("ERROR: Unsupported arguments for Endpoint Local PCI "
465 "Write\n");
466 goto ErrorExit;
467 }
468 if (verbose)
469 {
470 printf("Endpoint Local PCI Write of Seg:%02x %02x:%02x:%02x Reg "
471 "%02x: 0x%0*x\n",
472 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg, u8Size * 2,
473 u32PciWriteVal);
474 }
475 ret = peci_WrEndPointPCIConfigLocal(address, u8Seg, u8PciBus, u8PciDev,
476 u8PciFunc, u16PciReg, u8Size,
477 u32PciWriteVal, &cc);
478 if (0 != ret)
479 {
480 printf("ERROR %d: command failed\n", ret);
481 printf(" cc:0x%02x\n", cc);
482 return 1;
483 }
484 printf(" cc:0x%02x\n", cc);
485 }
486 else if (strcmp(cmd, "rdendpointconfigpci") == 0)
487 {
488 index = argc;
489 switch (argc - optind)
490 {
491 case 5:
492 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
493 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
494 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
495 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
496 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
497 break;
498
499 default:
500 printf("ERROR: Unsupported arguments for Endpoint PCI Read\n");
501 goto ErrorExit;
502 }
503 if (verbose)
504 {
505 printf("Endpoint PCI Read of Seg:%02x %02x:%02x:%02x Reg %02x\n",
506 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg);
507 }
508 ret = peci_RdEndPointConfigPci(address, u8Seg, u8PciBus, u8PciDev,
509 u8PciFunc, u16PciReg, u8Size,
510 (uint8_t*)&u32PciReadVal, &cc);
511 if (0 != ret)
512 {
513 printf("ERROR %d: command failed\n", ret);
514 printf(" cc:0x%02x\n", cc);
515 return 1;
516 }
517 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2, u32PciReadVal);
518 }
519 else if (strcmp(cmd, "wrendpointconfigpci") == 0)
520 {
521 index = argc;
522 switch (argc - optind)
523 {
524 case 6:
525 u32PciWriteVal = strtoul(argv[--index], NULL, 0);
526 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
527 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
528 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
529 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
530 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
531 break;
532
533 default:
534 printf("ERROR: Unsupported arguments for Endpoint PCI Write\n");
535 goto ErrorExit;
536 }
537 if (verbose)
538 {
539 printf("Endpoint PCI Write of Seg:%02x %02x:%02x:%02x Reg %02x: "
540 "0x%0*x\n",
541 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg, u8Size * 2,
542 u32PciWriteVal);
543 }
544 ret = peci_WrEndPointPCIConfig(address, u8Seg, u8PciBus, u8PciDev,
545 u8PciFunc, u16PciReg, u8Size,
546 u32PciWriteVal, &cc);
547 if (0 != ret)
548 {
549 printf("ERROR %d: command failed\n", ret);
550 printf(" cc:0x%02x\n", cc);
551 return 1;
552 }
553 printf(" cc:0x%02x\n", cc);
554 }
555 else if (strcmp(cmd, "rdendpointconfigmmio") == 0)
556 {
557 index = argc;
558 switch (argc - optind)
559 {
560 case 7:
561 u64Offset = strtoull(argv[--index], NULL, 0);
562 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
563 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
564 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
565 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
566 u8Bar = (uint8_t)strtoul(argv[--index], NULL, 0);
567 u8AddrType = (uint8_t)strtoul(argv[--index], NULL, 0);
568 break;
569
570 default:
571 printf("ERROR: Unsupported arguments for Endpoint MMIO Read\n");
572 goto ErrorExit;
573 }
574 if (verbose)
575 {
576 printf("Endpoint MMIO Read of Seg:%02x %02x:%02x:%02x AType:%02x "
577 "Bar:%02x Offset:0x%" PRIx64 "\n",
578 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u8AddrType, u8Bar,
579 u64Offset);
580 }
581 ret = peci_RdEndPointConfigMmio(address, u8Seg, u8PciBus, u8PciDev,
582 u8PciFunc, u8Bar, u8AddrType, u64Offset,
583 u8Size, (uint8_t*)&u32PciReadVal, &cc);
584 if (0 != ret)
585 {
586 printf("ERROR %d: command failed\n", ret);
587 printf(" cc:0x%02x\n", cc);
588 return 1;
589 }
590 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2, u32PciReadVal);
591 }
592 else if (strcmp(cmd, "wrendpointconfigmmio") == 0)
593 {
594 index = argc;
595 switch (argc - optind)
596 {
597 case 8:
598 u64MmioWriteVal = strtoull(argv[--index], NULL, 0);
599 u64Offset = strtoull(argv[--index], NULL, 0);
600 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
601 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
602 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
603 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
604 u8Bar = (uint8_t)strtoul(argv[--index], NULL, 0);
605 u8AddrType = (uint8_t)strtoul(argv[--index], NULL, 0);
606 break;
607
608 default:
609 printf(
610 "ERROR: Unsupported arguments for Endpoint MMIO Write\n");
611 goto ErrorExit;
612 }
613 if (verbose)
614 {
615 printf("Endpoint MMIO Write of Seg:%02x %02x:%02x:%02x AType:%02x "
616 "Bar:%02x Offset:0x%" PRIx64 ": 0x%0*" PRIx64 "\n",
617 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u8AddrType, u8Bar,
618 u64Offset, u8Size * 2, u64MmioWriteVal);
619 }
620 ret = peci_WrEndPointConfigMmio(address, u8Seg, u8PciBus, u8PciDev,
621 u8PciFunc, u8Bar, u8AddrType, u64Offset,
622 u8Size, u64MmioWriteVal, &cc);
623 if (0 != ret)
624 {
625 printf("ERROR %d: command failed\n", ret);
626 printf(" cc:0x%02x\n", cc);
627 return 1;
628 }
629 printf(" cc:0x%02x\n", cc);
630 }
631 else if (strcmp(cmd, "raw") == 0)
632 {
633 if ((argc - optind) < 3)
634 {
635 printf("ERROR: Unsupported arguments for raw command\n");
636 goto ErrorExit;
637 }
638
639 // Address is provided in the first byte of the PECI command
640 uint8_t rawAddr = (uint8_t)strtoul(argv[optind++], NULL, 0);
641 // Write length is provided in the second byte of the PECI command
642 uint8_t writeLength = (uint8_t)strtoul(argv[optind++], NULL, 0);
643 // Read length is provided in the third byte of the PECI command
644 uint8_t readLength = (uint8_t)strtoul(argv[optind++], NULL, 0);
645
646 // remaining parameters should match write length
647 if ((argc - optind) != writeLength)
648 {
649 printf("ERROR: Incorrect write length for raw command\n");
650 goto ErrorExit;
651 }
652 uint8_t* rawCmd = (uint8_t*)calloc(writeLength, sizeof(uint8_t));
653 if (rawCmd == NULL)
654 {
655 // calloc failed, abort the sequence
656 printf("Raw command memory allocation failed\n");
657 return 1;
658 }
659 for (i = 0; i < writeLength; i++)
660 {
661 rawCmd[i] = (uint8_t)strtoul(argv[i + optind], NULL, 0);
662 }
663 if (verbose)
664 {
665 printf("Raw command: %02x %02x %02x ", rawAddr, writeLength,
666 readLength);
667 for (i = 0; i < writeLength; i++)
668 {
669 printf("0x%02x ", rawCmd[i]);
670 }
671 printf("\n");
672 }
673
674 uint8_t* rawResp = (uint8_t*)calloc(readLength, sizeof(uint8_t));
675 if (rawResp == NULL)
676 {
677 // calloc failed, abort the sequence
678 printf("Raw command memory allocation failed\n");
679 free(rawCmd);
680 return 1;
681 }
682 ret = peci_raw(rawAddr, readLength, rawCmd, writeLength, rawResp,
683 readLength);
684 if (0 != ret)
685 {
686 printf("ERROR %d: command failed\n", ret);
687 free(rawCmd);
688 free(rawResp);
689 return 1;
690 }
691 printf(" ");
692 for (i = 0; i < readLength; i++)
693 {
694 printf("0x%02x ", rawResp[i]);
695 }
696 printf("\n");
697
698 free(rawCmd);
699 free(rawResp);
700 }
701 else
702 {
703 printf("ERROR: Unrecognized command\n");
704 goto ErrorExit;
705 }
706
707 return 0;
708
709ErrorExit:
710 Usage(argv[0]);
711 return 1;
712}