2 * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
3 * Andreas Heppel <aheppel@sysgo.de>
6 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
7 * Wolfgang Grandegger, DENX Software Engineering, wg@denx.de.
9 * SPDX-License-Identifier: GPL-2.0+
17 #include <bootretry.h>
22 #include <asm/processor.h>
32 static int pci_byte_size(enum pci_size_t size
)
45 static int pci_field_width(enum pci_size_t size
)
47 return pci_byte_size(size
) * 2;
51 static void pci_show_regs(struct udevice
*dev
, struct pci_reg_info
*regs
)
53 for (; regs
->name
; regs
++) {
56 dm_pci_read_config(dev
, regs
->offset
, &val
, regs
->size
);
57 printf(" %s =%*s%#.*lx\n", regs
->name
,
58 (int)(28 - strlen(regs
->name
)), "",
59 pci_field_width(regs
->size
), val
);
63 static unsigned long pci_read_config(pci_dev_t dev
, int offset
,
72 pci_read_config_byte(dev
, offset
, &val8
);
75 pci_read_config_word(dev
, offset
, &val16
);
79 pci_read_config_dword(dev
, offset
, &val32
);
84 static void pci_show_regs(pci_dev_t dev
, struct pci_reg_info
*regs
)
86 for (; regs
->name
; regs
++) {
87 printf(" %s =%*s%#.*lx\n", regs
->name
,
88 (int)(28 - strlen(regs
->name
)), "",
89 pci_field_width(regs
->size
),
90 pci_read_config(dev
, regs
->offset
, regs
->size
));
96 int pci_bar_show(struct udevice
*dev
)
99 int bar_cnt
, bar_id
, mem_type
;
101 u32 base_low
, base_high
;
102 u32 size_low
, size_high
;
107 dm_pci_read_config8(dev
, PCI_HEADER_TYPE
, &header_type
);
109 if (header_type
== PCI_HEADER_TYPE_CARDBUS
) {
110 printf("CardBus doesn't support BARs\n");
114 bar_cnt
= (header_type
== PCI_HEADER_TYPE_NORMAL
) ? 6 : 2;
116 printf("ID Base Size Width Type\n");
117 printf("----------------------------------------------------------\n");
120 reg_addr
= PCI_BASE_ADDRESS_0
;
122 dm_pci_read_config32(dev
, reg_addr
, &base_low
);
123 dm_pci_write_config32(dev
, reg_addr
, 0xffffffff);
124 dm_pci_read_config32(dev
, reg_addr
, &size_low
);
125 dm_pci_write_config32(dev
, reg_addr
, base_low
);
128 base
= base_low
& ~0xf;
129 size
= size_low
& ~0xf;
131 size_high
= 0xffffffff;
133 prefetchable
= base_low
& PCI_BASE_ADDRESS_MEM_PREFETCH
;
134 is_io
= base_low
& PCI_BASE_ADDRESS_SPACE_IO
;
135 mem_type
= base_low
& PCI_BASE_ADDRESS_MEM_TYPE_MASK
;
137 if (mem_type
== PCI_BASE_ADDRESS_MEM_TYPE_64
) {
138 dm_pci_read_config32(dev
, reg_addr
, &base_high
);
139 dm_pci_write_config32(dev
, reg_addr
, 0xffffffff);
140 dm_pci_read_config32(dev
, reg_addr
, &size_high
);
141 dm_pci_write_config32(dev
, reg_addr
, base_high
);
147 base
= base
| ((u64
)base_high
<< 32);
148 size
= size
| ((u64
)size_high
<< 32);
150 if ((!is_64
&& size_low
) || (is_64
&& size
)) {
152 printf(" %d %#016llx %#016llx %d %s %s\n",
153 bar_id
, (unsigned long long)base
,
154 (unsigned long long)size
, is_64
? 64 : 32,
155 is_io
? "I/O" : "MEM",
156 prefetchable
? "Prefetchable" : "");
167 static struct pci_reg_info regs_start
[] = {
168 { "vendor ID", PCI_SIZE_16
, PCI_VENDOR_ID
},
169 { "device ID", PCI_SIZE_16
, PCI_DEVICE_ID
},
170 { "command register ID", PCI_SIZE_16
, PCI_COMMAND
},
171 { "status register", PCI_SIZE_16
, PCI_STATUS
},
172 { "revision ID", PCI_SIZE_8
, PCI_REVISION_ID
},
176 static struct pci_reg_info regs_rest
[] = {
177 { "sub class code", PCI_SIZE_8
, PCI_CLASS_SUB_CODE
},
178 { "programming interface", PCI_SIZE_8
, PCI_CLASS_PROG
},
179 { "cache line", PCI_SIZE_8
, PCI_CACHE_LINE_SIZE
},
180 { "latency time", PCI_SIZE_8
, PCI_LATENCY_TIMER
},
181 { "header type", PCI_SIZE_8
, PCI_HEADER_TYPE
},
182 { "BIST", PCI_SIZE_8
, PCI_BIST
},
183 { "base address 0", PCI_SIZE_32
, PCI_BASE_ADDRESS_0
},
187 static struct pci_reg_info regs_normal
[] = {
188 { "base address 1", PCI_SIZE_32
, PCI_BASE_ADDRESS_1
},
189 { "base address 2", PCI_SIZE_32
, PCI_BASE_ADDRESS_2
},
190 { "base address 3", PCI_SIZE_32
, PCI_BASE_ADDRESS_3
},
191 { "base address 4", PCI_SIZE_32
, PCI_BASE_ADDRESS_4
},
192 { "base address 5", PCI_SIZE_32
, PCI_BASE_ADDRESS_5
},
193 { "cardBus CIS pointer", PCI_SIZE_32
, PCI_CARDBUS_CIS
},
194 { "sub system vendor ID", PCI_SIZE_16
, PCI_SUBSYSTEM_VENDOR_ID
},
195 { "sub system ID", PCI_SIZE_16
, PCI_SUBSYSTEM_ID
},
196 { "expansion ROM base address", PCI_SIZE_32
, PCI_ROM_ADDRESS
},
197 { "interrupt line", PCI_SIZE_8
, PCI_INTERRUPT_LINE
},
198 { "interrupt pin", PCI_SIZE_8
, PCI_INTERRUPT_PIN
},
199 { "min Grant", PCI_SIZE_8
, PCI_MIN_GNT
},
200 { "max Latency", PCI_SIZE_8
, PCI_MAX_LAT
},
204 static struct pci_reg_info regs_bridge
[] = {
205 { "base address 1", PCI_SIZE_32
, PCI_BASE_ADDRESS_1
},
206 { "primary bus number", PCI_SIZE_8
, PCI_PRIMARY_BUS
},
207 { "secondary bus number", PCI_SIZE_8
, PCI_SECONDARY_BUS
},
208 { "subordinate bus number", PCI_SIZE_8
, PCI_SUBORDINATE_BUS
},
209 { "secondary latency timer", PCI_SIZE_8
, PCI_SEC_LATENCY_TIMER
},
210 { "IO base", PCI_SIZE_8
, PCI_IO_BASE
},
211 { "IO limit", PCI_SIZE_8
, PCI_IO_LIMIT
},
212 { "secondary status", PCI_SIZE_16
, PCI_SEC_STATUS
},
213 { "memory base", PCI_SIZE_16
, PCI_MEMORY_BASE
},
214 { "memory limit", PCI_SIZE_16
, PCI_MEMORY_LIMIT
},
215 { "prefetch memory base", PCI_SIZE_16
, PCI_PREF_MEMORY_BASE
},
216 { "prefetch memory limit", PCI_SIZE_16
, PCI_PREF_MEMORY_LIMIT
},
217 { "prefetch memory base upper", PCI_SIZE_32
, PCI_PREF_BASE_UPPER32
},
218 { "prefetch memory limit upper", PCI_SIZE_32
, PCI_PREF_LIMIT_UPPER32
},
219 { "IO base upper 16 bits", PCI_SIZE_16
, PCI_IO_BASE_UPPER16
},
220 { "IO limit upper 16 bits", PCI_SIZE_16
, PCI_IO_LIMIT_UPPER16
},
221 { "expansion ROM base address", PCI_SIZE_32
, PCI_ROM_ADDRESS1
},
222 { "interrupt line", PCI_SIZE_8
, PCI_INTERRUPT_LINE
},
223 { "interrupt pin", PCI_SIZE_8
, PCI_INTERRUPT_PIN
},
224 { "bridge control", PCI_SIZE_16
, PCI_BRIDGE_CONTROL
},
228 static struct pci_reg_info regs_cardbus
[] = {
229 { "capabilities", PCI_SIZE_8
, PCI_CB_CAPABILITY_LIST
},
230 { "secondary status", PCI_SIZE_16
, PCI_CB_SEC_STATUS
},
231 { "primary bus number", PCI_SIZE_8
, PCI_CB_PRIMARY_BUS
},
232 { "CardBus number", PCI_SIZE_8
, PCI_CB_CARD_BUS
},
233 { "subordinate bus number", PCI_SIZE_8
, PCI_CB_SUBORDINATE_BUS
},
234 { "CardBus latency timer", PCI_SIZE_8
, PCI_CB_LATENCY_TIMER
},
235 { "CardBus memory base 0", PCI_SIZE_32
, PCI_CB_MEMORY_BASE_0
},
236 { "CardBus memory limit 0", PCI_SIZE_32
, PCI_CB_MEMORY_LIMIT_0
},
237 { "CardBus memory base 1", PCI_SIZE_32
, PCI_CB_MEMORY_BASE_1
},
238 { "CardBus memory limit 1", PCI_SIZE_32
, PCI_CB_MEMORY_LIMIT_1
},
239 { "CardBus IO base 0", PCI_SIZE_16
, PCI_CB_IO_BASE_0
},
240 { "CardBus IO base high 0", PCI_SIZE_16
, PCI_CB_IO_BASE_0_HI
},
241 { "CardBus IO limit 0", PCI_SIZE_16
, PCI_CB_IO_LIMIT_0
},
242 { "CardBus IO limit high 0", PCI_SIZE_16
, PCI_CB_IO_LIMIT_0_HI
},
243 { "CardBus IO base 1", PCI_SIZE_16
, PCI_CB_IO_BASE_1
},
244 { "CardBus IO base high 1", PCI_SIZE_16
, PCI_CB_IO_BASE_1_HI
},
245 { "CardBus IO limit 1", PCI_SIZE_16
, PCI_CB_IO_LIMIT_1
},
246 { "CardBus IO limit high 1", PCI_SIZE_16
, PCI_CB_IO_LIMIT_1_HI
},
247 { "interrupt line", PCI_SIZE_8
, PCI_INTERRUPT_LINE
},
248 { "interrupt pin", PCI_SIZE_8
, PCI_INTERRUPT_PIN
},
249 { "bridge control", PCI_SIZE_16
, PCI_CB_BRIDGE_CONTROL
},
250 { "subvendor ID", PCI_SIZE_16
, PCI_CB_SUBSYSTEM_VENDOR_ID
},
251 { "subdevice ID", PCI_SIZE_16
, PCI_CB_SUBSYSTEM_ID
},
252 { "PC Card 16bit base address", PCI_SIZE_32
, PCI_CB_LEGACY_MODE_BASE
},
257 * pci_header_show() - Show the header of the specified PCI device.
259 * @dev: Bus+Device+Function number
262 void pci_header_show(struct udevice
*dev
)
264 void pci_header_show(pci_dev_t dev
)
268 unsigned long class, header_type
;
270 dm_pci_read_config(dev
, PCI_CLASS_CODE
, &class, PCI_SIZE_8
);
271 dm_pci_read_config(dev
, PCI_HEADER_TYPE
, &header_type
, PCI_SIZE_8
);
273 u8
class, header_type
;
275 pci_read_config_byte(dev
, PCI_CLASS_CODE
, &class);
276 pci_read_config_byte(dev
, PCI_HEADER_TYPE
, &header_type
);
278 pci_show_regs(dev
, regs_start
);
279 printf(" class code = 0x%.2x (%s)\n", (int)class,
280 pci_class_str(class));
281 pci_show_regs(dev
, regs_rest
);
283 switch (header_type
& 0x03) {
284 case PCI_HEADER_TYPE_NORMAL
: /* "normal" PCI device */
285 pci_show_regs(dev
, regs_normal
);
287 case PCI_HEADER_TYPE_BRIDGE
: /* PCI-to-PCI bridge */
288 pci_show_regs(dev
, regs_bridge
);
290 case PCI_HEADER_TYPE_CARDBUS
: /* PCI-to-CardBus bridge */
291 pci_show_regs(dev
, regs_cardbus
);
295 printf("unknown header\n");
300 void pciinfo_header(int busnum
, bool short_listing
)
302 printf("Scanning PCI devices on bus %d\n", busnum
);
305 printf("BusDevFun VendorId DeviceId Device Class Sub-Class\n");
306 printf("_____________________________________________________________\n");
312 * pci_header_show_brief() - Show the short-form PCI device header
314 * Reads and prints the header of the specified PCI device in short form.
316 * @dev: PCI device to show
318 static void pci_header_show_brief(struct udevice
*dev
)
320 ulong vendor
, device
;
321 ulong
class, subclass
;
323 dm_pci_read_config(dev
, PCI_VENDOR_ID
, &vendor
, PCI_SIZE_16
);
324 dm_pci_read_config(dev
, PCI_DEVICE_ID
, &device
, PCI_SIZE_16
);
325 dm_pci_read_config(dev
, PCI_CLASS_CODE
, &class, PCI_SIZE_8
);
326 dm_pci_read_config(dev
, PCI_CLASS_SUB_CODE
, &subclass
, PCI_SIZE_8
);
328 printf("0x%.4lx 0x%.4lx %-23s 0x%.2lx\n",
330 pci_class_str(class), subclass
);
333 static void pciinfo(struct udevice
*bus
, bool short_listing
)
337 pciinfo_header(bus
->seq
, short_listing
);
339 for (device_find_first_child(bus
, &dev
);
341 device_find_next_child(&dev
)) {
342 struct pci_child_platdata
*pplat
;
344 pplat
= dev_get_parent_platdata(dev
);
346 printf("%02x.%02x.%02x ", bus
->seq
,
347 PCI_DEV(pplat
->devfn
), PCI_FUNC(pplat
->devfn
));
348 pci_header_show_brief(dev
);
350 printf("\nFound PCI device %02x.%02x.%02x:\n", bus
->seq
,
351 PCI_DEV(pplat
->devfn
), PCI_FUNC(pplat
->devfn
));
352 pci_header_show(dev
);
360 * pci_header_show_brief() - Show the short-form PCI device header
362 * Reads and prints the header of the specified PCI device in short form.
364 * @dev: Bus+Device+Function number
366 void pci_header_show_brief(pci_dev_t dev
)
371 pci_read_config_word(dev
, PCI_VENDOR_ID
, &vendor
);
372 pci_read_config_word(dev
, PCI_DEVICE_ID
, &device
);
373 pci_read_config_byte(dev
, PCI_CLASS_CODE
, &class);
374 pci_read_config_byte(dev
, PCI_CLASS_SUB_CODE
, &subclass
);
376 printf("0x%.4x 0x%.4x %-23s 0x%.2x\n",
378 pci_class_str(class), subclass
);
382 * pciinfo() - Show a list of devices on the PCI bus
384 * Show information about devices on PCI bus. Depending on @short_pci_listing
385 * the output will be more or less exhaustive.
387 * @bus_num: The number of the bus to be scanned
388 * @short_pci_listing: true to use short form, showing only a brief header
391 void pciinfo(int bus_num
, int short_pci_listing
)
393 struct pci_controller
*hose
= pci_bus_to_hose(bus_num
);
396 unsigned char header_type
;
397 unsigned short vendor_id
;
404 pciinfo_header(bus_num
, short_pci_listing
);
406 for (device
= 0; device
< PCI_MAX_PCI_DEVICES
; device
++) {
409 for (function
= 0; function
< PCI_MAX_PCI_FUNCTIONS
;
412 * If this is not a multi-function device, we skip
415 if (function
&& !(header_type
& 0x80))
418 dev
= PCI_BDF(bus_num
, device
, function
);
420 if (pci_skip_dev(hose
, dev
))
423 ret
= pci_read_config_word(dev
, PCI_VENDOR_ID
,
427 if ((vendor_id
== 0xFFFF) || (vendor_id
== 0x0000))
431 pci_read_config_byte(dev
, PCI_HEADER_TYPE
,
435 if (short_pci_listing
) {
436 printf("%02x.%02x.%02x ", bus_num
, device
,
438 pci_header_show_brief(dev
);
440 printf("\nFound PCI device %02x.%02x.%02x:\n",
441 bus_num
, device
, function
);
442 pci_header_show(dev
);
449 printf("Cannot read bus configuration: %d\n", ret
);
454 * get_pci_dev() - Convert the "bus.device.function" identifier into a number
456 * @name: Device string in the form "bus.device.function" where each is in hex
457 * @return encoded pci_dev_t or -1 if the string was invalid
459 static pci_dev_t
get_pci_dev(char *name
)
463 int bdfs
[3] = {0,0,0};
468 for (i
= 0, iold
= 0, n
= 0; i
< len
; i
++) {
469 if (name
[i
] == '.') {
470 memcpy(cnum
, &name
[iold
], i
- iold
);
471 cnum
[i
- iold
] = '\0';
472 bdfs
[n
++] = simple_strtoul(cnum
, NULL
, 16);
476 strcpy(cnum
, &name
[iold
]);
479 bdfs
[n
] = simple_strtoul(cnum
, NULL
, 16);
481 return PCI_BDF(bdfs
[0], bdfs
[1], bdfs
[2]);
485 static int pci_cfg_display(struct udevice
*dev
, ulong addr
,
486 enum pci_size_t size
, ulong length
)
488 static int pci_cfg_display(pci_dev_t bdf
, ulong addr
, enum pci_size_t size
,
492 #define DISP_LINE_LEN 16
493 ulong i
, nbytes
, linebytes
;
497 byte_size
= pci_byte_size(size
);
499 length
= 0x40 / byte_size
; /* Standard PCI config space */
502 * once, and all accesses are with the specified bus width.
504 nbytes
= length
* byte_size
;
506 printf("%08lx:", addr
);
507 linebytes
= (nbytes
> DISP_LINE_LEN
) ? DISP_LINE_LEN
: nbytes
;
508 for (i
= 0; i
< linebytes
; i
+= byte_size
) {
512 dm_pci_read_config(dev
, addr
, &val
, size
);
514 val
= pci_read_config(bdf
, addr
, size
);
516 printf(" %0*lx", pci_field_width(size
), val
);
525 } while (nbytes
> 0);
530 #ifndef CONFIG_DM_PCI
531 static int pci_cfg_write (pci_dev_t bdf
, ulong addr
, ulong size
, ulong value
)
534 pci_write_config_dword(bdf
, addr
, value
);
536 else if (size
== 2) {
537 ushort val
= value
& 0xffff;
538 pci_write_config_word(bdf
, addr
, val
);
541 u_char val
= value
& 0xff;
542 pci_write_config_byte(bdf
, addr
, val
);
549 static int pci_cfg_modify(struct udevice
*dev
, ulong addr
, ulong size
,
550 ulong value
, int incrflag
)
552 static int pci_cfg_modify(pci_dev_t bdf
, ulong addr
, ulong size
, ulong value
,
560 /* Print the address, followed by value. Then accept input for
561 * the next value. A non-converted value exits.
564 printf("%08lx:", addr
);
566 dm_pci_read_config(dev
, addr
, &val
, size
);
568 val
= pci_read_config(bdf
, addr
, size
);
570 printf(" %0*lx", pci_field_width(size
), val
);
572 nbytes
= cli_readline(" ? ");
573 if (nbytes
== 0 || (nbytes
== 1 && console_buffer
[0] == '-')) {
574 /* <CR> pressed as only input, don't modify current
575 * location and move to next. "-" pressed will go back.
578 addr
+= nbytes
? -size
: size
;
580 /* good enough to not time out */
581 bootretry_reset_cmd_timeout();
583 #ifdef CONFIG_BOOT_RETRY_TIME
584 else if (nbytes
== -2) {
585 break; /* timed out, exit the command */
590 i
= simple_strtoul(console_buffer
, &endp
, 16);
591 nbytes
= endp
- console_buffer
;
593 /* good enough to not time out
595 bootretry_reset_cmd_timeout();
597 dm_pci_write_config(dev
, addr
, i
, size
);
599 pci_cfg_write(bdf
, addr
, size
, i
);
611 static const struct pci_flag_info
{
614 } pci_flag_info
[] = {
615 { PCI_REGION_IO
, "io" },
616 { PCI_REGION_PREFETCH
, "prefetch" },
617 { PCI_REGION_SYS_MEMORY
, "sysmem" },
618 { PCI_REGION_RO
, "readonly" },
619 { PCI_REGION_IO
, "io" },
622 static void pci_show_regions(struct udevice
*bus
)
624 struct pci_controller
*hose
= dev_get_uclass_priv(bus
);
625 const struct pci_region
*reg
;
629 printf("Bus '%s' is not a PCI controller\n", bus
->name
);
633 printf("# %-16s %-16s %-16s %s\n", "Bus start", "Phys start", "Size",
635 for (i
= 0, reg
= hose
->regions
; i
< hose
->region_count
; i
++, reg
++) {
636 printf("%d %#016llx %#016llx %#016llx ", i
,
637 (unsigned long long)reg
->bus_start
,
638 (unsigned long long)reg
->phys_start
,
639 (unsigned long long)reg
->size
);
640 if (!(reg
->flags
& PCI_REGION_TYPE
))
642 for (j
= 0; j
< ARRAY_SIZE(pci_flag_info
); j
++) {
643 if (reg
->flags
& pci_flag_info
[j
].flag
)
644 printf("%s ", pci_flag_info
[j
].name
);
651 /* PCI Configuration Space access commands
654 * pci display[.b, .w, .l] bus.device.function} [addr] [len]
655 * pci next[.b, .w, .l] bus.device.function [addr]
656 * pci modify[.b, .w, .l] bus.device.function [addr]
657 * pci write[.b, .w, .l] bus.device.function addr value
659 static int do_pci(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
661 ulong addr
= 0, value
= 0, cmd_size
= 0;
662 enum pci_size_t size
= PCI_SIZE_32
;
664 struct udevice
*dev
, *bus
;
677 case 'd': /* display */
679 case 'm': /* modify */
680 case 'w': /* write */
681 /* Check for a size specification. */
682 cmd_size
= cmd_get_data_size(argv
[1], 4);
683 size
= (cmd_size
== 4) ? PCI_SIZE_32
: cmd_size
- 1;
685 addr
= simple_strtoul(argv
[3], NULL
, 16);
687 value
= simple_strtoul(argv
[4], NULL
, 16);
688 case 'h': /* header */
694 if ((bdf
= get_pci_dev(argv
[2])) == -1)
697 #if defined(CONFIG_DM_PCI)
702 case 'r': /* no break */
703 default: /* scan bus */
704 value
= 1; /* short listing */
706 if (cmd
!= 'r' && argv
[argc
-1][0] == 'l') {
711 busnum
= simple_strtoul(argv
[1], NULL
, 16);
714 ret
= uclass_get_device_by_seq(UCLASS_PCI
, busnum
, &bus
);
716 printf("No such bus\n");
717 return CMD_RET_FAILURE
;
720 pci_show_regions(bus
);
724 pciinfo(busnum
, value
);
730 ret
= dm_pci_bus_find_bdf(bdf
, &dev
);
732 printf("No such device\n");
733 return CMD_RET_FAILURE
;
739 switch (argv
[1][0]) {
740 case 'h': /* header */
741 pci_header_show(dev
);
743 case 'd': /* display */
744 return pci_cfg_display(dev
, addr
, size
, value
);
748 ret
= pci_cfg_modify(dev
, addr
, size
, value
, 0);
750 case 'm': /* modify */
753 ret
= pci_cfg_modify(dev
, addr
, size
, value
, 1);
755 case 'w': /* write */
759 ret
= dm_pci_write_config(dev
, addr
, value
, size
);
761 ret
= pci_cfg_write(dev
, addr
, size
, value
);
767 return pci_bar_show(dev
);
776 return CMD_RET_USAGE
;
779 /***************************************************/
781 #ifdef CONFIG_SYS_LONGHELP
782 static char pci_help_text
[] =
784 " - short or long list of PCI devices on bus 'bus'\n"
785 #if defined(CONFIG_DM_PCI)
787 " - Enumerate PCI buses\n"
790 " - show header of PCI device 'bus.device.function'\n"
793 " - show BARs base and size for device b.d.f'\n"
795 " - show PCI regions\n"
797 "pci display[.b, .w, .l] b.d.f [address] [# of objects]\n"
798 " - display PCI configuration space (CFG)\n"
799 "pci next[.b, .w, .l] b.d.f address\n"
800 " - modify, read and keep CFG address\n"
801 "pci modify[.b, .w, .l] b.d.f address\n"
802 " - modify, auto increment CFG address\n"
803 "pci write[.b, .w, .l] b.d.f address value\n"
804 " - write to CFG address";
809 "list and access PCI Configuration Space", pci_help_text