nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | #!/usr/bin/env python |
2 | """ |
||
3 | # b43 firmware state dumper |
||
4 | # |
||
5 | # Copyright (C) 2008 Michael Buesch <m@bues.ch> |
||
6 | # |
||
7 | # This program is free software: you can redistribute it and/or modify |
||
8 | # it under the terms of the GNU General Public License version 3 |
||
9 | # as published by the Free Software Foundation. |
||
10 | # |
||
11 | # This program is distributed in the hope that it will be useful, |
||
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
14 | # GNU General Public License for more details. |
||
15 | # |
||
16 | # You should have received a copy of the GNU General Public License |
||
17 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
18 | """ |
||
19 | |||
20 | import getopt |
||
21 | from libb43 import * |
||
22 | from sys import stdout |
||
23 | from tempfile import * |
||
24 | import re |
||
25 | |||
26 | |||
27 | def usage(): |
||
28 | print "b43 firmware state dumper" |
||
29 | print "" |
||
30 | print "Copyright (C) 2008 Michael Buesch <m@bues.ch>" |
||
31 | print "Licensed under the GNU/GPL version 3" |
||
32 | print "" |
||
33 | print "Usage: b43-fwdump [OPTIONS]" |
||
34 | print "" |
||
35 | print "-h|--help Print this help text" |
||
36 | print "-p|--phy WIPHY The WIPHY to use. For example phy0." |
||
37 | print " Can be omitted, if there is only one device in the system." |
||
38 | print "-b|--binary BIN The firmware binary. This is required for" |
||
39 | print " an instruction dump." |
||
40 | print "-d|--dasmopt OPT Additional options to the disassembler." |
||
41 | print "-s|--shm Also dump SHM." |
||
42 | print "-S|--shmbin Do a binary SHM dump, only." |
||
43 | return |
||
44 | |||
45 | def parseArgs(): |
||
46 | global phy |
||
47 | global binary |
||
48 | global dasmopt |
||
49 | global dumpShm |
||
50 | global dumpShmBin |
||
51 | |||
52 | phy = None # Autodetect |
||
53 | binary = None # No instruction dump |
||
54 | dasmopt = "" |
||
55 | dumpShm = False |
||
56 | dumpShmBin = False |
||
57 | |||
58 | try: |
||
59 | (opts, args) = getopt.getopt(sys.argv[1:], |
||
60 | "hp:b:d:sS", |
||
61 | [ "help", "phy=", "binary=", "dasmopt=", "shm", "shmbin" ]) |
||
62 | except getopt.GetoptError: |
||
63 | usage() |
||
64 | sys.exit(1) |
||
65 | |||
66 | for (o, v) in opts: |
||
67 | if o in ("-h", "--help"): |
||
68 | usage() |
||
69 | sys.exit(0) |
||
70 | if o in ("-p", "--phy"): |
||
71 | phy = v |
||
72 | if o in ("-b", "--binary"): |
||
73 | binary = v |
||
74 | if o in ("-d", "--dasmopt"): |
||
75 | dasmopt = v |
||
76 | if o in ("-s", "--shm"): |
||
77 | dumpShm = True |
||
78 | if o in ("-S", "--shmbin"): |
||
79 | dumpShmBin = True |
||
80 | return |
||
81 | |||
82 | |||
83 | def dump_regs(prefix, regs): |
||
84 | if len(regs) >= 10: |
||
85 | template = "%s%02u: %04X " |
||
86 | else: |
||
87 | template = "%s%01u: %04X " |
||
88 | for i in range(0, len(regs)): |
||
89 | if i != 0 and i % 4 == 0: |
||
90 | stdout.write("\n") |
||
91 | stdout.write(template % (prefix, i, regs[i])) |
||
92 | stdout.write("\n") |
||
93 | return |
||
94 | |||
95 | def dasmLineIsPC(line, pc): |
||
96 | m = re.match(r'.*/\*\s+([0-9a-fA-F]+)\s+\*/.*', line, re.DOTALL) |
||
97 | if not m: |
||
98 | return False |
||
99 | linePC = int(m.group(1), 16) |
||
100 | return pc == linePC |
||
101 | |||
102 | def makeShortDump(dasm, pc): |
||
103 | dasm = dasm.splitlines() |
||
104 | i = 0 |
||
105 | for line in dasm: |
||
106 | if dasmLineIsPC(line, pc): |
||
107 | break |
||
108 | i += 1 |
||
109 | else: |
||
110 | return "<Could not find PC in the binary>" |
||
111 | ret = "" |
||
112 | pos = max(i - 8, 0) |
||
113 | end = min(i + 8, len(dasm) - 1) |
||
114 | while pos != end: |
||
115 | ret += dasm[pos] |
||
116 | if dasmLineIsPC(dasm[pos], pc): |
||
117 | ret += "\t\t<<<<<<<<<<<" |
||
118 | ret += "\n" |
||
119 | pos += 1 |
||
120 | return ret |
||
121 | |||
122 | def toAscii(char): |
||
123 | if char >= 32 and char <= 126: |
||
124 | return chr(char) |
||
125 | return "." |
||
126 | |||
127 | def main(): |
||
128 | parseArgs() |
||
129 | |||
130 | b43 = B43(phy) |
||
131 | |||
132 | # Fetch the hardware information |
||
133 | b43.ucodeStop() |
||
134 | gpr = b43.getGprs() |
||
135 | lr = b43.getLinkRegs() |
||
136 | off = b43.getOffsetRegs() |
||
137 | if dumpShm or dumpShmBin: |
||
138 | shm = b43.shmSharedRead() |
||
139 | dbg = b43.getPsmDebug() |
||
140 | psmcond = b43.getPsmConditions() |
||
141 | b43.ucodeStart() |
||
142 | |||
143 | if dumpShmBin: |
||
144 | # Only do a binary SHM dump |
||
145 | stdout.write(shm) |
||
146 | sys.exit(0) |
||
147 | |||
148 | print "--- B43 microcode state dump ---" |
||
149 | print "PC: %03X PSM-COND: %04X" % (dbg.getPc(), psmcond) |
||
150 | print "Link registers:" |
||
151 | dump_regs("lr", lr) |
||
152 | print "Offset registers:" |
||
153 | dump_regs("off", off) |
||
154 | print "General purpose registers:" |
||
155 | dump_regs("r", gpr) |
||
156 | |||
157 | print "Code:" |
||
158 | if binary: |
||
159 | try: |
||
160 | bintext = file(binary, "r").read() |
||
161 | except IOError, e: |
||
162 | print "Could not read binary file %s: %s" % (binary, e.strerror) |
||
163 | sys.exit(1) |
||
164 | dasm = Disassembler(bintext, dasmopt + "--paddr").getAsm() |
||
165 | print makeShortDump(dasm, dbg.getPc()) |
||
166 | else: |
||
167 | print "<No binary supplied. See --binary option>" |
||
168 | |||
169 | if dumpShm: |
||
170 | print "Shared memory:" |
||
171 | ascii = "" |
||
172 | for i in range(0, len(shm)): |
||
173 | if i % 16 == 0 and i != 0: |
||
174 | stdout.write(" " + ascii + "\n") |
||
175 | ascii = "" |
||
176 | if i % 16 == 0: |
||
177 | stdout.write("0x%04X: " % i) |
||
178 | c = ord(shm[i]) |
||
179 | stdout.write("%02X" % c) |
||
180 | if (i % 2 != 0): |
||
181 | stdout.write(" ") |
||
182 | ascii += toAscii(c) |
||
183 | stdout.write(" " + ascii + "\n") |
||
184 | return |
||
185 | |||
186 | |||
187 | try: |
||
188 | main() |
||
189 | except B43Exception: |
||
190 | sys.exit(1) |