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