New issue
Advanced search Search tips

Issue 1046 attachment: dump_pci.py (5.5 KB)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import sys, struct

#The offset of the RAM on chip
RAM_OFFSET = 0x180000

#The size of the chip's RAM
RAM_SIZE = 0xC0000

#The number of bytes in a DWORD
DWORD_SIZE = 4

#The maximal ring number
BCMPCIE_COMMON_MSGRING_MAX_ID = 4

RING_NAMES = {0 : 'H2D_MSGRING_CONTROL_SUBMIT',
1 : 'H2D_MSGRING_RXPOST_SUBMIT',
2 : 'D2H_MSGRING_CONTROL_COMPLETE',
3 : 'D2H_MSGRING_TX_COMPLETE',
4 : 'D2H_MSGRING_RX_COMPLETE',
5 : 'TX_FLOW_RING'}

def read_dword(dump, address):
'''
Reads a single DWORD from the RAM dump at the given address
'''
address -= RAM_OFFSET
return struct.unpack("<I", dump[address:address + DWORD_SIZE])[0]

def read_qword(dump, address):
'''
Reads a single QWORD form the RAM dump at the given address
'''
address -= RAM_OFFSET
return struct.unpack("<Q", dump[address:address + 2*DWORD_SIZE])[0]

def main():
if len(sys.argv) != 2:
print "USAGE: %s <DUMP_FILE>" % sys.argv[0]
return
dump_file_path = sys.argv[1]
dump = open(dump_file_path, 'rb').read()

#Reading the address of the shared structure (pciedev_shared_t)
pciedev_shared_t_addr = read_dword(dump, RAM_OFFSET + RAM_SIZE - DWORD_SIZE)
print "Dumping pciedev_shared_t from 0x%08X" % pciedev_shared_t_addr
print "-----------------------------------------"
print "flags: 0x%08X" % read_dword(dump, pciedev_shared_t_addr + 0 * DWORD_SIZE)
print "trap_addr: 0x%08X" % read_dword(dump, pciedev_shared_t_addr + 1 * DWORD_SIZE)
print "assert_exp_addr: 0x%08X" % read_dword(dump, pciedev_shared_t_addr + 2 * DWORD_SIZE)
print "assert_file_addr: 0x%08X" % read_dword(dump, pciedev_shared_t_addr + 3 * DWORD_SIZE)
print "assert_line: 0x%08X" % read_dword(dump, pciedev_shared_t_addr + 4 * DWORD_SIZE)
print "console_addr: 0x%08X" % read_dword(dump, pciedev_shared_t_addr + 5 * DWORD_SIZE)
print "msgtrace_addr: 0x%08X" % read_dword(dump, pciedev_shared_t_addr + 6 * DWORD_SIZE)
print "fwid: 0x%08X" % read_dword(dump, pciedev_shared_t_addr + 7 * DWORD_SIZE)
print "total_lfrag_pkt_cnt: 0x%08X" % (read_dword(dump, pciedev_shared_t_addr + 8 * DWORD_SIZE) & 0xFFFF)
print "max_host_rxbufs: 0x%08X" % ((read_dword(dump, pciedev_shared_t_addr + 8 * DWORD_SIZE) >> 16) & 0xFFFF)
print "dma_rxoffset: 0x%08X" % read_dword(dump, pciedev_shared_t_addr + 9 * DWORD_SIZE)
print "h2d_mb_data_ptr: 0x%08X" % read_dword(dump, pciedev_shared_t_addr + 10 * DWORD_SIZE)
print "d2h_mb_data_ptr: 0x%08X" % read_dword(dump, pciedev_shared_t_addr + 11 * DWORD_SIZE)
print "rings_info_ptr: 0x%08X" % read_dword(dump, pciedev_shared_t_addr + 12 * DWORD_SIZE)
print "host_dma_scratch_buffer_len: 0x%08X" % read_dword(dump, pciedev_shared_t_addr + 13 * DWORD_SIZE)
print "host_dma_scratch_buffer: 0x%08X" % read_dword(dump, pciedev_shared_t_addr + 14 * DWORD_SIZE)
print "device_rings_stsblk_len: 0x%08X" % read_dword(dump, pciedev_shared_t_addr + 15 * DWORD_SIZE)
print "device_rings_stsblk: 0x%08X" % read_dword(dump, pciedev_shared_t_addr + 16 * DWORD_SIZE)

#Dumping the ring buffer physical addresses
rings_info_ptr = read_dword(dump, pciedev_shared_t_addr + 12 * DWORD_SIZE)
print
print "Dumping ring_info"
print "-----------------------------------------"
print "h2d_w_idx_ptr: 0x%08X" % read_dword(dump, rings_info_ptr + 1 * DWORD_SIZE)
print "h2d_r_idx_ptr: 0x%08X" % read_dword(dump, rings_info_ptr + 2 * DWORD_SIZE)
print "d2h_w_idx_ptr: 0x%08X" % read_dword(dump, rings_info_ptr + 3 * DWORD_SIZE)
print "d2h_r_idx_ptr: 0x%08X" % read_dword(dump, rings_info_ptr + 4 * DWORD_SIZE)
print "h2d_w_idx_hostaddr: 0x%08X" % read_qword(dump, rings_info_ptr + 5 * DWORD_SIZE)
print "h2d_r_idx_hostaddr: 0x%08X" % read_qword(dump, rings_info_ptr + 7 * DWORD_SIZE)
print "d2h_w_idx_hostaddr: 0x%08X" % read_qword(dump, rings_info_ptr + 9 * DWORD_SIZE)
print "d2h_r_idx_hostaddr: 0x%08X" % read_qword(dump, rings_info_ptr + 11 * DWORD_SIZE)

#Dumping each of the rings' metadata (ring_mem_t)
ringmem_ptr = read_dword(dump, rings_info_ptr)
print
print "Dumping ring metadata"
print "-----------------------------------------"
for i in range(0, BCMPCIE_COMMON_MSGRING_MAX_ID+1):
idx, ringtype, rsvd = struct.unpack("<HBB", struct.pack("<I", read_dword(dump, ringmem_ptr + i * 4 * DWORD_SIZE)))
max_items, len_items = struct.unpack("<HH", struct.pack("<I", read_dword(dump, ringmem_ptr + i * 4 * DWORD_SIZE + DWORD_SIZE)))
ringaddr_ptr = ringmem_ptr + i * 4 * DWORD_SIZE + 2*DWORD_SIZE
ringaddr = read_qword(dump, ringaddr_ptr)
print "ring: %d" % i
print "idx: %d" % idx
print "ring name: %s" % RING_NAMES[i]
print "ringtype: %d" % ringtype
print "rsvd: %d" % rsvd
print "max_items: %d" % max_items
print "len_items: %d" % len_items
print "ringaddr: 0x%08X (mem 0x%08X)" % (ringaddr, ringaddr_ptr)
print "ring size: %d" % (max_items * len_items)
print

if __name__ == "__main__":
main()