b43-fwdump 4.4 KB

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