3 ######################################
5 ######################################
6 def GetMemMappedPciCfgAddrFromRegistry():
7 """ Retrieve the base address of the memory mapped PCI config space. It is
8 found in registry entry AppleACPIPlatformExpert, property acpi-mmcfg-seg0.
10 int base address of memory mapped PCI config space
12 kgm_pci_cfg_base_default
= 0xe0000000
13 acpi_pe_obj
= FindRegistryObjectRecurse(kern
.globals.gRegistryRoot
,
14 "AppleACPIPlatformExpert")
15 if acpi_pe_obj
is None:
16 print "Could not find AppleACPIPlatformExpert in registry, \
17 using default base address for memory mapped PCI config space"
18 return kgm_pci_cfg_base_default
19 entry
= kern
.GetValueFromAddress(int(acpi_pe_obj
), 'IOService *')
20 acpi_mmcfg_seg_prop
= LookupKeyInPropTable(entry
.fPropertyTable
, "acpi-mmcfg-seg0")
21 if acpi_mmcfg_seg_prop
is None:
22 print "Could not find acpi-mmcfg-seg0 property, \
23 using default base address for memory mapped PCI config space"
24 return kgm_pci_cfg_base_default
26 return int(GetNumber(acpi_mmcfg_seg_prop
))
28 @static_var('kgm_pci_cfg_base', -1)
29 def GetMemMappedPciCfgAddrBase():
30 """ Returns the base address of the memory mapped PCI config space. The address
31 is retrieved once from the registry, and is remembered for all subsequent
32 calls to this function
34 int base address of memory mapped PCI config space
36 if GetMemMappedPciCfgAddrBase
.kgm_pci_cfg_base
== -1:
37 # Retrieve the base address from the registry if it hasn't been
39 GetMemMappedPciCfgAddrBase
.kgm_pci_cfg_base
= GetMemMappedPciCfgAddrFromRegistry()
40 return GetMemMappedPciCfgAddrBase
.kgm_pci_cfg_base
42 def MakeMemMappedPciCfgAddr(bus
, dev
, func
, offs
):
43 """ Construct the memory address for the PCI config register specified by the
44 bus, device, function, and offset
46 bus, dev, func, offs: int - bus, device, function, and offset that specifies
47 the PCI config space register
49 int - the physical memory address that maps to the PCI config space register
51 return GetMemMappedPciCfgAddrBase() |
(bus
<< 20) |
(dev
<< 15) |
(func
<< 12) | offs
53 def DoPciCfgRead(bits
, bus
, dev
, func
, offs
):
54 """ Helper function that performs PCI config space read
56 bits: int - bit width of access: 8, 16, or 32 bits
57 bus, dev, func, offs: int - PCI config bus, device, function and offset
59 int - the value read from PCI config space
61 phys_addr
= MakeMemMappedPciCfgAddr(bus
, dev
, func
, offs
)
62 return ReadPhysInt(phys_addr
, bits
)
64 def DoPciCfgWrite(bits
, bus
, dev
, func
, offs
, val
):
65 """ Helper function that performs PCI config space write
67 bits: int - bit width of access: 8, 16, or 32 bits
68 bus, dev, func, offs: int - PCI config bus, device, function and offset
70 boolean - True upon success, False otherwise
72 phys_addr
= MakeMemMappedPciCfgAddr(bus
, dev
, func
, offs
)
73 return WritePhysInt(phys_addr
, val
, bits
)
75 def ShowPciCfgBytes(bus
, dev
, func
, offset
):
76 """ Prints 16 bytes of PCI config space starting at specified offset
78 bus, dev, func, offset: int - bus, dev, function, and offset of the
79 PCI config space register
81 # Print mem-mapped address at beginning of each 16-byte line
82 phys_addr
= MakeMemMappedPciCfgAddr(bus
, dev
, func
, offset
)
83 read_vals
= [DoPciCfgRead(32, bus
, dev
, func
, offset
+ byte
)
84 for byte
in range(0, 16, 4)]
85 # It would be nicer to have a shorter format that we could loop
86 # over, but each call to print results in a newline which
87 # would prevent us from printing all 16 bytes on one line.
88 bytes_fmt
= "{:08x}:" + "{:02x} " * 16
89 print bytes_fmt
.format(
91 read_vals
[0] & 0xff, (read_vals
[0] >> 8) & 0xff,
92 (read_vals
[0] >> 16) & 0xff, (read_vals
[0] >> 24) & 0xff,
93 read_vals
[1] & 0xff, (read_vals
[1] >> 8) & 0xff,
94 (read_vals
[1] >> 16) & 0xff, (read_vals
[1] >> 24) & 0xff,
95 read_vals
[2] & 0xff, (read_vals
[2] >> 8) & 0xff,
96 (read_vals
[2] >> 16) & 0xff, (read_vals
[2] >> 24) & 0xff,
97 read_vals
[3] & 0xff, (read_vals
[3] >> 8) & 0xff,
98 (read_vals
[3] >> 16) & 0xff, (read_vals
[3] >> 24) & 0xff)
100 def DoPciCfgDump(bus
, dev
, func
):
101 """ Dumps PCI config space of the PCI device specified by bus, dev, function
103 bus, dev, func: int - bus, dev, function of PCI config space to dump
105 # Check for a valid PCI device
106 vendor_id
= DoPciCfgRead(16, bus
, dev
, func
, 0)
107 if (vendor_id
== 0xbad10ad) or not (vendor_id
> 0 and vendor_id
< 0xffff):
109 # Show the standard PCI config space
110 print "address: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n"
111 print "--------------------------------------------------------"
112 for offset
in range(0, 256, 16):
113 ShowPciCfgBytes(bus
, dev
, func
, offset
)
114 # Check for PCIE extended capability config space
115 if DoPciCfgRead(8, bus
, dev
, func
, 256) < 0xff:
117 for offset
in range(256, 4096, 16):
118 ShowPciCfgBytes(bus
, dev
, func
, offset
)
120 def DoPciCfgScan(max_bus
, dump
):
121 """ Do a PCI config scan starting at bus 0 up to specified max bus
123 max_bus: int - maximum bus to scan
124 dump: bool - if True, dump the config space of each scanned device
125 if False, print basic information of each scanned device
129 bdfs
= ({'bus':bus, 'dev':dev, 'func':func}
130 for bus
in range(max_bus
)
131 for dev
in range(max_dev
)
132 for func
in range(max_func
))
133 fmt_string
= "{:03x}:" * 3 + " " + \
134 "{:02x}" * 2 + " " + \
135 "{:02x}" * 2 + " {:02x} | " + \
141 vend_dev_id
= DoPciCfgRead(32, bus
, dev
, func
, 0)
142 if not (vend_dev_id
> 0 and vend_dev_id
< 0xffffffff):
145 class_rev_id
= DoPciCfgRead(32, bus
, dev
, func
, 8)
146 print fmt_string
.format(
148 (vend_dev_id
>> 8) & 0xff, vend_dev_id
& 0xff,
149 (vend_dev_id
>> 24) & 0xff, (vend_dev_id
>> 16) & 0xff,
150 class_rev_id
& 0xff, (class_rev_id
>> 24) & 0xff,
151 (class_rev_id
>> 16) & 0xff, (class_rev_id
>> 8) & 0xff)
153 print "{:03x}:{:03x}:{:03x}".format(bus
, dev
, func
)
154 DoPciCfgDump(bus
, dev
, func
)
156 ######################################
158 ######################################
159 @lldb_command('pci_cfg_read')
160 def PciCfgRead(cmd_args
=None):
161 """ Read PCI config space at the specified bus, device, function, and offset
162 Syntax: pci_cfg_read <bits> <bus> <device> <function> <offset>
165 if cmd_args
== None or len(cmd_args
) < 5:
166 print PciCfgRead
.__doc
__
169 bits
= ArgumentStringToInt(cmd_args
[0])
170 bus
= ArgumentStringToInt(cmd_args
[1])
171 dev
= ArgumentStringToInt(cmd_args
[2])
172 func
= ArgumentStringToInt(cmd_args
[3])
173 offs
= ArgumentStringToInt(cmd_args
[4])
175 read_val
= DoPciCfgRead(bits
, bus
, dev
, func
, offs
)
176 if read_val
== 0xbad10ad:
177 print "ERROR: Failed to read PCI config space"
180 format_for_bits
= {8:"{:#04x}
", 16:"{:#06x}
", 32:"{:#010x}
"}
181 phys_addr = MakeMemMappedPciCfgAddr(bus, dev, func, offs)
182 fmt_string = "{:08x}
: " + format_for_bits[bits]
183 print fmt_string.format(phys_addr, read_val)
185 lldb_alias('pci_cfg_read8', 'pci_cfg_read 8')
186 lldb_alias('pci_cfg_read16', 'pci_cfg_read 16')
187 lldb_alias('pci_cfg_read32', 'pci_cfg_read 32')
189 @lldb_command('pci_cfg_write')
190 def PciCfgWrite(cmd_args=None):
191 """ Write PCI config space at the specified bus, device, function, and offset
192 Syntax: pci_cfg_write <bits> <bus> <device> <function> <offset> <write val>
195 Prints an error message if there was a problem
196 Prints nothing upon success.
198 if cmd_args == None or len(cmd_args) < 6:
199 print PciCfgWrite.__doc__
202 bits = ArgumentStringToInt(cmd_args[0])
203 bus = ArgumentStringToInt(cmd_args[1])
204 dev = ArgumentStringToInt(cmd_args[2])
205 func = ArgumentStringToInt(cmd_args[3])
206 offs = ArgumentStringToInt(cmd_args[4])
207 write_val = ArgumentStringToInt(cmd_args[5])
209 if DoPciCfgWrite(bits, bus, dev, func, offs, write_val) == False:
210 print "ERROR
: Failed to write PCI config space
"
212 lldb_alias('pci_cfg_write8', 'pci_cfg_write 8')
213 lldb_alias('pci_cfg_write16', 'pci_cfg_write 16')
214 lldb_alias('pci_cfg_write32', 'pci_cfg_write 32')
216 @lldb_command('pci_cfg_dump')
217 def PciCfgDump(cmd_args=None):
218 """ Dump PCI config space for specified bus, device, and function
219 If an invalid/inaccessible PCI device is specified, nothing will
221 Syntax: pci_cfg_dump <bus> <dev> <fuction>
223 if cmd_args == None or len(cmd_args) < 3:
224 print PciCfgDump.__doc__
227 bus = ArgumentStringToInt(cmd_args[0])
228 dev = ArgumentStringToInt(cmd_args[1])
229 func = ArgumentStringToInt(cmd_args[2])
231 DoPciCfgDump(bus, dev, func)
233 @lldb_command('pci_cfg_scan')
234 def PciCfgScan(cmd_args=None):
235 """ Scan for pci devices. The maximum bus number to be scanned defaults to 8,
236 but can be specified as an argument
237 Syntax: pci_cfg_scan [max bus number]
239 if cmd_args == None or len(cmd_args) == 0:
241 elif len(cmd_args) == 1:
242 max_bus = ArgumentStringToInt(cmd_args[0])
244 print PciCfgScan.__doc__
247 print "bus
:dev
:fcn
: vendor device rev |
class"
248 print "--------------------------------------"
249 DoPciCfgScan(max_bus, False)
251 @lldb_command('pci_cfg_dump_all')
252 def PciCfgDumpAll(cmd_args=None):
253 """ Dump config space for all scanned PCI devices. The maximum bus number to
254 be scanned defaults to 8, but can be specified as an argument
255 Syntax: pci_cfg_dump_all [max bus number]
257 if cmd_args == None or len(cmd_args) == 0:
259 elif len(cmd_args) == 1:
260 max_bus = ArgumentStringToInt(cmd_args[0])
262 print PciCfgDumpAll.__doc__
265 DoPciCfgScan(max_bus, True)