Commit 2af8ca43 authored by Michael Büsch's avatar Michael Büsch

Add a python library to access device internals.

Signed-off-by: Michael Büsch's avatarMichael Buesch <mb@bu3sch.de>
parent 8d9445b1
......@@ -7,6 +7,7 @@
*.so.dbg
*.i
*.lst
*.pyc
.gitignore
*.ucode
......
This diff is collapsed.
This is a set of tools for debugging the b43 driver and/or firmware.
Note that it is licensed under the GNU GPL version 3 ONLY!
Please be careful when using these tools. They have direct access to the
hardware, so you can easily crash something.
Michael
#!/usr/bin/env python
#
# b43 firmware state dumper
#
# Copyright (C) 2008 Michael Buesch <mb@bu3sch.de>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3
# as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from libb43 import *
try:
phy = sys.argv[1]
except IndexError:
phy = None
try:
b43 = B43(phy)
regs = b43.ucodeRegsRead()
shm = b43.shmSharedRead()
dbg = b43.getPsmDebug()
print "PC is at 0x%03X" % dbg.getPc()
#TODO
except B43Exception:
sys.exit(1)
#
# b43 debugging library
#
# Copyright (C) 2008 Michael Buesch <mb@bu3sch.de>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3
# as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import sys
import os
import re
# SHM routing values
B43_SHM_UCODE = 0
B43_SHM_SHARED = 1
B43_SHM_REGS = 2
B43_SHM_IHR = 3
B43_SHM_RCMTA = 4
class B43Exception(Exception):
pass
B43_MMIO_PSMDEBUG = 0x154
class B43PsmDebug:
"""Parse the contents of the PSM-debug register"""
def __init__(self, reg_content):
self.pc = reg_content & 0xFFF
return
def getPc(self):
"""Get the microcode program counter"""
return self.pc
class B43:
def __init__(self, phy):
debugfs_path = self.__debugfs_find()
# Construct the debugfs b43 path to the device
b43_path = debugfs_path + "/b43/"
if phy:
b43_path += phy
else:
# Get the PHY.
phys = os.listdir(b43_path)
if not phys:
print "Could not find any b43 device"
raise B43Exception
if len(phys) != 1:
print "Found multiple b43 devices."
print "You must call this tool with a phyX parameter to specify a device"
raise B43Exception
phy = phys[0]
b43_path += phy;
# Open the debugfs files
try:
self.f_mmio16read = file(b43_path + "/mmio16read", "r+")
self.f_mmio16write = file(b43_path + "/mmio16write", "w")
self.f_mmio32read = file(b43_path + "/mmio32read", "r+")
self.f_mmio32write = file(b43_path + "/mmio32write", "w")
self.f_shm16read = file(b43_path + "/shm16read", "r+")
self.f_shm16write = file(b43_path + "/shm16write", "w")
self.f_shm32read = file(b43_path + "/shm32read", "r+")
self.f_shm32write = file(b43_path + "/shm32write", "w")
except IOError, e:
print "Could not open debugfs file %s: %s" % (e.filename, e.strerror)
raise B43Exception
return
# Get the debugfs mountpoint.
def __debugfs_find(self):
mtab = file("/etc/mtab").read().splitlines()
regexp = re.compile(r"^[\w\-_]+\s+([\w/\-_]+)\s+debugfs")
path = None
for line in mtab:
m = regexp.match(line)
if m:
path = m.group(1)
break
if not path:
print "Could not find debugfs in /etc/mtab"
raise B43Exception
return path
def read16(self, reg):
"""Do a 16bit MMIO read"""
try:
self.f_mmio16read.seek(0)
self.f_mmio16read.write("0x%X" % reg)
self.f_mmio16read.seek(0)
val = self.f_mmio16read.read()
except IOError, e:
print "Coult not access debugfs file %s: %s" % (e.filename, e.strerror)
raise B43Exception
return int(val, 16)
def read32(self, reg):
"""Do a 32bit MMIO read"""
try:
self.f_mmio32read.seek(0)
self.f_mmio32read.write("0x%X" % reg)
self.f_mmio32read.seek(0)
val = self.f_mmio32read.read()
except IOError, e:
print "Coult not access debugfs file %s: %s" % (e.filename, e.strerror)
raise B43Exception
return int(val, 16)
def write16(self, reg, value):
"""Do a 16bit MMIO write"""
try:
self.f_mmio16write.seek(0)
self.f_mmio16write.write("0x%X = 0x%X" % (reg, value))
except IOError, e:
print "Coult not access debugfs file %s: %s" % (e.filename, e.strerror)
raise B43Exception
return
def write32(self, reg, value):
"""Do a 32bit MMIO write"""
try:
self.f_mmio32write.seek(0)
self.f_mmio32write.write("0x%X = 0x%X" % (reg, value))
except IOError, e:
print "Coult not access debugfs file %s: %s" % (e.filename, e.strerror)
raise B43Exception
return
def shmRead16(self, routing, offset):
"""Do a 16bit SHM read"""
try:
self.f_shm16read.seek(0)
self.f_shm16read.write("0x%X 0x%X" % (routing, offset))
self.f_shm16read.seek(0)
val = self.f_shm16read.read()
except IOError, e:
print "Coult not access debugfs file %s: %s" % (e.filename, e.strerror)
raise B43Exception
return int(val, 16)
def shmMaskSet16(self, routing, offset, mask, set):
"""Do a 16bit SHM mask-and-set operation"""
try:
self.f_shm16write.seek(0)
self.f_shm16write.write("0x%X 0x%X 0x%X 0x%X" % (routing, offset, mask, set))
except IOError, e:
print "Coult not access debugfs file %s: %s" % (e.filename, e.strerror)
raise B43Exception
return
def shmWrite16(self, routing, offset, value):
"""Do a 16bit SHM write"""
self.shmMaskSet16(routing, offset, 0, value)
return
def shmRead32(self, routing, offset):
"""Do a 32bit SHM read"""
try:
self.f_shm32read.seek(0)
self.f_shm32read.write("0x%X 0x%X" % (routing, offset))
self.f_shm32read.seek(0)
val = self.f_shm32read.read()
except IOError, e:
print "Coult not access debugfs file %s: %s" % (e.filename, e.strerror)
raise B43Exception
return int(val, 16)
def shmMaskSet32(self, routing, offset, mask, set):
"""Do a 32bit SHM mask-and-set operation"""
try:
self.f_shm32write.seek(0)
self.f_shm32write.write("0x%X 0x%X 0x%X 0x%X" % (routing, offset, mask, set))
except IOError, e:
print "Coult not access debugfs file %s: %s" % (e.filename, e.strerror)
raise B43Exception
return
def shmWrite32(self, routing, offset, value):
"""Do a 32bit SHM write"""
self.shmMaskSet32(routing, offset, 0, value)
return
def ucodeRegsRead(self):
"""Returns an array of 64 ints. One for each ucode register."""
ret = []
for i in range(0, 64):
val = self.shmRead16(B43_SHM_REGS, i)
ret.append(val)
return ret
def shmSharedRead(self):
"""Returns an array of ints containing the bytewise SHM contents."""
ret = []
for i in range(0, 4096, 4):
val = self.shmRead32(B43_SHM_SHARED, i)
ret.append(val & 0xFF)
ret.append((val >> 8) & 0xFF)
ret.append((val >> 16) & 0xFF)
ret.append((val >> 24) & 0xFF)
return ret
def getPsmDebug(self):
"""Read the PSM-debug register and return an instance of B43PsmDebug."""
val = self.read32(B43_MMIO_PSMDEBUG)
return B43PsmDebug(val)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment