[Skiboot] [PATCH] external/xscom-utils: Add python library for xscom access
Madhavan Srinivasan
maddy at linux.vnet.ibm.com
Thu Jun 7 22:21:16 AEST 2018
Patch adds a simple python library module for xscom access.
It directly manipulate the '/access' file for scom read
and write from debugfs 'scom' directory.
Example on how to generate a getscom using this module:
#!/usr/bin/python
from adu_scoms import *
getscom = GetSCom()
getscom.parse_args()
getscom.run_command()
Sample output for above getscom.py:
# ./getscom.py -l
Chip ID | Rev | Chip type
---------|-------|-----------
00000008 | DD2.0 | P9 (Nimbus) processor
00000000 | DD2.0 | P9 (Nimbus) processor
Signed-off-by: Madhavan Srinivasan <maddy at linux.vnet.ibm.com>
---
external/xscom-utils/adu_scoms.py | 312 ++++++++++++++++++++++++++++++++++++++
1 file changed, 312 insertions(+)
create mode 100755 external/xscom-utils/adu_scoms.py
diff --git a/external/xscom-utils/adu_scoms.py b/external/xscom-utils/adu_scoms.py
new file mode 100755
index 000000000000..eab5bbea69b0
--- /dev/null
+++ b/external/xscom-utils/adu_scoms.py
@@ -0,0 +1,312 @@
+#!/usr/bin/python
+
+# Python library for in-band SCom access
+# (based on xscom-utils from OPAL firmware)
+#
+# Copyright 2018 IBM Corp.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os, sys, struct, getopt
+
+class XSCom(object):
+ def __init__(self):
+ self.name = "xscom"
+ self.base = "/sys/kernel/debug/powerpc/scom/"
+ self.enabled = False
+ self.setup = False
+ self.chips = []
+ self.dirs = []
+ self.key_val_bin = {}
+ self.file = "/access"
+
+ if os.path.exists(self.base):
+ self.enabled = True
+
+ if not self.scan_chips():
+ raise ValueError
+
+ def scan_chips(self):
+ if not self.enabled:
+ print "Not supported"
+ return False
+
+ for i in os.listdir(self.base):
+ if os.path.isdir(self.base+i):
+ self.dirs.append(i)
+ self.chips.append(int(i,16))
+
+ for i in self.dirs:
+ try:
+ b = open(self.base+i+self.file, "rb+")
+ self.key_val_bin[int(i,16)] = b
+ except:
+ print "Count not open"+self.base+i+self.file
+ return False
+
+ self.setup = True
+ return True
+
+ def is_supported(self):
+ return self.enabled
+
+ def get_chip_ids(self):
+ return self.key_val_bin.keys()
+
+ def mangle_addr(self, addr):
+ tmp = (addr & 0xf000000000000000) >> 4
+ addr = (addr & 0x00ffffffffffffff)
+ addr = addr | tmp
+ return (addr << 3)
+
+ def xscom_read(self, chip_id, addr):
+ if not isinstance(chip_id, int) or not isinstance(addr, int):
+ print "xscom_read: Input paramater type mismatch"
+ return -1
+
+ if not self.key_val_bin.has_key(chip_id):
+ print "Invalid Chip id"
+ return -1
+
+ saddr = self.mangle_addr(addr)
+ fd = self.key_val_bin.get(chip_id)
+ fd.seek(saddr, 0)
+ return struct.unpack('Q',fd.read(8))[0]
+
+ def xscom_read_spl(self, chip_id, addr):
+ if not isinstance(chip_id, int) or not isinstance(addr, int):
+ print "xscom_read: Input paramater type mismatch"
+ return -1
+
+ if not self.key_val_bin.has_key(chip_id):
+ print "Invalid Chip id"
+ return -1
+
+ saddr = self.mangle_addr(addr)
+ fd = self.key_val_bin.get(chip_id)
+ fd.seek(saddr, 0)
+ val = struct.unpack('Q',fd.read(8))[0]
+ fd.close()
+ try:
+ b = open(self.key_val_path.get(chip_id), "rb+")
+ except:
+ print "Reopen failed"
+ return val
+ self.key_val_bin[chip_id] = b
+ return val
+
+ def xscom_write(self, chip_id, addr, val):
+ if not self.key_val_bin.has_key(chip_id):
+ print "Invalid Chip id"
+ return -1
+
+ c = struct.pack('Q',val)
+ saddr = self.mangle_addr(addr)
+ fd = self.key_val_bin.get(chip_id)
+
+ try:
+ fd.seek(saddr, 0)
+ fd.write(c)
+ # write again just to be sure
+ fd.seek(saddr, 0)
+ fd.write(c)
+ except:
+ print "Write() error"
+ return -1
+
+ def xscom_read_ex(self, ex_target_id, addr):
+ if not isinstance(ex_target_id, int) or not isinstance(addr, int):
+ print "xscom_read_ex: Input paramater type mismatch"
+ return -1
+
+ chip_id = ex_target_id >> 4
+ addr |= (ex_target_id & 0xf) << 24;
+ return self.xscom_read(chip_id, addr, val);
+
+ def xscom_write_ex(self, ex_target_id, addr, val):
+ chip_id = ex_target_id >> 4
+ addr |= (ex_target_id & 0xf) << 24;
+ return self.xscom_write(chip_id, addr, val)
+
+class GetSCom(object):
+ def __init__(self):
+ self.name = "getscom"
+ self.backend = XSCom()
+ self.listchip = False
+ self.chip_id = 0
+ self.chips = False
+ self.addr = 0
+ self.flg_addr = False
+
+ if not self.backend.is_supported():
+ print "In-Band SCom not supported Exiting...."
+ raise ValueError
+
+ def set_chip(self, chip_id):
+ self.chip_id = chip_id
+ self.chips = True
+
+ def set_addr(self, scom_addr):
+ self.addr = scom_addr
+ self.flg_addr = True
+
+ def print_usage(self):
+ print("usage: getscom [-c|--chip chip-id] addr")
+ print(" getscom -l|--list-chips")
+ print(" getscom -h|--help")
+ sys.exit(0)
+
+
+ def chip_info(self, chip_id):
+ val = self.backend.xscom_read(chip_id, 0xf000f)
+ if val < 0:
+ print "Error in scom read"
+ raise ValueError
+
+ c_id = val >> 44
+ id = c_id & 0xff
+ if id == 0xf9:
+ name = "P7 processor"
+ elif id == 0xe8:
+ name = "P7+ processor"
+ elif id == 0xef:
+ name = "P8E (Murano) processor"
+ elif id == 0xea:
+ name = "P8 (Venice) processor"
+ elif id == 0xd3:
+ name = "P8NVL (Naples) processor"
+ elif id == 0xd1:
+ name = "P9 (Nimbus) processor"
+ elif id == 0xd4:
+ name = "P9 (Cumulus) processor"
+ elif id == 0xe9:
+ name = "Centaur memory buffer"
+ else:
+ name = "Unknown ID 0x%x"%id
+
+ print ("%08x | DD%s.%s | %s"%(chip_id, ((c_id >> 16) & 0xf), ((c_id >> 8) & 0xf), name))
+
+ def parse_args(self):
+ try:
+ optlist, sys.argv = getopt.getopt(sys.argv[1:], "lhc:", ["chip", "list-chips", "help"])
+ except getopt.GetoptError as err:
+ print str(err)
+ self.print_usage()
+ sys.exit(0)
+
+ if len(optlist) == 0:
+ self.print_usage()
+ sys.exit(0)
+
+ for opt, arg in optlist:
+ if opt in [ "-h", "--help"]:
+ self.print_usage()
+ sys.exit(0)
+
+ elif opt in [ "-l", "--list-chips"]:
+ self.listchip = True
+
+ elif opt in ["-c", "--chip"]:
+ self.chip_id = int(arg, 16)
+ self.chips = True
+
+ if sys.argv:
+ self.addr = int(sys.argv.pop(), 16)
+ self.flg_addr = True
+
+ if self.listchip:
+ print("Chip ID | Rev | Chip type")
+ print("---------|-------|-----------")
+ for i in self.backend.get_chip_ids():
+ self.chip_info(i)
+
+ sys.exit(0)
+
+ def run_command(self):
+ if self.chips and self.flg_addr:
+ print hex(self.backend.xscom_read(self.chip_id, self.addr))
+
+ def list_chips(self):
+ print("Chip ID | Rev | Chip type")
+ print("---------|-------|-----------")
+ for i in self.backend.get_chip_ids():
+ self.chip_info(i)
+
+ raise ValueError
+
+ def execute(self, chip_id, addr):
+ return self.backend.xscom_read(chip_id, addr)
+
+ def execute_spl(self, chip_id, addr):
+ return self.backend.xscom_read_spl(chip_id, addr)
+
+class PutSCom(object):
+ def __init__(self):
+ self.name = "putscom"
+ self.backend = XSCom()
+ self.chip_id = 0
+ self.chips = False
+ self.addr = 0
+ self.value = 0
+
+ if not self.backend.is_supported():
+ print "In-Band SCom not supported Exiting...."
+ raise ValueError
+
+ def set_addr(self, addr):
+ self.addr = addr
+
+ def set_value(self, value):
+ self.value = value
+
+ def print_usage(self):
+ print("usage: putscom [-c|--chip chip-id] addr value")
+ print(" putscom -h|--help")
+ sys.exit(0)
+
+ def parse_args(self):
+ try:
+ optlist, sys.argv = getopt.getopt(sys.argv[1:], "hc:", ["chip", "help"])
+ except getopt.GetoptError as err:
+ print str(err)
+ self.print_usage()
+ sys.exit(0)
+
+ if len(optlist) == 0:
+ self.print_usage()
+ sys.exit(0)
+
+ for opt, arg in optlist:
+ if opt in [ "-h", "--help"]:
+ self.print_usage()
+ sys.exit(0)
+
+ elif opt in ["-c", "--chip"]:
+ self.chip_id = int(arg, 16)
+ self.chips = True
+
+ if sys.argv:
+ self.value = int(sys.argv.pop(), 16)
+ self.addr = int(sys.argv.pop(), 16)
+
+ if self.chips:
+ self.backend.xscom_write(self.chip_id, self.addr, self.value)
+
+ def run_command(self):
+ if self.chips:
+ self.backend.xscom_write(self.chip_id, self.addr, self.value)
+
+ def execute(self, chip_id, addr, value):
+ self.backend.xscom_write(chip_id, addr, value)
+
--
2.7.4
More information about the Skiboot
mailing list