4535cfb6b976f94ec87d381261a3c17443201a4a
[b43-tools.git] / debug / libb43.py
1 #
2 #  b43 debugging library
3 #
4 #  Copyright (C) 2008 Michael Buesch <mb@bu3sch.de>
5 #
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.
9 #
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.
14 #
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/>.
17 #
18
19 import sys
20 import os
21 import re
22
23
24 # SHM routing values
25 B43_SHM_UCODE           = 0
26 B43_SHM_SHARED          = 1
27 B43_SHM_REGS            = 2
28 B43_SHM_IHR             = 3
29 B43_SHM_RCMTA           = 4
30
31
32 class B43Exception(Exception):
33         pass
34
35
36 B43_MMIO_PSMDEBUG = 0x154
37
38 class B43PsmDebug:
39         """Parse the contents of the PSM-debug register"""
40         def __init__(self, reg_content):
41                 self.pc = reg_content & 0xFFF
42                 return
43
44         def getPc(self):
45                 """Get the microcode program counter"""
46                 return self.pc
47
48
49 class B43:
50         def __init__(self, phy):
51                 debugfs_path = self.__debugfs_find()
52
53                 # Construct the debugfs b43 path to the device
54                 b43_path = debugfs_path + "/b43/"
55                 if phy:
56                         b43_path += phy
57                 else:
58                         # Get the PHY.
59                         phys = os.listdir(b43_path)
60                         if not phys:
61                                 print "Could not find any b43 device"
62                                 raise B43Exception
63                         if len(phys) != 1:
64                                 print "Found multiple b43 devices."
65                                 print "You must call this tool with a phyX parameter to specify a device"
66                                 raise B43Exception
67                         phy = phys[0]
68                         b43_path += phy;
69
70                 # Open the debugfs files
71                 try:
72                         self.f_mmio16read = file(b43_path + "/mmio16read", "r+")
73                         self.f_mmio16write = file(b43_path + "/mmio16write", "w")
74                         self.f_mmio32read = file(b43_path + "/mmio32read", "r+")
75                         self.f_mmio32write = file(b43_path + "/mmio32write", "w")
76                         self.f_shm16read = file(b43_path + "/shm16read", "r+")
77                         self.f_shm16write = file(b43_path + "/shm16write", "w")
78                         self.f_shm32read = file(b43_path + "/shm32read", "r+")
79                         self.f_shm32write = file(b43_path + "/shm32write", "w")
80                 except IOError, e:
81                         print "Could not open debugfs file %s: %s" % (e.filename, e.strerror)
82                         raise B43Exception
83                 return
84
85         # Get the debugfs mountpoint.
86         def __debugfs_find(self):
87                 mtab = file("/etc/mtab").read().splitlines()
88                 regexp = re.compile(r"^[\w\-_]+\s+([\w/\-_]+)\s+debugfs")
89                 path = None
90                 for line in mtab:
91                         m = regexp.match(line)
92                         if m:
93                                 path = m.group(1)
94                                 break
95                 if not path:
96                         print "Could not find debugfs in /etc/mtab"
97                         raise B43Exception
98                 return path
99
100         def read16(self, reg):
101                 """Do a 16bit MMIO read"""
102                 try:
103                         self.f_mmio16read.seek(0)
104                         self.f_mmio16read.write("0x%X" % reg)
105                         self.f_mmio16read.seek(0)
106                         val = self.f_mmio16read.read()
107                 except IOError, e:
108                         print "Coult not access debugfs file %s: %s" % (e.filename, e.strerror)
109                         raise B43Exception
110                 return int(val, 16)
111
112         def read32(self, reg):
113                 """Do a 32bit MMIO read"""
114                 try:
115                         self.f_mmio32read.seek(0)
116                         self.f_mmio32read.write("0x%X" % reg)
117                         self.f_mmio32read.seek(0)
118                         val = self.f_mmio32read.read()
119                 except IOError, e:
120                         print "Coult not access debugfs file %s: %s" % (e.filename, e.strerror)
121                         raise B43Exception
122                 return int(val, 16)
123
124         def write16(self, reg, value):
125                 """Do a 16bit MMIO write"""
126                 try:
127                         self.f_mmio16write.seek(0)
128                         self.f_mmio16write.write("0x%X = 0x%X" % (reg, value))
129                 except IOError, e:
130                         print "Coult not access debugfs file %s: %s" % (e.filename, e.strerror)
131                         raise B43Exception
132                 return
133
134         def write32(self, reg, value):
135                 """Do a 32bit MMIO write"""
136                 try:
137                         self.f_mmio32write.seek(0)
138                         self.f_mmio32write.write("0x%X = 0x%X" % (reg, value))
139                 except IOError, e:
140                         print "Coult not access debugfs file %s: %s" % (e.filename, e.strerror)
141                         raise B43Exception
142                 return
143
144         def shmRead16(self, routing, offset):
145                 """Do a 16bit SHM read"""
146                 try:
147                         self.f_shm16read.seek(0)
148                         self.f_shm16read.write("0x%X 0x%X" % (routing, offset))
149                         self.f_shm16read.seek(0)
150                         val = self.f_shm16read.read()
151                 except IOError, e:
152                         print "Coult not access debugfs file %s: %s" % (e.filename, e.strerror)
153                         raise B43Exception
154                 return int(val, 16)
155
156         def shmMaskSet16(self, routing, offset, mask, set):
157                 """Do a 16bit SHM mask-and-set operation"""
158                 try:
159                         self.f_shm16write.seek(0)
160                         self.f_shm16write.write("0x%X 0x%X 0x%X 0x%X" % (routing, offset, mask, set))
161                 except IOError, e:
162                         print "Coult not access debugfs file %s: %s" % (e.filename, e.strerror)
163                         raise B43Exception
164                 return
165
166         def shmWrite16(self, routing, offset, value):
167                 """Do a 16bit SHM write"""
168                 self.shmMaskSet16(routing, offset, 0, value)
169                 return
170
171         def shmRead32(self, routing, offset):
172                 """Do a 32bit SHM read"""
173                 try:
174                         self.f_shm32read.seek(0)
175                         self.f_shm32read.write("0x%X 0x%X" % (routing, offset))
176                         self.f_shm32read.seek(0)
177                         val = self.f_shm32read.read()
178                 except IOError, e:
179                         print "Coult not access debugfs file %s: %s" % (e.filename, e.strerror)
180                         raise B43Exception
181                 return int(val, 16)
182
183         def shmMaskSet32(self, routing, offset, mask, set):
184                 """Do a 32bit SHM mask-and-set operation"""
185                 try:
186                         self.f_shm32write.seek(0)
187                         self.f_shm32write.write("0x%X 0x%X 0x%X 0x%X" % (routing, offset, mask, set))
188                 except IOError, e:
189                         print "Coult not access debugfs file %s: %s" % (e.filename, e.strerror)
190                         raise B43Exception
191                 return
192
193         def shmWrite32(self, routing, offset, value):
194                 """Do a 32bit SHM write"""
195                 self.shmMaskSet32(routing, offset, 0, value)
196                 return
197
198         def ucodeRegsRead(self):
199                 """Returns an array of 64 ints. One for each ucode register."""
200                 ret = []
201                 for i in range(0, 64):
202                         val = self.shmRead16(B43_SHM_REGS, i)
203                         ret.append(val)
204                 return ret
205
206         def shmSharedRead(self):
207                 """Returns an array of ints containing the bytewise SHM contents."""
208                 ret = []
209                 for i in range(0, 4096, 4):
210                         val = self.shmRead32(B43_SHM_SHARED, i)
211                         ret.append(val & 0xFF)
212                         ret.append((val >> 8) & 0xFF)
213                         ret.append((val >> 16) & 0xFF)
214                         ret.append((val >> 24) & 0xFF)
215                 return ret
216
217         def getPsmDebug(self):
218                 """Read the PSM-debug register and return an instance of B43PsmDebug."""
219                 val = self.read32(B43_MMIO_PSMDEBUG)
220                 return B43PsmDebug(val)