From patchwork Wed May 5 17:10:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liming Sun X-Patchwork-Id: 1474467 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=Nvidia.com header.i=@Nvidia.com header.a=rsa-sha256 header.s=selector2 header.b=aWIlg6/I; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Fb3Bp4RCvz9sT6; Thu, 6 May 2021 03:10:58 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1leL31-0004is-JP; Wed, 05 May 2021 17:10:55 +0000 Received: from mail-co1nam11on2082.outbound.protection.outlook.com ([40.107.220.82] helo=NAM11-CO1-obe.outbound.protection.outlook.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1leL2x-0004hN-BG for kernel-team@lists.ubuntu.com; Wed, 05 May 2021 17:10:51 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=QzASbCtr4IMALXSJubvCaLuEF4H8Pq7Jah5Xj87l8T9888y2u/yP799KLve9BsE2Qxiq0w9pQYsVu+3rNyeKbK+6nwk4958ayXE8HB/QdBdUX4Jw0zxoRWlHN+a94UZHNL1f7WKPokeioxiYFiayYkKqn8bqEAe5PdwQ6i2yxGe5R67WlOGZmwvVhxWMwqKtu0dxtFEVlTZSaT3QYeFjz65mPrVsjyI9lyhRGNCWxglW9XBNqHUtKhpdsGLXyUjlXNewTC2jOHAmS+wl+i2R19sEYjMCUf22AYQto95yh9Bu0jxHokHrJuXB9c4faE0VQjtjPgAqQOxDRhhJzIxfcA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=aVIWAWCpWbj5j9G4znX/g4ZX2rgtxxeHs4yce8ejOGk=; b=hILvy8IqzCrCy3/QZ3mkkXUWEvb+fP6BcLMtybqNKa5Cmo+uh62TzDqfPFZ/WScA0PDnbv/ubPDaNpHPts/8rNYr1wQ8EyST4j+Gi4/jOPTRwurT+NSuWrg/MIyqATWzw9cBt8wfJSW/iRIWFzhKIc8oofxcPmeEFLjcN1ehSqv2UwVAwM1d7uMmSRrOctGx+o4VeKyZAd35swtEm59hqv4p2rRiIuTjYk2FSiQKawOBpGGLtyDFbMeBYRIJPrV1DcE4+kzmOUAQeUxYcHdlzNsk+nk8fB9GWtEvIDtKrOsP0e7zQfgxNIubrxt9ajpjAEWU/J9pLTXbuEB1Lnam2w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.112.36) smtp.rcpttodomain=lists.ubuntu.com smtp.mailfrom=nvidia.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=aVIWAWCpWbj5j9G4znX/g4ZX2rgtxxeHs4yce8ejOGk=; b=aWIlg6/IO/e5j5SChFsA0wwITFysb9yBUGe5VGdg6LIS+4dobM3rggdliAv4ZC1VMp1ixKYWHVP5uT8VQzVyzj7qK3B2tzOzcZ34W51UOg9FLp+A9Bj/UUBkbcsoVfLRkO5cotwJMyFKu6flKYJqY/E+1xzi8cobngLAm20ADFjECvY+NwrlTeyjc0ELwXLNpr/M4GmvLJNvQjcphFT7x9XiIeavRmGeULZ+yHheA5q1621lcVmd2golOAz5Eoq+2+Vi2zKevldPg3HC4ae4YysMYgoP8PPJrnB7V4YDndw4lSDEQ2+X4M7rE97j/yC2Z+3v4FeYTXAF8PV3aimw4Q== Received: from BN6PR19CA0061.namprd19.prod.outlook.com (2603:10b6:404:e3::23) by BN6PR12MB1924.namprd12.prod.outlook.com (2603:10b6:404:108::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4087.44; Wed, 5 May 2021 17:10:48 +0000 Received: from BN8NAM11FT008.eop-nam11.prod.protection.outlook.com (2603:10b6:404:e3:cafe::93) by BN6PR19CA0061.outlook.office365.com (2603:10b6:404:e3::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4108.25 via Frontend Transport; Wed, 5 May 2021 17:10:48 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.112.36) smtp.mailfrom=nvidia.com; lists.ubuntu.com; dkim=none (message not signed) header.d=none;lists.ubuntu.com; dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.112.36 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.112.36; helo=mail.nvidia.com; Received: from mail.nvidia.com (216.228.112.36) by BN8NAM11FT008.mail.protection.outlook.com (10.13.177.95) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.4108.25 via Frontend Transport; Wed, 5 May 2021 17:10:47 +0000 Received: from HQMAIL109.nvidia.com (172.20.187.15) by HQMAIL101.nvidia.com (172.20.187.10) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 5 May 2021 17:10:47 +0000 Received: from vdi.nvidia.com (172.20.145.6) by mail.nvidia.com (172.20.187.15) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Wed, 5 May 2021 10:10:46 -0700 From: Liming Sun To: Subject: [SRU][F:linux-bluefield][PATCH v1 1/1] UBUNTU: SAUCE: mlx-bootctl: rshim logging display from linux sysfs Date: Wed, 5 May 2021 13:10:32 -0400 Message-ID: <8f4bb75041167893ebd991562d4bfcaa2bbaf8ff.1620234248.git.limings@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: References: MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: ba9d0bca-87a9-4096-eb21-08d90fe8ba33 X-MS-TrafficTypeDiagnostic: BN6PR12MB1924: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:335; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: bgV8mf93+63fMPmTle/CUfSYuQk7OijFGY85DIl3vknsJCICeqMRYMhhAEgnUVkIhKuXWTV3KGcJAKISnduPnDR6tI63a+s0XW9XKgMas7vty3Ptx/IA2GWd6vb7n2NRLs2iS2F2Kq7TWefKId6KmptR/c0TJ8okgIgw0FdGbn3bzyc9RXzv//Mv/Fuh4hwtBmgrziRj6vHYLqvRungIFIxn4uqfoJvnvZwZhIOVeR5RQkkX0gEEGYBZyZ1zorCm4aidfQP+eLfC9tgiEwWobMsN3RYnN6ZAnl97MPA0UCuCGscFFpBOQi8hHBVuF74D2xF5J2qDmiASQfsnB1W5rwfHYmZfZVmrmZYxJYdywnxRTGEwrYYNHizjoobnQuAankp1vsADnoi09qSsz7f5ImbFCWw/b0khfF7eLVsQsEEC8+5ISQMTqfCvsEMMJRiyMuvXNiLrQxzjC/dLOLybjL3DvHuv/wUT83TsD+ZF3jSC1LFIQY759rqCqTWm6biqEcikwt9vxRiyKzGJyrQvAwVcmgVza4Rv2oMpnI2F3TcXl2z2+actV4Re+UAbUIxwD2YKx2PwBoJVdWpAMQFPpOZXWUzI9p4mxW3EW8JhGgYBfIv/zk1Qr+b9ZbKA1OAWH61g43L3MMq3vvC4bVJPsMIrDYnJNOf55WkOvhCDah8= X-Forefront-Antispam-Report: CIP:216.228.112.36; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid05.nvidia.com; CAT:NONE; SFS:(4636009)(346002)(136003)(39860400002)(376002)(396003)(46966006)(36840700001)(70206006)(86362001)(186003)(478600001)(83380400001)(82740400003)(6916009)(8936002)(26005)(7696005)(7636003)(356005)(316002)(2906002)(6666004)(5660300002)(70586007)(336012)(36906005)(36756003)(426003)(107886003)(36860700001)(30864003)(4326008)(47076005)(8676002)(82310400003)(2616005); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 May 2021 17:10:47.7861 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: ba9d0bca-87a9-4096-eb21-08d90fe8ba33 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.36]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: BN8NAM11FT008.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN6PR12MB1924 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Liming Sun Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" This commit adds the rshim logging display support from linux sysfs. The display logic is ported from the user-space rshim driver. Module parameter 'rsh_log_clear_on_read' is added to clear the the logging buffer after read when this flag is set. Example: cat /sys/bus/platform/drivers/mlx-bootctl/rsh_log INFO[BL2]: start INFO[BL2]: DDR POST passed INFO[BL2]: UEFI loaded INFO[BL31]: start INFO[BL31]: runtime ... echo 1 > /sys/module/mlx_bootctl/parameters/rsh_log_clear_on_read Change-Id: I50129fc30f9e2e7b6b38713c740968f9235b532a --- drivers/platform/mellanox/mlx-bootctl.c | 408 +++++++++++++++++++++++++++++--- 1 file changed, 376 insertions(+), 32 deletions(-) diff --git a/drivers/platform/mellanox/mlx-bootctl.c b/drivers/platform/mellanox/mlx-bootctl.c index 7ec7c9a..4c85139 100644 --- a/drivers/platform/mellanox/mlx-bootctl.c +++ b/drivers/platform/mellanox/mlx-bootctl.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause /* * Mellanox boot control driver * This driver provides a sysfs interface for systems management @@ -64,6 +64,10 @@ struct boot_name { static void __iomem *rsh_scratch_buf_ctl; static void __iomem *rsh_scratch_buf_data; +static int rsh_log_clear_on_read; +module_param(rsh_log_clear_on_read, int, 0644); +MODULE_PARM_DESC(rsh_log_clear_on_read, "Clear rshim logging buffer after read."); + /* * Objects are stored within the MFG partition per type. Type 0 is not * supported. @@ -86,7 +90,7 @@ enum { * The expected format is: "XX:XX:XX:XX:XX:XX" */ #define MLNX_MFG_OOB_MAC_FORMAT_LEN \ - ((MLNX_MFG_OOB_MAC_LEN * 2) + (MLNX_MFG_OOB_MAC_LEN - 1)) + ((MLNX_MFG_OOB_MAC_LEN * 2) + (MLNX_MFG_OOB_MAC_LEN - 1)) /* The SMC calls in question are atomic, so we don't have to lock here. */ static int smc_call1(unsigned int smc_op, int smc_arg) @@ -290,7 +294,7 @@ static ssize_t fw_reset_store(struct device_driver *drv, static ssize_t oob_mac_show(struct device_driver *drv, char *buf) { - char mac_str[MLNX_MFG_OOB_MAC_FORMAT_LEN] = { 0 }; + char mac_str[MLNX_MFG_OOB_MAC_FORMAT_LEN + 1] = { 0 }; struct arm_smccc_res res; u8 *mac_byte_ptr; @@ -315,14 +319,15 @@ static ssize_t oob_mac_store(struct device_driver *drv, const char *buf, struct arm_smccc_res res; u64 mac_addr = 0; u8 *mac_byte_ptr; - int byte_idx; + int byte_idx, len; if ((count - 1) != MLNX_MFG_OOB_MAC_FORMAT_LEN) return -EINVAL; - if (MLNX_MFG_OOB_MAC_LEN != sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", - &byte[0], &byte[1], &byte[2], - &byte[3], &byte[4], &byte[5])) + len = sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", + &byte[0], &byte[1], &byte[2], + &byte[3], &byte[4], &byte[5]); + if (len != MLNX_MFG_OOB_MAC_LEN) return -EINVAL; mac_byte_ptr = (u8 *)&mac_addr; @@ -340,7 +345,7 @@ static ssize_t oob_mac_store(struct device_driver *drv, const char *buf, static u8 get_opn_type(u8 word) { - switch(word) { + switch (word) { case 0: return MLNX_MFG_TYPE_OPN_0; case 1: @@ -452,7 +457,32 @@ static ssize_t mfg_lock_store(struct device_driver *drv, const char *buf, #define RSH_LOG_LEVEL_SHIFT 0 /* Module ID and type used here. */ -#define RSH_LOG_TYPE 0x04ULL /* message */ +#define BF_RSH_LOG_TYPE_UNKNOWN 0x00ULL +#define BF_RSH_LOG_TYPE_PANIC 0x01ULL +#define BF_RSH_LOG_TYPE_EXCEPTION 0x02ULL +#define BF_RSH_LOG_TYPE_UNUSED 0x03ULL +#define BF_RSH_LOG_TYPE_MSG 0x04ULL + +/* Utility macro. */ +#define BF_RSH_LOG_MOD_MASK 0x0FULL +#define BF_RSH_LOG_MOD_SHIFT 60 +#define BF_RSH_LOG_TYPE_MASK 0x0FULL +#define BF_RSH_LOG_TYPE_SHIFT 56 +#define BF_RSH_LOG_LEN_MASK 0x7FULL +#define BF_RSH_LOG_LEN_SHIFT 48 +#define BF_RSH_LOG_ARG_MASK 0xFFFFFFFFULL +#define BF_RSH_LOG_ARG_SHIFT 16 +#define BF_RSH_LOG_HAS_ARG_MASK 0xFFULL +#define BF_RSH_LOG_HAS_ARG_SHIFT 8 +#define BF_RSH_LOG_LEVEL_MASK 0xFFULL +#define BF_RSH_LOG_LEVEL_SHIFT 0 +#define BF_RSH_LOG_PC_MASK 0xFFFFFFFFULL +#define BF_RSH_LOG_PC_SHIFT 0 +#define BF_RSH_LOG_SYNDROME_MASK 0xFFFFFFFFULL +#define BF_RSH_LOG_SYNDROME_SHIFT 0 + +#define BF_RSH_LOG_HEADER_GET(f, h) \ + (((h) >> BF_RSH_LOG_##f##_SHIFT) & BF_RSH_LOG_##f##_MASK) /* Log message level. */ enum { @@ -461,16 +491,159 @@ enum { RSH_LOG_ERR }; -const char *rsh_log_level[] = {"INFO", "WARN", "ERR"}; +/* Log module */ +const char * const rsh_log_mod[] = { + "MISC", "BL1", "BL2", "BL2R", "BL31", "UEFI" +}; + +const char *rsh_log_level[] = {"INFO", "WARN", "ERR", "ASSERT"}; + +#define AARCH64_MRS_REG_SHIFT 5 +#define AARCH64_MRS_REG_MASK 0xffff +#define AARCH64_ESR_ELX_EXCEPTION_CLASS_SHIFT 26 + +struct rsh_log_reg { + char *name; + u32 opcode; +} rsh_log_reg; + +static struct rsh_log_reg rsh_log_regs[] = { + {"actlr_el1", 0b1100000010000001}, + {"actlr_el2", 0b1110000010000001}, + {"actlr_el3", 0b1111000010000001}, + {"afsr0_el1", 0b1100001010001000}, + {"afsr0_el2", 0b1110001010001000}, + {"afsr0_el3", 0b1111001010001000}, + {"afsr1_el1", 0b1100001010001001}, + {"afsr1_el2", 0b1110001010001001}, + {"afsr1_el3", 0b1111001010001001}, + {"amair_el1", 0b1100010100011000}, + {"amair_el2", 0b1110010100011000}, + {"amair_el3", 0b1111010100011000}, + {"ccsidr_el1", 0b1100100000000000}, + {"clidr_el1", 0b1100100000000001}, + {"cntkctl_el1", 0b1100011100001000}, + {"cntp_ctl_el0", 0b1101111100010001}, + {"cntp_cval_el0", 0b1101111100010010}, + {"cntv_ctl_el0", 0b1101111100011001}, + {"cntv_cval_el0", 0b1101111100011010}, + {"contextidr_el1", 0b1100011010000001}, + {"cpacr_el1", 0b1100000010000010}, + {"cptr_el2", 0b1110000010001010}, + {"cptr_el3", 0b1111000010001010}, + {"vtcr_el2", 0b1110000100001010}, + {"ctr_el0", 0b1101100000000001}, + {"currentel", 0b1100001000010010}, + {"dacr32_el2", 0b1110000110000000}, + {"daif", 0b1101101000010001}, + {"dczid_el0", 0b1101100000000111}, + {"dlr_el0", 0b1101101000101001}, + {"dspsr_el0", 0b1101101000101000}, + {"elr_el1", 0b1100001000000001}, + {"elr_el2", 0b1110001000000001}, + {"elr_el3", 0b1111001000000001}, + {"esr_el1", 0b1100001010010000}, + {"esr_el2", 0b1110001010010000}, + {"esr_el3", 0b1111001010010000}, + {"esselr_el1", 0b1101000000000000}, + {"far_el1", 0b1100001100000000}, + {"far_el2", 0b1110001100000000}, + {"far_el3", 0b1111001100000000}, + {"fpcr", 0b1101101000100000}, + {"fpexc32_el2", 0b1110001010011000}, + {"fpsr", 0b1101101000100001}, + {"hacr_el2", 0b1110000010001111}, + {"har_el2", 0b1110000010001000}, + {"hpfar_el2", 0b1110001100000100}, + {"hstr_el2", 0b1110000010001011}, + {"far_el1", 0b1100001100000000}, + {"far_el2", 0b1110001100000000}, + {"far_el3", 0b1111001100000000}, + {"hcr_el2", 0b1110000010001000}, + {"hpfar_el2", 0b1110001100000100}, + {"id_aa64afr0_el1", 0b1100000000101100}, + {"id_aa64afr1_el1", 0b1100000000101101}, + {"id_aa64dfr0_el1", 0b1100000000101100}, + {"id_aa64isar0_el1", 0b1100000000110000}, + {"id_aa64isar1_el1", 0b1100000000110001}, + {"id_aa64mmfr0_el1", 0b1100000000111000}, + {"id_aa64mmfr1_el1", 0b1100000000111001}, + {"id_aa64pfr0_el1", 0b1100000000100000}, + {"id_aa64pfr1_el1", 0b1100000000100001}, + {"ifsr32_el2", 0b1110001010000001}, + {"isr_el1", 0b1100011000001000}, + {"mair_el1", 0b1100010100010000}, + {"mair_el2", 0b1110010100010000}, + {"mair_el3", 0b1111010100010000}, + {"midr_el1", 0b1100000000000000}, + {"mpidr_el1", 0b1100000000000101}, + {"nzcv", 0b1101101000010000}, + {"revidr_el1", 0b1100000000000110}, + {"rmr_el3", 0b1111011000000010}, + {"par_el1", 0b1100001110100000}, + {"rvbar_el3", 0b1111011000000001}, + {"scr_el3", 0b1111000010001000}, + {"sctlr_el1", 0b1100000010000000}, + {"sctlr_el2", 0b1110000010000000}, + {"sctlr_el3", 0b1111000010000000}, + {"sp_el0", 0b1100001000001000}, + {"sp_el1", 0b1110001000001000}, + {"spsel", 0b1100001000010000}, + {"spsr_abt", 0b1110001000011001}, + {"spsr_el1", 0b1100001000000000}, + {"spsr_el2", 0b1110001000000000}, + {"spsr_el3", 0b1111001000000000}, + {"spsr_fiq", 0b1110001000011011}, + {"spsr_irq", 0b1110001000011000}, + {"spsr_und", 0b1110001000011010}, + {"tcr_el1", 0b1100000100000010}, + {"tcr_el2", 0b1110000100000010}, + {"tcr_el3", 0b1111000100000010}, + {"tpidr_el0", 0b1101111010000010}, + {"tpidr_el1", 0b1100011010000100}, + {"tpidr_el2", 0b1110011010000010}, + {"tpidr_el3", 0b1111011010000010}, + {"tpidpro_el0", 0b1101111010000011}, + {"vbar_el1", 0b1100011000000000}, + {"vbar_el2", 0b1110011000000000}, + {"vbar_el3", 0b1111011000000000}, + {"vmpidr_el2", 0b1110000000000101}, + {"vpidr_el2", 0b1110000000000000}, + {"ttbr0_el1", 0b1100000100000000}, + {"ttbr0_el2", 0b1110000100000000}, + {"ttbr0_el3", 0b1111000100000000}, + {"ttbr1_el1", 0b1100000100000001}, + {"vtcr_el2", 0b1110000100001010}, + {"vttbr_el2", 0b1110000100001000}, + {NULL, 0b0000000000000000}, +}; /* Size(8-byte words) of the log buffer. */ -#define RSH_SCRATCH_BUF_CTL_IDX_MAX 0x7f +#define RSH_SCRATCH_BUF_CTL_IDX_MASK 0x7f + +static int rsh_log_sem_lock(void) +{ + unsigned long timeout; + + /* Take the semaphore. */ + timeout = jiffies + msecs_to_jiffies(100); + while (readq(rsh_semaphore)) { + if (time_after(jiffies, timeout)) + return -ETIMEDOUT; + } + + return 0; +} + +static void rsh_log_sem_unlock(void) +{ + writeq(0, rsh_semaphore); +} static ssize_t rsh_log_store(struct device_driver *drv, const char *buf, size_t count) { - int idx, num, len, size = (int)count, level = RSH_LOG_INFO; - unsigned long timeout; + int idx, num, len, size = (int)count, level = RSH_LOG_INFO, rc; u64 data; if (!size) @@ -501,22 +674,20 @@ static ssize_t rsh_log_store(struct device_driver *drv, const char *buf, } /* Take the semaphore. */ - timeout = jiffies + msecs_to_jiffies(100); - while (readq(rsh_semaphore)) { - if (time_after(jiffies, timeout)) - return -ETIMEDOUT; - } + rc = rsh_log_sem_lock(); + if (rc) + return rc; /* Calculate how many words are available. */ num = (size + sizeof(u64) - 1) / sizeof(u64); idx = readq(rsh_scratch_buf_ctl); - if (idx + num + 1 >= RSH_SCRATCH_BUF_CTL_IDX_MAX) - num = RSH_SCRATCH_BUF_CTL_IDX_MAX - idx - 1; + if (idx + num + 1 >= RSH_SCRATCH_BUF_CTL_IDX_MASK) + num = RSH_SCRATCH_BUF_CTL_IDX_MASK - idx - 1; if (num <= 0) goto done; /* Write Header. */ - data = (RSH_LOG_TYPE << RSH_LOG_TYPE_SHIFT) | + data = (BF_RSH_LOG_TYPE_MSG << RSH_LOG_TYPE_SHIFT) | ((u64)num << RSH_LOG_LEN_SHIFT) | ((u64)level << RSH_LOG_LEVEL_SHIFT); writeq(data, rsh_scratch_buf_data); @@ -528,7 +699,7 @@ static ssize_t rsh_log_store(struct device_driver *drv, const char *buf, memcpy(&data, buf, len); len = 0; } else { - memcpy (&data, buf, sizeof(u64)); + memcpy(&data, buf, sizeof(u64)); len -= sizeof(u64); buf += sizeof(u64); } @@ -537,24 +708,197 @@ static ssize_t rsh_log_store(struct device_driver *drv, const char *buf, done: /* Release the semaphore. */ - writeq(0, rsh_semaphore); + rsh_log_sem_unlock(); /* Ignore the rest if no more space. */ return count; } -#define MBC_DRV_ATTR(_name) DRIVER_ATTR_RW(_name) +static char *rsh_log_get_reg_name(u64 opcode) +{ + struct rsh_log_reg *reg = rsh_log_regs; + + while (reg->name) { + if (reg->opcode == opcode) + return reg->name; + reg++; + } + + return "unknown"; +} + +static int rsh_log_show_crash(u64 hdr, char *buf) +{ + int i, module, type, len, n = 0; + u32 pc, syndrome, ec; + u64 opcode, data; + char *p = buf; + + module = BF_RSH_LOG_HEADER_GET(MOD, hdr); + if (module >= ARRAY_SIZE(rsh_log_mod)) + module = 0; + type = BF_RSH_LOG_HEADER_GET(TYPE, hdr); + len = BF_RSH_LOG_HEADER_GET(LEN, hdr); + + if (type == BF_RSH_LOG_TYPE_EXCEPTION) { + syndrome = BF_RSH_LOG_HEADER_GET(SYNDROME, hdr); + ec = syndrome >> AARCH64_ESR_ELX_EXCEPTION_CLASS_SHIFT; + n = sprintf(p, " Exception(%s): syndrome = 0x%x%s\n", + rsh_log_mod[module], syndrome, + (ec == 0x24 || ec == 0x25) ? "(Data Abort)" : + (ec == 0x2f) ? "(SError)" : ""); + } else if (type == BF_RSH_LOG_TYPE_PANIC) { + pc = BF_RSH_LOG_HEADER_GET(PC, hdr); + n = sprintf(p, " PANIC(%s): PC = 0x%x\n", rsh_log_mod[module], + pc); + } + if (n > 0) + p += n; + + /* + * Read the registers in a loop. 'len' is the total number of words in + * 8-bytes. Two words are read in each loop. + */ + for (i = 0; i < len/2; i++) { + opcode = readq(rsh_scratch_buf_data); + data = readq(rsh_scratch_buf_data); + + opcode = (opcode >> AARCH64_MRS_REG_SHIFT) & + AARCH64_MRS_REG_MASK; + n = sprintf(p, " %-16s0x%llx\n", rsh_log_get_reg_name(opcode), + (unsigned long long)data); + if (n > 0) + p += n; + } + + return p - buf; +} + +static int rsh_log_format_msg(char *buf, const char *msg, ...) +{ + va_list args; + int len; + + va_start(args, msg); + len = vsprintf(buf, msg, args); + va_end(args); + + return len; +} + +static int rsh_log_show_msg(u64 hdr, char *buf) +{ + int has_arg = BF_RSH_LOG_HEADER_GET(HAS_ARG, hdr); + int level = BF_RSH_LOG_HEADER_GET(LEVEL, hdr); + int module = BF_RSH_LOG_HEADER_GET(MOD, hdr); + int len = BF_RSH_LOG_HEADER_GET(LEN, hdr); + u32 arg = BF_RSH_LOG_HEADER_GET(ARG, hdr); + char *msg, *p; + u64 data; + + if (len <= 0) + return -EINVAL; + + if (module >= ARRAY_SIZE(rsh_log_mod)) + module = 0; + + if (level >= ARRAY_SIZE(rsh_log_level)) + level = 0; + + msg = kmalloc(len * sizeof(u64) + 1, GFP_KERNEL); + if (!msg) + return 0; + p = msg; + + while (len--) { + data = readq(rsh_scratch_buf_data); + memcpy(p, &data, sizeof(data)); + p += sizeof(data); + } + *p = '\0'; + if (!has_arg) { + len = sprintf(buf, " %s[%s]: %s\n", rsh_log_level[level], + rsh_log_mod[module], msg); + } else { + len = sprintf(buf, " %s[%s]: ", rsh_log_level[level], + rsh_log_mod[module]); + len += rsh_log_format_msg(buf + len, msg, arg); + len += sprintf(buf + len, "\n"); + } + + kfree(msg); + return len; +} + +static ssize_t rsh_log_show(struct device_driver *drv, char *buf) +{ + u64 hdr; + char *p = buf; + int i, n, rc, idx, type, len; + + if (!rsh_semaphore || !rsh_scratch_buf_ctl) + return -EOPNOTSUPP; + + /* Take the semaphore. */ + rc = rsh_log_sem_lock(); + if (rc) + return rc; + + /* Save the current index and read from 0. */ + idx = readq(rsh_scratch_buf_ctl) & RSH_SCRATCH_BUF_CTL_IDX_MASK; + if (!idx) + goto done; + writeq(0, rsh_scratch_buf_ctl); + + i = 0; + while (i < idx) { + hdr = readq(rsh_scratch_buf_data); + type = BF_RSH_LOG_HEADER_GET(TYPE, hdr); + len = BF_RSH_LOG_HEADER_GET(LEN, hdr); + i += 1 + len; + if (i > idx) + break; + + switch (type) { + case BF_RSH_LOG_TYPE_PANIC: + case BF_RSH_LOG_TYPE_EXCEPTION: + n = rsh_log_show_crash(hdr, p); + p += n; + break; + case BF_RSH_LOG_TYPE_MSG: + n = rsh_log_show_msg(hdr, p); + p += n; + break; + default: + /* Drain this message. */ + while (len--) + (void) readq(rsh_scratch_buf_data); + break; + } + } + + if (rsh_log_clear_on_read) + writeq(0, rsh_scratch_buf_ctl); + else + writeq(idx, rsh_scratch_buf_ctl); + +done: + /* Release the semaphore. */ + rsh_log_sem_unlock(); + + return p - buf; +} -static MBC_DRV_ATTR(post_reset_wdog); -static MBC_DRV_ATTR(reset_action); -static MBC_DRV_ATTR(second_reset_action); +static DRIVER_ATTR_RW(post_reset_wdog); +static DRIVER_ATTR_RW(reset_action); +static DRIVER_ATTR_RW(second_reset_action); static DRIVER_ATTR_RO(lifecycle_state); static DRIVER_ATTR_RO(secure_boot_fuse_state); static DRIVER_ATTR_WO(fw_reset); -static MBC_DRV_ATTR(oob_mac); -static MBC_DRV_ATTR(opn_str); +static DRIVER_ATTR_RW(oob_mac); +static DRIVER_ATTR_RW(opn_str); static DRIVER_ATTR_WO(mfg_lock); -static DRIVER_ATTR_WO(rsh_log); +static DRIVER_ATTR_RW(rsh_log); static struct attribute *mbc_dev_attrs[] = { &driver_attr_post_reset_wdog.attr, @@ -626,7 +970,7 @@ static ssize_t mbc_bootfifo_read_raw(struct file *filp, struct kobject *kobj, } static struct bin_attribute mbc_bootfifo_sysfs_attr = { - .attr = { .name = "bootfifo", .mode = S_IRUSR }, + .attr = { .name = "bootfifo", .mode = 0400 }, .read = mbc_bootfifo_read_raw, }; @@ -720,4 +1064,4 @@ static int mbc_remove(struct platform_device *pdev) MODULE_DESCRIPTION(DRIVER_DESCRIPTION); MODULE_VERSION(DRIVER_VERSION); MODULE_AUTHOR("Mellanox Technologies"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("Dual BSD/GPL");