blob: 1e83ef0004146b38d6ffc89d6627223421f9af28 [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:
Jason M. Bills62cbc712020-05-07 14:07:49 -0700248 u32PkgValue = (uint32_t)strtoul(argv[--index], NULL, 0);
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700249 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 }
Jason M. Bills62cbc712020-05-07 14:07:49 -0700298 printf(" cc:0x%02x 0x%0*llx\n", cc, u8Size * 2,
299 (unsigned long long)u64MsrVal);
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700300 }
301 else if (strcmp(cmd, "rdpciconfig") == 0)
302 {
303 index = argc;
304 switch (argc - optind)
305 {
306 case 4:
307 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
308 /* FALLTHROUGH */
309 case 3:
310 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
311 /* FALLTHROUGH */
312 case 2:
313 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
314 /* FALLTHROUGH */
315 case 1:
316 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
317 break;
318 default:
319 printf("ERROR: Unsupported arguments for PCI Read\n");
320 goto ErrorExit;
321 break;
322 }
323 if (verbose)
324 {
325 printf("PCI Read of %02x:%02x:%02x Reg %02x\n", u8PciBus, u8PciDev,
326 u8PciFunc, u16PciReg);
327 }
328 ret = peci_RdPCIConfig(address, u8PciBus, u8PciDev, u8PciFunc,
329 u16PciReg, (uint8_t*)&u32PciReadVal, &cc);
330 if (0 != ret)
331 {
332 printf("ERROR %d: command failed\n", ret);
333 printf(" cc:0x%02x\n", cc);
334 return 1;
335 }
336 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2, u32PciReadVal);
337 }
338 else if (strcmp(cmd, "rdpciconfiglocal") == 0)
339 {
340 index = argc;
341 switch (argc - optind)
342 {
343 case 4:
344 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
345 /* FALLTHROUGH */
346 case 3:
347 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
348 /* FALLTHROUGH */
349 case 2:
350 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
351 /* FALLTHROUGH */
352 case 1:
353 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
354 break;
355 default:
356 printf("ERROR: Unsupported arguments for Local PCI Read\n");
357 goto ErrorExit;
358 break;
359 }
360 if (verbose)
361 {
362 printf("Local PCI Read of %02x:%02x:%02x Reg %02x\n", u8PciBus,
363 u8PciDev, u8PciFunc, u16PciReg);
364 }
365 ret = peci_RdPCIConfigLocal(address, u8PciBus, u8PciDev, u8PciFunc,
366 u16PciReg, u8Size, (uint8_t*)&u32PciReadVal,
367 &cc);
368 if (0 != ret)
369 {
370 printf("ERROR %d: command failed\n", ret);
371 printf(" cc:0x%02x\n", cc);
372 return 1;
373 }
374 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2, u32PciReadVal);
375 }
376 else if (strcmp(cmd, "wrpciconfiglocal") == 0)
377 {
378 index = argc;
Jason M. Bills62cbc712020-05-07 14:07:49 -0700379 u32PciWriteVal = (uint32_t)strtoul(argv[--index], NULL, 0);
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700380 switch (argc - optind)
381 {
382 case 5:
383 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
384 /* FALLTHROUGH */
385 case 4:
386 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
387 /* FALLTHROUGH */
388 case 3:
389 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
390 /* FALLTHROUGH */
391 case 2:
392 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
393 break;
394 default:
395 printf("ERROR: Unsupported arguments for Local PCI Write\n");
396 goto ErrorExit;
397 break;
398 }
399 if (verbose)
400 {
401 printf("Local PCI Write of %02x:%02x:%02x Reg %02x: 0x%0*x\n",
402 u8PciBus, u8PciDev, u8PciFunc, u16PciReg, u8Size * 2,
403 u32PciWriteVal);
404 }
405 ret = peci_WrPCIConfigLocal(address, u8PciBus, u8PciDev, u8PciFunc,
406 u16PciReg, u8Size, u32PciWriteVal, &cc);
407 if (0 != ret)
408 {
409 printf("ERROR %d: command failed\n", ret);
410 printf(" cc:0x%02x\n", cc);
411 return 1;
412 }
413 printf(" cc:0x%02x\n", cc);
414 }
415 else if (strcmp(cmd, "rdendpointconfigpcilocal") == 0)
416 {
417 index = argc;
418 switch (argc - optind)
419 {
420 case 5:
421 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
422 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
423 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
424 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
425 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
426 break;
427
428 default:
429 printf("ERROR: Unsupported arguments for Endpoint Local PCI "
430 "Read\n");
431 goto ErrorExit;
432 }
433 if (verbose)
434 {
435 printf(
436 "Endpoint Local PCI Read of Seg:%02x %02x:%02x:%02x Reg %02x\n",
437 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg);
438 }
439 ret = peci_RdEndPointConfigPciLocal(address, u8Seg, u8PciBus, u8PciDev,
440 u8PciFunc, u16PciReg, u8Size,
441 (uint8_t*)&u32PciReadVal, &cc);
442 if (0 != ret)
443 {
444 printf("ERROR %d: command failed\n", ret);
445 printf(" cc:0x%02x\n", cc);
446 return 1;
447 }
448 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2, u32PciReadVal);
449 }
450 else if (strcmp(cmd, "wrendpointconfigpcilocal") == 0)
451 {
452 index = argc;
453 switch (argc - optind)
454 {
455 case 6:
Jason M. Bills62cbc712020-05-07 14:07:49 -0700456 u32PciWriteVal = (uint32_t)strtoul(argv[--index], NULL, 0);
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700457 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
458 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
459 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
460 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
461 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
462 break;
463
464 default:
465 printf("ERROR: Unsupported arguments for Endpoint Local PCI "
466 "Write\n");
467 goto ErrorExit;
468 }
469 if (verbose)
470 {
471 printf("Endpoint Local PCI Write of Seg:%02x %02x:%02x:%02x Reg "
472 "%02x: 0x%0*x\n",
473 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg, u8Size * 2,
474 u32PciWriteVal);
475 }
476 ret = peci_WrEndPointPCIConfigLocal(address, u8Seg, u8PciBus, u8PciDev,
477 u8PciFunc, u16PciReg, u8Size,
478 u32PciWriteVal, &cc);
479 if (0 != ret)
480 {
481 printf("ERROR %d: command failed\n", ret);
482 printf(" cc:0x%02x\n", cc);
483 return 1;
484 }
485 printf(" cc:0x%02x\n", cc);
486 }
487 else if (strcmp(cmd, "rdendpointconfigpci") == 0)
488 {
489 index = argc;
490 switch (argc - optind)
491 {
492 case 5:
493 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
494 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
495 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
496 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
497 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
498 break;
499
500 default:
501 printf("ERROR: Unsupported arguments for Endpoint PCI Read\n");
502 goto ErrorExit;
503 }
504 if (verbose)
505 {
506 printf("Endpoint PCI Read of Seg:%02x %02x:%02x:%02x Reg %02x\n",
507 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg);
508 }
509 ret = peci_RdEndPointConfigPci(address, u8Seg, u8PciBus, u8PciDev,
510 u8PciFunc, u16PciReg, u8Size,
511 (uint8_t*)&u32PciReadVal, &cc);
512 if (0 != ret)
513 {
514 printf("ERROR %d: command failed\n", ret);
515 printf(" cc:0x%02x\n", cc);
516 return 1;
517 }
518 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2, u32PciReadVal);
519 }
520 else if (strcmp(cmd, "wrendpointconfigpci") == 0)
521 {
522 index = argc;
523 switch (argc - optind)
524 {
525 case 6:
Jason M. Bills62cbc712020-05-07 14:07:49 -0700526 u32PciWriteVal = (uint32_t)strtoul(argv[--index], NULL, 0);
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700527 u16PciReg = (uint16_t)strtoul(argv[--index], NULL, 0);
528 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
529 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
530 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
531 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
532 break;
533
534 default:
535 printf("ERROR: Unsupported arguments for Endpoint PCI Write\n");
536 goto ErrorExit;
537 }
538 if (verbose)
539 {
540 printf("Endpoint PCI Write of Seg:%02x %02x:%02x:%02x Reg %02x: "
541 "0x%0*x\n",
542 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u16PciReg, u8Size * 2,
543 u32PciWriteVal);
544 }
545 ret = peci_WrEndPointPCIConfig(address, u8Seg, u8PciBus, u8PciDev,
546 u8PciFunc, u16PciReg, u8Size,
547 u32PciWriteVal, &cc);
548 if (0 != ret)
549 {
550 printf("ERROR %d: command failed\n", ret);
551 printf(" cc:0x%02x\n", cc);
552 return 1;
553 }
554 printf(" cc:0x%02x\n", cc);
555 }
556 else if (strcmp(cmd, "rdendpointconfigmmio") == 0)
557 {
558 index = argc;
559 switch (argc - optind)
560 {
561 case 7:
Jason M. Bills62cbc712020-05-07 14:07:49 -0700562 u64Offset = (uint64_t)strtoull(argv[--index], NULL, 0);
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700563 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
564 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
565 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
566 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
567 u8Bar = (uint8_t)strtoul(argv[--index], NULL, 0);
568 u8AddrType = (uint8_t)strtoul(argv[--index], NULL, 0);
569 break;
570
571 default:
572 printf("ERROR: Unsupported arguments for Endpoint MMIO Read\n");
573 goto ErrorExit;
574 }
575 if (verbose)
576 {
577 printf("Endpoint MMIO Read of Seg:%02x %02x:%02x:%02x AType:%02x "
578 "Bar:%02x Offset:0x%" PRIx64 "\n",
579 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u8AddrType, u8Bar,
580 u64Offset);
581 }
582 ret = peci_RdEndPointConfigMmio(address, u8Seg, u8PciBus, u8PciDev,
583 u8PciFunc, u8Bar, u8AddrType, u64Offset,
584 u8Size, (uint8_t*)&u32PciReadVal, &cc);
585 if (0 != ret)
586 {
587 printf("ERROR %d: command failed\n", ret);
588 printf(" cc:0x%02x\n", cc);
589 return 1;
590 }
591 printf(" cc:0x%02x 0x%0*x\n", cc, u8Size * 2, u32PciReadVal);
592 }
593 else if (strcmp(cmd, "wrendpointconfigmmio") == 0)
594 {
595 index = argc;
596 switch (argc - optind)
597 {
598 case 8:
Jason M. Bills62cbc712020-05-07 14:07:49 -0700599 u64MmioWriteVal = (uint64_t)strtoull(argv[--index], NULL, 0);
600 u64Offset = (uint64_t)strtoull(argv[--index], NULL, 0);
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700601 u8PciFunc = (uint8_t)strtoul(argv[--index], NULL, 0);
602 u8PciDev = (uint8_t)strtoul(argv[--index], NULL, 0);
603 u8PciBus = (uint8_t)strtoul(argv[--index], NULL, 0);
604 u8Seg = (uint8_t)strtoul(argv[--index], NULL, 0);
605 u8Bar = (uint8_t)strtoul(argv[--index], NULL, 0);
606 u8AddrType = (uint8_t)strtoul(argv[--index], NULL, 0);
607 break;
608
609 default:
610 printf(
611 "ERROR: Unsupported arguments for Endpoint MMIO Write\n");
612 goto ErrorExit;
613 }
614 if (verbose)
615 {
616 printf("Endpoint MMIO Write of Seg:%02x %02x:%02x:%02x AType:%02x "
617 "Bar:%02x Offset:0x%" PRIx64 ": 0x%0*" PRIx64 "\n",
618 u8Seg, u8PciBus, u8PciDev, u8PciFunc, u8AddrType, u8Bar,
619 u64Offset, u8Size * 2, u64MmioWriteVal);
620 }
621 ret = peci_WrEndPointConfigMmio(address, u8Seg, u8PciBus, u8PciDev,
622 u8PciFunc, u8Bar, u8AddrType, u64Offset,
623 u8Size, u64MmioWriteVal, &cc);
624 if (0 != ret)
625 {
626 printf("ERROR %d: command failed\n", ret);
627 printf(" cc:0x%02x\n", cc);
628 return 1;
629 }
630 printf(" cc:0x%02x\n", cc);
631 }
632 else if (strcmp(cmd, "raw") == 0)
633 {
634 if ((argc - optind) < 3)
635 {
636 printf("ERROR: Unsupported arguments for raw command\n");
637 goto ErrorExit;
638 }
639
640 // Address is provided in the first byte of the PECI command
641 uint8_t rawAddr = (uint8_t)strtoul(argv[optind++], NULL, 0);
642 // Write length is provided in the second byte of the PECI command
643 uint8_t writeLength = (uint8_t)strtoul(argv[optind++], NULL, 0);
644 // Read length is provided in the third byte of the PECI command
645 uint8_t readLength = (uint8_t)strtoul(argv[optind++], NULL, 0);
646
Jason M. Billsc965e722020-07-06 15:49:14 -0700647 // remaining parameters should fit within write length
648 if ((argc - optind) > writeLength)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700649 {
650 printf("ERROR: Incorrect write length for raw command\n");
651 goto ErrorExit;
652 }
653 uint8_t* rawCmd = (uint8_t*)calloc(writeLength, sizeof(uint8_t));
654 if (rawCmd == NULL)
655 {
656 // calloc failed, abort the sequence
657 printf("Raw command memory allocation failed\n");
658 return 1;
659 }
Jason M. Billsc965e722020-07-06 15:49:14 -0700660 for (i = 0; i < (argc - optind); i++)
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700661 {
662 rawCmd[i] = (uint8_t)strtoul(argv[i + optind], NULL, 0);
663 }
664 if (verbose)
665 {
666 printf("Raw command: %02x %02x %02x ", rawAddr, writeLength,
667 readLength);
668 for (i = 0; i < writeLength; i++)
669 {
670 printf("0x%02x ", rawCmd[i]);
671 }
672 printf("\n");
673 }
674
675 uint8_t* rawResp = (uint8_t*)calloc(readLength, sizeof(uint8_t));
676 if (rawResp == NULL)
677 {
678 // calloc failed, abort the sequence
679 printf("Raw command memory allocation failed\n");
680 free(rawCmd);
681 return 1;
682 }
683 ret = peci_raw(rawAddr, readLength, rawCmd, writeLength, rawResp,
684 readLength);
Jason M. Bills0e21dde2020-07-06 14:51:53 -0700685 if (verbose)
686 {
687 printf("Raw response: ");
688 for (i = 0; i < readLength; i++)
689 {
690 printf("0x%02x ", rawResp[i]);
691 }
692 printf("\n");
693 }
Jason M. Bills7ef5a552020-04-06 14:58:44 -0700694 if (0 != ret)
695 {
696 printf("ERROR %d: command failed\n", ret);
697 free(rawCmd);
698 free(rawResp);
699 return 1;
700 }
701 printf(" ");
702 for (i = 0; i < readLength; i++)
703 {
704 printf("0x%02x ", rawResp[i]);
705 }
706 printf("\n");
707
708 free(rawCmd);
709 free(rawResp);
710 }
711 else
712 {
713 printf("ERROR: Unrecognized command\n");
714 goto ErrorExit;
715 }
716
717 return 0;
718
719ErrorExit:
720 Usage(argv[0]);
721 return 1;
722}