From patchwork Thu Jun 7 12:21:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: maddy X-Patchwork-Id: 926284 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 411l5g2d5Pz9s31 for ; Thu, 7 Jun 2018 22:21:43 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.vnet.ibm.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 411l5f6LSCzF34g for ; Thu, 7 Jun 2018 22:21:42 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.vnet.ibm.com X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (mailfrom) smtp.mailfrom=linux.vnet.ibm.com (client-ip=148.163.158.5; helo=mx0a-001b2d01.pphosted.com; envelope-from=maddy@linux.vnet.ibm.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.vnet.ibm.com Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 411l5M53btzF34X for ; Thu, 7 Jun 2018 22:21:26 +1000 (AEST) Received: from pps.filterd (m0098413.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w57CJmB0109698 for ; Thu, 7 Jun 2018 08:21:24 -0400 Received: from e06smtp07.uk.ibm.com (e06smtp07.uk.ibm.com [195.75.94.103]) by mx0b-001b2d01.pphosted.com with ESMTP id 2jf4cu8syj-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 07 Jun 2018 08:21:23 -0400 Received: from localhost by e06smtp07.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 7 Jun 2018 13:21:22 +0100 Received: from b06cxnps4075.portsmouth.uk.ibm.com (9.149.109.197) by e06smtp07.uk.ibm.com (192.168.101.137) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Thu, 7 Jun 2018 13:21:20 +0100 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w57CLKGH34603218 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 7 Jun 2018 12:21:20 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 69D0211C050; Thu, 7 Jun 2018 13:12:04 +0100 (BST) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 571ED11C04A; Thu, 7 Jun 2018 13:12:03 +0100 (BST) Received: from SrihariSrinidhi.in.ibm.com (unknown [9.77.195.5]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 7 Jun 2018 13:12:03 +0100 (BST) From: Madhavan Srinivasan To: stewart@linux.vnet.ibm.com Date: Thu, 7 Jun 2018 17:51:16 +0530 X-Mailer: git-send-email 2.7.4 X-TM-AS-GCONF: 00 x-cbid: 18060712-0028-0000-0000-000002CE42F0 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18060712-0029-0000-0000-0000238546AF Message-Id: <1528374076-26183-1-git-send-email-maddy@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-06-07_05:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1805220000 definitions=main-1806070143 Subject: [Skiboot] [PATCH] external/xscom-utils: Add python library for xscom access X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: skiboot@lists.ozlabs.org MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" 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 --- 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) +