24f1f0d23d8e99cbb60b24eb7180e0eec93ee100
[b43-tools.git] / debug / b43-fwdump
1 #!/usr/bin/env python
2 """
3 #  b43 firmware state dumper
4 #
5 #  Copyright (C) 2008 Michael Buesch <mb@bu3sch.de>
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
25
26 def usage():
27         print "b43 firmware state dumper"
28         print ""
29         print "Copyright (C) 2008 Michael Buesch <mb@bu3sch.de>"
30         print "Licensed under the GNU/GPL version 3"
31         print ""
32         print "Usage: b43-fwdump [OPTIONS]"
33         print ""
34         print "-h|--help            Print this help text"
35         print "-p|--phy WIPHY       The WIPHY to use. For example phy0."
36         print "                     Can be omitted, if there is only one device in the system."
37         print "-b|--binary BIN      The firmware binary. This is required for"
38         print "                     an instruction dump."
39         print "-d|--dasmopt OPT     Additional options to the disassembler."
40         print "-s|--shm             Also dump SHM."
41         print "-S|--shmbin          Do a binary SHM dump, only."
42         return
43
44 def parseArgs():
45         global phy
46         global binary
47         global dasmopt
48         global dumpShm
49         global dumpShmBin
50
51         phy = None # Autodetect
52         binary = None # No instruction dump
53         dasmopt = ""
54         dumpShm = False
55         dumpShmBin = False
56
57         try:
58                 (opts, args) = getopt.getopt(sys.argv[1:],
59                         "hp:b:d:sS",
60                         [ "help", "phy=", "binary=", "dasmopt=", "shm", "shmbin" ])
61         except getopt.GetoptError:
62                 usage()
63                 sys.exit(1)
64
65         for (o, v) in opts:
66                 if o in ("-h", "--help"):
67                         usage()
68                         sys.exit(0)
69                 if o in ("-p", "--phy"):
70                         phy = v
71                 if o in ("-b", "--binary"):
72                         binary = v
73                 if o in ("-d", "--dasmopt"):
74                         dasmopt = v
75                 if o in ("-s", "--shm"):
76                         dumpShm = True
77                 if o in ("-S", "--shmbin"):
78                         dumpShmBin = True
79         return
80
81
82 def dump_regs(prefix, regs):
83         if len(regs) >= 10:
84                 template = "%s%02u: %04X  "
85         else:
86                 template = "%s%01u: %04X  "
87         for i in range(0, len(regs)):
88                 if i != 0 and i % 4 == 0:
89                         stdout.write("\n")
90                 stdout.write(template % (prefix, i, regs[i]))
91         stdout.write("\n")
92         return
93
94 def makeShortDump(dasm, pc):
95         dasm = dasm.splitlines()
96         i = 0
97         for line in dasm:
98                 if "/* %03X */" % pc in line:
99                         break
100                 i += 1
101         if i >= len(dasm):
102                 return "<Could not find PC in the binary>"
103         ret = ""
104         pos = max(i - 8, 0)
105         end = min(i + 8, len(dasm) - 1)
106         while pos != end:
107                 ret += dasm[pos]
108                 if "/* %03X */" % pc in dasm[pos]:
109                         ret += "\t\t<<<<<<<<<<<"
110                 ret += "\n"
111                 pos += 1
112         return ret
113
114 def toAscii(char):
115         if char >= 32 and char <= 126:
116                 return chr(char)
117         return "."
118
119 def main():
120         parseArgs()
121
122         b43 = B43(phy)
123
124         # Fetch the hardware information
125         b43.ucodeStop()
126         gpr = b43.getGprs()
127         lr = b43.getLinkRegs()
128         off = b43.getOffsetRegs()
129         if dumpShm or dumpShmBin:
130                 shm = b43.shmSharedRead()
131         dbg = b43.getPsmDebug()
132         psmcond = b43.getPsmConditions()
133         b43.ucodeStart()
134
135         if dumpShmBin:
136                 # Only do a binary SHM dump
137                 stdout.write(shm)
138                 sys.exit(0)
139
140         print "--- B43 microcode state dump ---"
141         print "PC: %03X  PSM-COND: %04X" % (dbg.getPc(), psmcond)
142         print "Link registers:"
143         dump_regs("lr", lr)
144         print "Offset registers:"
145         dump_regs("off", off)
146         print "General purpose registers:"
147         dump_regs("r", gpr)
148
149         print "Code:"
150         if binary:
151                 try:
152                         bintext = file(binary, "r").read()
153                 except IOError, e:
154                         print "Could not read binary file %s: %s" % (binary, e.strerror)
155                         sys.exit(1)
156                 dasm = Disassembler(bintext, dasmopt + "--paddr").getAsm()
157                 print makeShortDump(dasm, dbg.getPc())
158         else:
159                 print "<No binary supplied. See --binary option>"
160
161         if dumpShm:
162                 print "Shared memory:"
163                 ascii = ""
164                 for i in range(0, len(shm)):
165                         if i % 16 == 0 and i != 0:
166                                 stdout.write("  " + ascii + "\n")
167                                 ascii = ""
168                         if i % 16 == 0:
169                                 stdout.write("0x%04X:  " % i)
170                         c = ord(shm[i])
171                         stdout.write("%02X" % c)
172                         if (i % 2 != 0):
173                                 stdout.write(" ")
174                         ascii += toAscii(c)
175                 stdout.write("  " + ascii + "\n")
176         return
177
178
179 try:
180         main()
181 except B43Exception:
182         sys.exit(1)