2 # b43 debugging library
4 # Copyright (C) 2008 Michael Buesch <mb@bu3sch.de>
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License version 3
8 # as published by the Free Software Foundation.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
32 class B43Exception(Exception):
36 B43_MMIO_MACCTL = 0x120
37 B43_MMIO_PSMDEBUG = 0x154
39 B43_MACCTL_PSM_MACEN = 0x00000001
40 B43_MACCTL_PSM_RUN = 0x00000002
41 B43_MACCTL_PSM_JMP0 = 0x00000004
42 B43_MACCTL_PSM_DEBUG = 0x00002000
46 """Parse the contents of the PSM-debug register"""
47 def __init__(self, reg_content):
48 self.raw = reg_content
52 """Get the raw PSM-debug register value"""
56 """Get the microcode program counter"""
57 return self.raw & 0xFFF
61 def __init__(self, phy):
62 debugfs_path = self.__debugfs_find()
64 # Construct the debugfs b43 path to the device
65 b43_path = debugfs_path + "/b43/"
70 phys = os.listdir(b43_path)
72 print "Could not find any b43 device"
75 print "Found multiple b43 devices."
76 print "You must call this tool with a phyX parameter to specify a device"
81 # Open the debugfs files
83 self.f_mmio16read = file(b43_path + "/mmio16read", "r+")
84 self.f_mmio16write = file(b43_path + "/mmio16write", "w")
85 self.f_mmio32read = file(b43_path + "/mmio32read", "r+")
86 self.f_mmio32write = file(b43_path + "/mmio32write", "w")
87 self.f_shm16read = file(b43_path + "/shm16read", "r+")
88 self.f_shm16write = file(b43_path + "/shm16write", "w")
89 self.f_shm32read = file(b43_path + "/shm32read", "r+")
90 self.f_shm32write = file(b43_path + "/shm32write", "w")
92 print "Could not open debugfs file %s: %s" % (e.filename, e.strerror)
95 self.b43_path = b43_path
98 # Get the debugfs mountpoint.
99 def __debugfs_find(self):
100 mtab = file("/etc/mtab").read().splitlines()
101 regexp = re.compile(r"^[\w\-_]+\s+([\w/\-_]+)\s+debugfs")
104 m = regexp.match(line)
109 print "Could not find debugfs in /etc/mtab"
113 def read16(self, reg):
114 """Do a 16bit MMIO read"""
116 self.f_mmio16read.seek(0)
117 self.f_mmio16read.write("0x%X" % reg)
118 self.f_mmio16read.flush()
119 self.f_mmio16read.seek(0)
120 val = self.f_mmio16read.read()
122 print "Could not access debugfs file %s: %s" % (e.filename, e.strerror)
126 def read32(self, reg):
127 """Do a 32bit MMIO read"""
129 self.f_mmio32read.seek(0)
130 self.f_mmio32read.write("0x%X" % reg)
131 self.f_mmio32read.flush()
132 self.f_mmio32read.seek(0)
133 val = self.f_mmio32read.read()
135 print "Could not access debugfs file %s: %s" % (e.filename, e.strerror)
139 def maskSet16(self, reg, mask, set):
140 """Do a 16bit MMIO mask-and-set operation"""
144 self.f_mmio16write.seek(0)
145 self.f_mmio16write.write("0x%X 0x%X 0x%X" % (reg, mask, set))
146 self.f_mmio16write.flush()
148 print "Could not access debugfs file %s: %s" % (e.filename, e.strerror)
152 def write16(self, reg, value):
153 """Do a 16bit MMIO write"""
154 self.maskSet16(reg, 0, value)
157 def maskSet32(self, reg, mask, set):
158 """Do a 32bit MMIO mask-and-set operation"""
162 self.f_mmio32write.seek(0)
163 self.f_mmio32write.write("0x%X 0x%X 0x%X" % (reg, mask, set))
164 self.f_mmio32write.flush()
166 print "Could not access debugfs file %s: %s" % (e.filename, e.strerror)
170 def write32(self, reg, value):
171 """Do a 32bit MMIO write"""
172 self.maskSet32(reg, 0, value)
175 def shmRead16(self, routing, offset):
176 """Do a 16bit SHM read"""
178 self.f_shm16read.seek(0)
179 self.f_shm16read.write("0x%X 0x%X" % (routing, offset))
180 self.f_shm16read.flush()
181 self.f_shm16read.seek(0)
182 val = self.f_shm16read.read()
184 print "Could not access debugfs file %s: %s" % (e.filename, e.strerror)
188 def shmMaskSet16(self, routing, offset, mask, set):
189 """Do a 16bit SHM mask-and-set operation"""
193 self.f_shm16write.seek(0)
194 self.f_shm16write.write("0x%X 0x%X 0x%X 0x%X" % (routing, offset, mask, set))
195 self.f_shm16write.flush()
197 print "Could not access debugfs file %s: %s" % (e.filename, e.strerror)
201 def shmWrite16(self, routing, offset, value):
202 """Do a 16bit SHM write"""
203 self.shmMaskSet16(routing, offset, 0, value)
206 def shmRead32(self, routing, offset):
207 """Do a 32bit SHM read"""
209 self.f_shm32read.seek(0)
210 self.f_shm32read.write("0x%X 0x%X" % (routing, offset))
211 self.f_shm32read.flush()
212 self.f_shm32read.seek(0)
213 val = self.f_shm32read.read()
215 print "Could not access debugfs file %s: %s" % (e.filename, e.strerror)
219 def shmMaskSet32(self, routing, offset, mask, set):
220 """Do a 32bit SHM mask-and-set operation"""
224 self.f_shm32write.seek(0)
225 self.f_shm32write.write("0x%X 0x%X 0x%X 0x%X" % (routing, offset, mask, set))
226 self.f_shm32write.flush()
228 print "Could not access debugfs file %s: %s" % (e.filename, e.strerror)
232 def shmWrite32(self, routing, offset, value):
233 """Do a 32bit SHM write"""
234 self.shmMaskSet32(routing, offset, 0, value)
238 """Returns an array of 64 ints. One for each General Purpose register."""
240 for i in range(0, 64):
241 val = self.shmRead16(B43_SHM_REGS, i)
245 def getLinkRegs(self):
246 """Returns an array of 4 ints. One for each Link Register."""
248 for i in range(0, 4):
249 val = self.read16(0x4D0 + (i * 2))
253 def getOffsetRegs(self):
254 """Returns an array of 7 ints. One for each Offset Register."""
256 for i in range(0, 7):
257 val = self.read16(0x4C0 + (i * 2))
261 def shmSharedRead(self):
262 """Returns a string containing the SHM contents."""
264 for i in range(0, 4096, 4):
265 val = self.shmRead32(B43_SHM_SHARED, i)
266 ret += "%c%c%c%c" % (val & 0xFF,
272 def getPsmDebug(self):
273 """Read the PSM-debug register and return an instance of B43PsmDebug."""
274 val = self.read32(B43_MMIO_PSMDEBUG)
275 return B43PsmDebug(val)
277 def getPsmConditions(self):
278 """This returns the contents of the programmable-PSM-conditions register."""
279 return self.read16(0x4D8)
282 """Unconditionally stop the microcode PSM. """
283 self.maskSet32(B43_MMIO_MACCTL, ~B43_MACCTL_PSM_RUN, 0)
286 def ucodeStart(self):
287 """Unconditionally start the microcode PSM. This will restart the
288 microcode on the current PC. It will not jump to 0. Warning: This will
289 unconditionally restart the PSM and ignore any driver-state!"""
290 self.maskSet32(B43_MMIO_MACCTL, ~0, B43_MACCTL_PSM_RUN)