From nobody Sat Nov 23 22:46:15 2024 Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9874C19D884; Mon, 11 Nov 2024 12:48:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.156.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731329313; cv=none; b=o4CG9cCelJyAHymxUFnDQg44EiNvRQmWgqjvBR1uOFTT1pSktaLurg6boizwQQK/MMavGLiAKNMUUHbzJgj1ZlRvmP6wiHTgWPGHe5DfJ5EqnalYH9/qxkOK6BUhWp6NWSEeGRGtgCenJ6yKaExdvdQGUb/qM5ZWEw7YTJgaTvs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731329313; c=relaxed/simple; bh=2WN9wccwhKH1U2cE8jLIwLiED+5eZXILD/PLKna2Sl8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Is9odXRJ1E5E0jlGG72hfjIDJYhrTujMthQ7CKAjGJ0DRHYi3DPhIFI/wsFRN1fHhIwBGUWv6IEFn+4pQMjfKJWScYGwOkCS5wnbnVwQ038oNfQnDCOIGIEytfaSkFwvgKR66Nl7fI8BLpV9RpLyfKOBxbGvLE2/boOQGSIGqFQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com; spf=pass smtp.mailfrom=marvell.com; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b=Qz4lHp8a; arc=none smtp.client-ip=67.231.156.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marvell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b="Qz4lHp8a" Received: from pps.filterd (m0431383.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 4ABCFNwZ031736; Mon, 11 Nov 2024 04:48:19 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=pfpt0220; bh=9 a9JArKBjG+dOCqDWhuvG4xfABvA+VjzWn0PGTTG8Tw=; b=Qz4lHp8aDDyCnqDIO 3bi5aqzVcwyGWb+5uJ9LCoLhTLaNH0nA1Wjtd21eqNkFE1N5Ah+CNFS6Tb02ttiF jJI/HVSCQdNAH36/VLt64d8iS2VMTWYGeWXp5veeMd5nArBJvjIXR0aZ67RBf4MC NNczviU9na0eaC/kPILQeJUPI53bU9DN7QQhL21FloZwHx2ol8Xt8Zr+C5s1mqLP gqc0SxXmjlWjRbYaRSClsnGzaX2uhKNsHiEXQOAlNxFR1mT4Ivu1v0qAt6NlUkvC R4j3V9PS/IlulkK2cp0s/VUTerLaJyn+1rYjz6cRngn7PpxCOl5CzL1BpzNatlm7 dUvhg== Received: from dc5-exch05.marvell.com ([199.233.59.128]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 42uhrrg1c2-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 11 Nov 2024 04:48:19 -0800 (PST) Received: from DC5-EXCH05.marvell.com (10.69.176.209) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.4; Mon, 11 Nov 2024 04:48:17 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server id 15.2.1544.4 via Frontend Transport; Mon, 11 Nov 2024 04:48:17 -0800 Received: from virtx40.. (unknown [10.28.34.196]) by maili.marvell.com (Postfix) with ESMTP id 4E34B3F70AE; Mon, 11 Nov 2024 04:48:12 -0800 (PST) From: Linu Cherian To: , , CC: , , , , , , , , , , , Linu Cherian Subject: [PATCH v11 4/8] coresight: tmc: Enable panic sync handling Date: Mon, 11 Nov 2024 18:17:42 +0530 Message-ID: <20241111124746.2210378-5-lcherian@marvell.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241111124746.2210378-1-lcherian@marvell.com> References: <20241111124746.2210378-1-lcherian@marvell.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-GUID: qI_HEHT6liYAcEfwYZLZuRa8RIjnFCPj X-Proofpoint-ORIG-GUID: qI_HEHT6liYAcEfwYZLZuRa8RIjnFCPj X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.687,Hydra:6.0.235,FMLib:17.0.607.475 definitions=2020-10-13_15,2020-10-13_02,2020-04-07_01 Content-Type: text/plain; charset="utf-8" - Get reserved region from device tree node for metadata - Define metadata format for TMC - Add TMC ETR panic sync handler that syncs register snapshot to metadata region - Add TMC ETF panic sync handler that syncs register snapshot to metadata region and internal SRAM to reserved trace buffer region. Signed-off-by: Linu Cherian Reviewed-by: James Clark --- Changelog from v10: * Converted all csdev_access_* to readl functions in tmc_panic_sync_* * Added "tmc" prefix for register snapshots in struct tmc_crash_metadata * Converted dev_info to dev_dbg in panic handlers=20 * Converted dsb to dmb in panic handlers=20 * Removed a redudant reserved buffer check in panic handler * Keeping the Reviewed-by as is since the changes are trivial .../hwtracing/coresight/coresight-tmc-core.c | 14 ++++ .../hwtracing/coresight/coresight-tmc-etf.c | 80 +++++++++++++++++++ .../hwtracing/coresight/coresight-tmc-etr.c | 73 +++++++++++++++++ drivers/hwtracing/coresight/coresight-tmc.h | 66 +++++++++++++++ 4 files changed, 233 insertions(+) diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwt= racing/coresight/coresight-tmc-core.c index 248989833b20..1e3938ec12cb 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-core.c +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c @@ -444,6 +444,20 @@ static void tmc_get_reserved_region(struct device *par= ent) =20 drvdata->resrv_buf.paddr =3D res.start; drvdata->resrv_buf.size =3D resource_size(&res); + + if (of_tmc_get_reserved_resource_by_name(parent, "metadata", &res)) + return; + + drvdata->crash_mdata.vaddr =3D memremap(res.start, + resource_size(&res), + MEMREMAP_WC); + if (IS_ERR_OR_NULL(drvdata->crash_mdata.vaddr)) { + dev_err(parent, "Metadata memory mapping failed\n"); + return; + } + + drvdata->crash_mdata.paddr =3D res.start; + drvdata->crash_mdata.size =3D resource_size(&res); } =20 /* Detect and initialise the capabilities of a TMC ETR */ diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtr= acing/coresight/coresight-tmc-etf.c index d4f641cd9de6..0f9155a10ac2 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c @@ -590,6 +590,81 @@ static unsigned long tmc_update_etf_buffer(struct core= sight_device *csdev, return to_read; } =20 +static int tmc_panic_sync_etf(struct coresight_device *csdev) +{ + u32 val; + struct tmc_crash_metadata *mdata; + struct tmc_drvdata *drvdata =3D dev_get_drvdata(csdev->dev.parent); + + mdata =3D (struct tmc_crash_metadata *)drvdata->crash_mdata.vaddr; + + /* Make sure we have valid reserved memory */ + if (!tmc_has_reserved_buffer(drvdata) || + !tmc_has_crash_mdata_buffer(drvdata)) + return 0; + + tmc_crashdata_set_invalid(drvdata); + + CS_UNLOCK(drvdata->base); + + /* Proceed only if ETF is enabled or configured as sink */ + val =3D readl(drvdata->base + TMC_CTL); + if (!(val & TMC_CTL_CAPT_EN)) + goto out; + val =3D readl(drvdata->base + TMC_MODE); + if (val !=3D TMC_MODE_CIRCULAR_BUFFER) + goto out; + + val =3D readl(drvdata->base + TMC_FFSR); + /* Do manual flush and stop only if its not auto-stopped */ + if (!(val & TMC_FFSR_FT_STOPPED)) { + dev_dbg(&csdev->dev, + "%s: Triggering manual flush\n", __func__); + tmc_flush_and_stop(drvdata); + } else + tmc_wait_for_tmcready(drvdata); + + /* Sync registers from hardware to metadata region */ + mdata->tmc_sts =3D readl(drvdata->base + TMC_STS); + mdata->tmc_mode =3D readl(drvdata->base + TMC_MODE); + mdata->tmc_ffcr =3D readl(drvdata->base + TMC_FFCR); + mdata->tmc_ffsr =3D readl(drvdata->base + TMC_FFSR); + + /* Sync Internal SRAM to reserved trace buffer region */ + drvdata->buf =3D drvdata->resrv_buf.vaddr; + tmc_etb_dump_hw(drvdata); + /* Store as per RSZ register convention */ + mdata->tmc_ram_size =3D drvdata->len >> 2; + + /* Other fields for processing trace buffer reads */ + mdata->tmc_rrp =3D 0; + mdata->tmc_dba =3D 0; + mdata->tmc_rwp =3D drvdata->len; + mdata->trace_paddr =3D drvdata->resrv_buf.paddr; + + mdata->version =3D CS_CRASHDATA_VERSION; + + /* + * Make sure all previous writes are ordered, + * before we mark valid + */ + dmb(sy); + mdata->valid =3D true; + /* + * Below order need to maintained, since crc of metadata + * is dependent on first + */ + mdata->crc32_tdata =3D find_crash_tracedata_crc(drvdata, mdata); + mdata->crc32_mdata =3D find_crash_metadata_crc(mdata); + + tmc_disable_hw(drvdata); + + dev_dbg(&csdev->dev, "%s: success\n", __func__); +out: + CS_UNLOCK(drvdata->base); + return 0; +} + static const struct coresight_ops_sink tmc_etf_sink_ops =3D { .enable =3D tmc_enable_etf_sink, .disable =3D tmc_disable_etf_sink, @@ -603,6 +678,10 @@ static const struct coresight_ops_link tmc_etf_link_op= s =3D { .disable =3D tmc_disable_etf_link, }; =20 +static const struct coresight_ops_panic tmc_etf_sync_ops =3D { + .sync =3D tmc_panic_sync_etf, +}; + const struct coresight_ops tmc_etb_cs_ops =3D { .sink_ops =3D &tmc_etf_sink_ops, }; @@ -610,6 +689,7 @@ const struct coresight_ops tmc_etb_cs_ops =3D { const struct coresight_ops tmc_etf_cs_ops =3D { .sink_ops =3D &tmc_etf_sink_ops, .link_ops =3D &tmc_etf_link_ops, + .panic_ops =3D &tmc_etf_sync_ops, }; =20 int tmc_read_prepare_etb(struct tmc_drvdata *drvdata) diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtr= acing/coresight/coresight-tmc-etr.c index 8bca5b36334a..fb944a68a11c 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -1814,6 +1814,74 @@ static int tmc_disable_etr_sink(struct coresight_dev= ice *csdev) return 0; } =20 +static int tmc_panic_sync_etr(struct coresight_device *csdev) +{ + u32 val; + struct tmc_crash_metadata *mdata; + struct tmc_drvdata *drvdata =3D dev_get_drvdata(csdev->dev.parent); + + mdata =3D (struct tmc_crash_metadata *)drvdata->crash_mdata.vaddr; + + if (!drvdata->etr_buf) + return 0; + + /* Being in RESRV mode implies valid reserved memory as well */ + if (drvdata->etr_buf->mode !=3D ETR_MODE_RESRV) + return 0; + + if (!tmc_has_crash_mdata_buffer(drvdata)) + return 0; + + CS_UNLOCK(drvdata->base); + + /* Proceed only if ETR is enabled */ + val =3D readl(drvdata->base + TMC_CTL); + if (!(val & TMC_CTL_CAPT_EN)) + goto out; + + val =3D readl(drvdata->base + TMC_FFSR); + /* Do manual flush and stop only if its not auto-stopped */ + if (!(val & TMC_FFSR_FT_STOPPED)) { + dev_dbg(&csdev->dev, + "%s: Triggering manual flush\n", __func__); + tmc_flush_and_stop(drvdata); + } else + tmc_wait_for_tmcready(drvdata); + + /* Sync registers from hardware to metadata region */ + mdata->tmc_ram_size =3D readl(drvdata->base + TMC_RSZ); + mdata->tmc_sts =3D readl(drvdata->base + TMC_STS); + mdata->tmc_mode =3D readl(drvdata->base + TMC_MODE); + mdata->tmc_ffcr =3D readl(drvdata->base + TMC_FFCR); + mdata->tmc_ffsr =3D readl(drvdata->base + TMC_FFSR); + mdata->tmc_rrp =3D tmc_read_rrp(drvdata); + mdata->tmc_rwp =3D tmc_read_rwp(drvdata); + mdata->tmc_dba =3D tmc_read_dba(drvdata); + mdata->trace_paddr =3D drvdata->resrv_buf.paddr; + mdata->version =3D CS_CRASHDATA_VERSION; + + /* + * Make sure all previous writes are ordered, + * before we mark valid + */ + dmb(sy); + mdata->valid =3D true; + /* + * Below order need to maintained, since crc of metadata + * is dependent on first + */ + mdata->crc32_tdata =3D find_crash_tracedata_crc(drvdata, mdata); + mdata->crc32_mdata =3D find_crash_metadata_crc(mdata); + + tmc_disable_hw(drvdata); + + dev_dbg(&csdev->dev, "%s: success\n", __func__); +out: + CS_UNLOCK(drvdata->base); + + return 0; +} + static const struct coresight_ops_sink tmc_etr_sink_ops =3D { .enable =3D tmc_enable_etr_sink, .disable =3D tmc_disable_etr_sink, @@ -1822,8 +1890,13 @@ static const struct coresight_ops_sink tmc_etr_sink_= ops =3D { .free_buffer =3D tmc_free_etr_buffer, }; =20 +static const struct coresight_ops_panic tmc_etr_sync_ops =3D { + .sync =3D tmc_panic_sync_etr, +}; + const struct coresight_ops tmc_etr_cs_ops =3D { .sink_ops =3D &tmc_etr_sink_ops, + .panic_ops =3D &tmc_etr_sync_ops, }; =20 int tmc_read_prepare_etr(struct tmc_drvdata *drvdata) diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracin= g/coresight/coresight-tmc.h index d2261eddab71..d76e83fc840b 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -12,6 +12,7 @@ #include #include #include +#include =20 #define TMC_RSZ 0x004 #define TMC_STS 0x00c @@ -76,6 +77,9 @@ #define TMC_AXICTL_AXCACHE_OS (0xf << 2) #define TMC_AXICTL_ARCACHE_OS (0xf << 16) =20 +/* TMC_FFSR - 0x300 */ +#define TMC_FFSR_FT_STOPPED BIT(1) + /* TMC_FFCR - 0x304 */ #define TMC_FFCR_FLUSHMAN_BIT 6 #define TMC_FFCR_EN_FMT BIT(0) @@ -94,6 +98,9 @@ =20 #define TMC_AUTH_NSID_MASK GENMASK(1, 0) =20 +/* Major version 1 Minor version 0 */ +#define CS_CRASHDATA_VERSION (1 << 16) + enum tmc_config_type { TMC_CONFIG_TYPE_ETB, TMC_CONFIG_TYPE_ETR, @@ -131,6 +138,25 @@ enum tmc_mem_intf_width { #define CORESIGHT_SOC_600_ETR_CAPS \ (TMC_ETR_SAVE_RESTORE | TMC_ETR_AXI_ARCACHE) =20 +/* TMC metadata region for ETR and ETF configurations */ +struct tmc_crash_metadata { + uint32_t crc32_mdata; /* crc of metadata */ + uint32_t crc32_tdata; /* crc of tracedata */ + uint32_t version; /* 31:16 Major version, 15:0 Minor version */ + uint32_t valid; /* Indicate if this ETF/ETR was enabled */ + uint32_t tmc_ram_size; /* Ram Size register */ + uint32_t tmc_sts; /* Status register */ + uint32_t tmc_mode; /* Mode register */ + uint32_t tmc_ffcr; /* Formatter and flush control register */ + uint32_t tmc_ffsr; /* Formatter and flush status register */ + uint32_t reserved32; + uint64_t tmc_rrp; /* Ram Read pointer register */ + uint64_t tmc_rwp; /* Ram Write pointer register */ + uint64_t tmc_dba; /* Data buffer address register */ + uint64_t trace_paddr; /* Phys address of trace buffer */ + uint64_t reserved64[3]; +}; + enum etr_mode { ETR_MODE_FLAT, /* Uses contiguous flat buffer */ ETR_MODE_ETR_SG, /* Uses in-built TMC ETR SG mechanism */ @@ -205,6 +231,8 @@ struct tmc_resrv_buf { * retention (after crash) only when ETR_MODE_RESRV buffer * mode is enabled. Used by ETF for trace data retention * (after crash) by default. + * @crash_mdata: Reserved memory for storing tmc crash metadata. + * Used by ETR/ETF. */ struct tmc_drvdata { struct clk *pclk; @@ -231,6 +259,7 @@ struct tmc_drvdata { struct etr_buf *sysfs_buf; struct etr_buf *perf_buf; struct tmc_resrv_buf resrv_buf; + struct tmc_resrv_buf crash_mdata; }; =20 struct etr_buf_operations { @@ -356,6 +385,43 @@ static inline bool tmc_has_reserved_buffer(struct tmc_= drvdata *drvdata) return false; } =20 +static inline bool tmc_has_crash_mdata_buffer(struct tmc_drvdata *drvdata) +{ + if (drvdata->crash_mdata.vaddr && + drvdata->crash_mdata.size) + return true; + return false; +} + +static inline void tmc_crashdata_set_invalid(struct tmc_drvdata *drvdata) +{ + struct tmc_crash_metadata *mdata; + + mdata =3D (struct tmc_crash_metadata *)drvdata->crash_mdata.vaddr; + + if (tmc_has_crash_mdata_buffer(drvdata)) + mdata->valid =3D false; +} + +static inline uint32_t find_crash_metadata_crc(struct tmc_crash_metadata *= md) +{ + unsigned long crc_size; + + crc_size =3D sizeof(struct tmc_crash_metadata) - + offsetof(struct tmc_crash_metadata, crc32_tdata); + return crc32_le(0, (void *)&md->crc32_tdata, crc_size); +} + +static inline uint32_t find_crash_tracedata_crc(struct tmc_drvdata *drvdat= a, + struct tmc_crash_metadata *md) +{ + unsigned long crc_size; + + /* Take CRC of configured buffer size to keep it simple */ + crc_size =3D md->tmc_ram_size << 2; + return crc32_le(0, (void *)drvdata->resrv_buf.vaddr, crc_size); +} + struct coresight_device *tmc_etr_get_catu_device(struct tmc_drvdata *drvda= ta); =20 void tmc_etr_set_catu_ops(const struct etr_buf_operations *catu); --=20 2.34.1