Krait L1/L2 EDAC driver
Subsystems (5)
v6 cover Krait L1/L2 EDAC driver
This patchset adds support for the Krait L1/L2 cache error detection hardware. The second patch adds the Krait L2 indirection register code. This patch is in need of an ACK from ARM folks. The next two patches add the driver and the binding and the final patch fixes up the DT nodes to match the binding (this last one should go through the arm-soc tree).
NOTE: the DT binding patches rely on Lorenzo's cache DT binding document[1]
Changes since v5:
* Don't rely on platform device being created from cpus node
* Get interrupts from L1 cache node
* Rework binding to be in cache document
Changes since v4:
* Prefixed l2 accessors functions with krait_
* Dropped first two patches as Boris says he picked them up
Changes since v3:
* Fixed l1_irq handler to properly dereference dev_id
Changes since v2:
* Picked up acks
* s/an/a/ in DT binding
Stephen Boyd (5):
genirq: export percpu irq functions for module usage
ARM: Add Krait L2 register accessor functions
devicetree: bindings: Document Krait cache error interrupts
edac: Add support for Krait CPU cache error detection
ARM: dts: msm: Fix Krait CPU/L2 nodes
Documentation/devicetree/bindings/arm/cache.txt | 48 ++- arch/arm/boot/dts/qcom-msm8960.dtsi | 29 +- arch/arm/boot/dts/qcom-msm8974.dtsi | 49 +++- arch/arm/common/Kconfig | 3 + arch/arm/common/Makefile | 1 + arch/arm/common/krait-l2-accessors.c | 58 ++++ arch/arm/include/asm/krait-l2-accessors.h | 20 ++ drivers/edac/Kconfig | 8 + drivers/edac/Makefile | 2 + drivers/edac/krait_edac.c | 370 ++++++++++++++++++++++++ kernel/irq/manage.c | 2 + 11 files changed, 568 insertions(+), 22 deletions(-) create mode 100644 arch/arm/common/krait-l2-accessors.c create mode 100644 arch/arm/include/asm/krait-l2-accessors.h create mode 100644 drivers/edac/krait_edac.c
[1] http://www.spinics.net/lists/arm-kernel/msg308540.html
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
PATCH v6 1/5 genirq: export percpu irq functions for module usage
In the near future we're going to use these percpu irq functions in the Krait CPU EDAC driver. Export them so that the EDAC driver can be compiled as a module.
--- kernel/irq/manage.c | 2 ++ 1 file changed, 2 insertions(+)
kernel/irq/manage.c +2 -0
@@ -1705,6 +1705,7 @@ void free_percpu_irq(unsigned int irq, void __percpu *dev_id)kfree (__free_percpu_irq (irq, dev_id));chip_bus_sync_unlock (desc); } +EXPORT_SYMBOL_GPL (free_percpu_irq);/** * setup_percpu_irq - setup a per-cpu interrupt
@@ -1775,3 +1776,4 @@ int request_percpu_irq(unsigned int irq, irq_handler_t handler,return retval; } +EXPORT_SYMBOL_GPL (request_percpu_irq);
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
PATCH v6 2/5 ARM: Add Krait L2 register accessor functions
In reply to Stephen BoydKrait CPUs have a handful of L2 cache controller registers that live behind a cp15 based indirection register. First you program the indirection register (l2cpselr) to point the L2 'window' register (l2cpdr) at what you want to read/write. Then you read/write the 'window' register to do what you want. The l2cpselr register is not banked per-cpu so we must lock around accesses to it to prevent other CPUs from re-pointing l2cpdr underneath us.
--- arch/arm/common/Kconfig | 3 ++ arch/arm/common/Makefile | 1 + arch/arm/common/krait-l2-accessors.c | 58 +++++++++++++++++++++++++++++++ arch/arm/include/asm/krait-l2-accessors.h | 20 +++++++++++ 4 files changed, 82 insertions(+) create mode 100644 arch/arm/common/krait-l2-accessors.c create mode 100644 arch/arm/include/asm/krait-l2-accessors.h
arch/arm/common/Kconfig +3 -0
@@ -9,6 +9,9 @@ config DMABOUNCE bool select ZONE_DMA +config KRAIT_L2_ACCESSORS + bool + config SHARP_LOCOMO bool
arch/arm/common/Makefile +1 -0
@@ -7,6 +7,7 @@ obj-y += firmware.o obj-$(CONFIG_ICST) += icst.o obj-$(CONFIG_SA1111) += sa1111.o obj-$(CONFIG_DMABOUNCE) += dmabounce.o +obj-$(CONFIG_KRAIT_L2_ACCESSORS) += krait-l2-accessors.o obj-$(CONFIG_SHARP_LOCOMO) += locomo.o obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o obj-$(CONFIG_SHARP_SCOOP) += scoop.o
arch/arm/common/krait-l2-accessors.c new file +58 -0
58 lines not on this page · raw message
arch/arm/include/asm/krait-l2-accessors.h new file +20 -0
@@ -0,0 +1,20 @@ +/* +* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 and +* only version 2 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. +*/ + +#ifndef __ASMARM_KRAIT_L2_ACCESSORS_H +#define __ASMARM_KRAIT_L2_ACCESSORS_H + +extern void krait_set_l2_indirect_reg (u32 addr,u32 val); +extern u32 krait_get_l2_indirect_reg (u32 addr); + +#endif
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
Borislav Petkov
maintainerRe: [PATCH v6 2/5] ARM: Add Krait L2 register accessor functions
Quoted 55 lines · Stephen Boyd
Krait CPUs have a handful of L2 cache controller registers that live behind a cp15 based indirection register. First you program the indirection register (l2cpselr) to point the L2 'window' register (l2cpdr) at what you want to read/write. Then you read/write the 'window' register to do what you want. The l2cpselr register is not banked per-cpu so we must lock around accesses to it to prevent other CPUs from re-pointing l2cpdr underneath us.
Cc Mark Rutland <[email protected]>Cc Russell King <[email protected]>Cc Courtney Cavin <[email protected]>Signed-off-by Stephen Boyd <[email protected]>--- arch/arm/common/Kconfig | 3 ++ arch/arm/common/Makefile | 1 + arch/arm/common/krait-l2-accessors.c | 58 +++++++++++++++++++++++++++++++ arch/arm/include/asm/krait-l2-accessors.h | 20 +++++++++++ 4 files changed, 82 insertions(+) create mode 100644 arch/arm/common/krait-l2-accessors.c create mode 100644 arch/arm/include/asm/krait-l2-accessors.harch/arm/common/Kconfig +3
-0@@ -9,6 +9,9 @@ config DMABOUNCE bool select ZONE_DMA +config KRAIT_L2_ACCESSORS + bool + config SHARP_LOCOMO boolarch/arm/common/Makefile +1
-0@@ -7,6 +7,7 @@ obj-y += firmware.o obj-$(CONFIG_ICST) += icst.o obj-$(CONFIG_SA1111) += sa1111.o obj-$(CONFIG_DMABOUNCE) += dmabounce.o +obj-$(CONFIG_KRAIT_L2_ACCESSORS) += krait-l2-accessors.o obj-$(CONFIG_SHARP_LOCOMO) += locomo.o obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o obj-$(CONFIG_SHARP_SCOOP) += scoop.oarch/arm/common/krait-l2-accessors.c new file +1
-0@@ -0,0 +1,58 @@ +/*
arch/arm/common/krait-l2-accessors.c line 11
Quoted 10 lines
arch/arm/common/krait-l2-accessors.c new file +10
-0+* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 and +* only version 2 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.
Can we refer to COPYING here instead of adding that boilerplate to every file?
Quoted 54 lines
arch/arm/common/krait-l2-accessors.c new file +47
-0+*/ + +#include <linux/spinlock.h> +#include <linux/export.h> + +#include <asm/barrier.h> +#include <asm/krait-l2-accessors.h> + +static DEFINE_RAW_SPINLOCK (krait_l2_lock); + +void krait_set_l2_indirect_reg (u32 addr,u32 val) +{ +unsigned long flags; + +raw_spin_lock_irqsave (&krait_l2_lock, flags); +/* +* Select the L2 window by poking l2cpselr, then write to the window +* via l2cpdr. +*/ + asmvolatile ("mcr p15, 3, %0, c15, c0, 6 @ l2cpselr" : :"r" (addr)); +isb (); + asmvolatile ("mcr p15, 3, %0, c15, c0, 7 @ l2cpdr" : :"r" (val)); +isb (); + +raw_spin_unlock_irqrestore (&krait_l2_lock, flags); +} +EXPORT_SYMBOL (krait_set_l2_indirect_reg); + +u32 krait_get_l2_indirect_reg (u32 addr) +{ +u32 val; +unsigned long flags; + +raw_spin_lock_irqsave (&krait_l2_lock, flags); +/* +* Select the L2 window by poking l2cpselr, then read from the window +* via l2cpdr. +*/ + asmvolatile ("mcr p15, 3, %0, c15, c0, 6 @ l2cpselr" : :"r" (addr)); +isb (); + asmvolatile ("mrc p15, 3, %0, c15, c0, 7 @ l2cpdr" :"=r" (val)); + +raw_spin_unlock_irqrestore (&krait_l2_lock, flags); + +return val; +} +EXPORT_SYMBOL (krait_get_l2_indirect_reg);arch/arm/include/asm/krait-l2-accessors.h new file +1
-0@@ -0,0 +1,20 @@ +/*
arch/arm/include/asm/krait-l2-accessors.h line 11
Quoted 10 lines
arch/arm/include/asm/krait-l2-accessors.h new file +10
-0+* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 and +* only version 2 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.
Ditto.
Thanks.
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--Re: [PATCH v6 2/5] ARM: Add Krait L2 register accessor functions
Quoted 13 lines · Borislav Petkov
Quoted 12 lines · Stephen Boyd
arch/arm/common/krait-l2-accessors.c new file +6
-0@@ -0,0 +1,58 @@ +/* +* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 and +* only version 2 as published by the Free Software Foundation.
Quoted 8 lines
arch/arm/common/krait-l2-accessors.c line 11
Quoted 5 lines
arch/arm/common/krait-l2-accessors.c new file +5
-0+* +* 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. Can we refer to COPYING here instead of adding that boilerplate to every file?
No. This is the template I'm told to use.
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Borislav Petkov
maintainerRe: [PATCH v6 2/5] ARM: Add Krait L2 register accessor functions
Quoted 1 line · Stephen Boyd
No. This is the template I'm told to use.
By whom? And why?
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--Re: [PATCH v6 2/5] ARM: Add Krait L2 register accessor functions
Hi Borislav,
Quoted 4 lines · Borislav Petkov
Quoted 1 line · Stephen Boyd
No. This is the template I'm told to use.
By whom? And why?
As I understand it, the license authors. They find it important to maintain clarity even when files get copied into other projects.
http://www.gnu.org/licenses/gpl-howto.html
http://www.gnu.org/licenses/gpl-faq.html#NoticeInSourceFile
Regards,
Christopher
Signature · 3 lines
Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by the Linux Foundation.
Borislav Petkov
maintainerRe: [PATCH v6 2/5] ARM: Add Krait L2 register accessor functions
Quoted 6 lines · Christopher Covington
As I understand it, the license authors. They find it important to maintain clarity even when files get copied into other projects.
Right, so what is wrong with stating the same thing in two lines:
"Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
This file is licensed under GNU GPLv2. See COPYING for full license text."
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--Re: [PATCH v6 2/5] ARM: Add Krait L2 register accessor functions
Quoted 6 lines · On Tue, 8 Apr 2014 17:10:56 +0200 Borislav Petkov <[email protected]> wrote:
Quoted 5 lines · Christopher Covington
As I understand it, the license authors. They find it important to maintain clarity even when files get copied into other projects.
Quoted 7 lines
Right, so what is wrong with stating the same thing in two lines:
"Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
This file is licensed under GNU GPLv2. See COPYING for full license text.
The COPYING file may not be present. There may be cases where the absence of the warranty statement in the header is problematic etc etc.
Corporate legals have their own policies on this and there is no point fighting them because
- they are the ones qualified to make the decision
- the corporate legal angle is often "do this or don't release it"
- we have huge numbers of files using that same no warranty in every file, and major companies who specify it must be present in their code releases
Including the without warranty is standard practice at a lot of companies. It's not even wasting space - it'll compress beautifully as there are already lots of similar headers all over the tree.
Alan
Borislav Petkov
maintainerRe: [PATCH v6 2/5] ARM: Add Krait L2 register accessor functions
Quoted 3 lines · One Thousand Gnomes
Including the without warranty is standard practice at a lot of companies. It's not even wasting space - it'll compress beautifully as there are already lots of similar headers all over the tree.
Right, I was just trying to find out from Stephen/Christopher whether they're actually really required by legal to slap the boilerplate or they can get by with a smaller chunk. That's all.
But thanks for this Alan, I was hoping someone would school me on the legal practice wrt license boilerplates in the kernel, and there you are. :-)
Thanks.
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--PATCH v6 3/5 devicetree: bindings: Document Krait cache error interrupts
In reply to Stephen BoydThe Krait L1/L2 error reporting hardware is made up a per-CPU interrupt for the L1 cache and a SPI interrupt for the L2.
--- Documentation/devicetree/bindings/arm/cache.txt | 48 ++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/arm/cache.txt +47 -1
@@ -37,7 +37,9 @@ This document provides the device tree bindings for ARM architected caches. - compatible Usage: Required Value type: <string> - Definition: value shall be "arm,arch-cache". + Definition: shall be one of: + "arm,arch-cache" + "qcom,arch-cache" - power-domain Usage: Optional
@@ -45,6 +47,12 @@ This document provides the device tree bindings for ARM architected caches. Definition: A phandle and power domain specifier as defined by bindings of power domain specified by [3]. + - interrupts + Usage: Optional for caches with compatible of "qcom,arch-cache" + Value type: <prop-encoded-array> + Definition: Error interrupt associated with this cache. + + Example(dual-cluster big.LITTLE system 32-bit) cpus {
@@ -156,6 +164,44 @@ Example(dual-cluster big.LITTLE system 32-bit) }; }; +Example (Krait 32-bit system): + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu at 0 { + compatible = "qcom,krait"; + device_type = "cpu"; + reg = <0>; + next-level-cache = <&L1_0>; + + L1_0: l1-cache { + compatible = "qcom,arch-cache"; + interrupts = <1 14 0x104>; + next-level-cache = <&L2>; + }; + + L2: l2-cache { + compatible = "qcom,arch-cache"; + interrupts = <0 2 0x4>; + }; + }; + + cpu at 1 { + compatible = "qcom,krait"; + device_type = "cpu"; + reg = <1>; + next-level-cache = <&L1_1>; + + L1_1: l1-cache { + compatible = "qcom,arch-cache"; + interrupts = <1 14 0x204>; + next-level-cache = <&L2>; + }; + }; + }; + [1] ARM Architecture Reference Manuals http://infocenter.arm.com/help/index.jsp
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
Borislav Petkov
maintainerRe: [PATCH v6 3/5] devicetree: bindings: Document Krait cache error interrupts
Documentation/devicetree/bindings/arm/cache.txt
Quoted 16 lines · Stephen Boyd
The Krait L1/L2 error reporting hardware is made up a per-CPU interrupt for the L1 cache and a SPI interrupt for the L2.
Cc Lorenzo Pieralisi <[email protected]>Cc Mark Rutland <[email protected]>Cc Kumar Gala <[email protected]>Cc <[email protected]>Signed-off-by Stephen Boyd <[email protected]>--- Documentation/devicetree/bindings/arm/cache.txt | 48 ++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-)Documentation/devicetree/bindings/arm/cache.txt +0
-0
Right, that's http://www.spinics.net/lists/arm-kernel/msg308540.html
So whoever picks those patches up, Lorenzo's doc needs to be in his tree first too.
How about I review the EDAC part and an arm maintainer picks the whole series up? Would that be easier, logistically?
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--Re: [PATCH v6 3/5] devicetree: bindings: Document Krait cache error interrupts
Quoted 19 lines · Borislav Petkov
Documentation/devicetree/bindings/arm/cache.txt
Quoted 16 lines · Stephen Boyd
The Krait L1/L2 error reporting hardware is made up a per-CPU interrupt for the L1 cache and a SPI interrupt for the L2.
Cc Lorenzo Pieralisi <[email protected]>Cc Mark Rutland <[email protected]>Cc Kumar Gala <[email protected]>Cc <[email protected]>Signed-off-by Stephen Boyd <[email protected]>--- Documentation/devicetree/bindings/arm/cache.txt | 48 ++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-)Documentation/devicetree/bindings/arm/cache.txt +0
-0Right, that's http://www.spinics.net/lists/arm-kernel/msg308540.html
Quoted 6 lines
So whoever picks those patches up, Lorenzo's doc needs to be in his tree first too.
How about I review the EDAC part and an arm maintainer picks the whole series up? Would that be easier, logistically?
That sounds fine if you want to give an ack on the edac changes. I can route it through arm-soc.
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Re: [PATCH v6 3/5] devicetree: bindings: Document Krait cache error interrupts
In reply to Borislav PetkovQuoted 20 lines · Borislav Petkov
Documentation/devicetree/bindings/arm/cache.txt
Quoted 16 lines · Stephen Boyd
The Krait L1/L2 error reporting hardware is made up a per-CPU interrupt for the L1 cache and a SPI interrupt for the L2.
Cc Lorenzo Pieralisi <[email protected]>Cc Mark Rutland <[email protected]>Cc Kumar Gala <[email protected]>Cc <[email protected]>Signed-off-by Stephen Boyd <[email protected]>--- Documentation/devicetree/bindings/arm/cache.txt | 48 ++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-)Documentation/devicetree/bindings/arm/cache.txt +0
-0Right, that's http://www.spinics.net/lists/arm-kernel/msg308540.html
Quoted 2 lines
So whoever picks those patches up, Lorenzo's doc needs to be in his tree first too.
Sorry for the delay in replying. Those cache bindings need an ACK to get merged, and were introduced so that idle states can retrieve power domain information for caches. I am going to revive the idle bindings thread to see what we can/should merge of these bindings as things stand, I really hope this won't block the series any further, otherwise we can rework the patches so that this series can get in first, or simplify my series to allow both to get merged as soon as possible without compromising future requirements.
Thanks,
Lorenzo
Borislav Petkov
maintainerRe: [PATCH v6 3/5] devicetree: bindings: Document Krait cache error interrupts
Quoted 8 lines · Lorenzo Pieralisi
Sorry for the delay in replying. Those cache bindings need an ACK to get merged, and were introduced so that idle states can retrieve power domain information for caches. I am going to revive the idle bindings thread to see what we can/should merge of these bindings as things stand, I really hope this won't block the series any further, otherwise we can rework the patches so that this series can get in first, or simplify my series to allow both to get merged as soon as possible without compromising future requirements.
Right, I think this is Stephen's call. AFAIR, the current state of affairs is for a followup patchset to come up which I can ack for the EDAC bits and then another maintainer picks the whole thing up.
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--PATCH v6 4/5 edac: Add support for Krait CPU cache error detection
In reply to Stephen BoydAdd support for the Krait CPU cache error detection. This is a simplified version of the code originally written by Stepan Moskovchenko[1] ported to the EDAC device framework.
[1] https://www.codeaurora.org/cgit/quic/la/kernel/msm/tree/arch/arm/mach-msm/cache_erp.c?h=msm-3.4
--- drivers/edac/Kconfig | 8 + drivers/edac/Makefile | 2 + drivers/edac/krait_edac.c | 370 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 380 insertions(+) create mode 100644 drivers/edac/krait_edac.c
drivers/edac/Kconfig +8 -0
@@ -368,4 +368,12 @@ config EDAC_OCTEON_PCI Support for error detection and correction on the Cavium Octeon family of SOCs. +config EDAC_KRAIT_CACHE + tristate "Krait L1/L2 Cache" + depends on EDAC_MM_EDAC && ARM && OF + select KRAIT_L2_ACCESSORS + help + Support for error detection and correction on the + Krait L1/L2 cache controller. + endif # EDAC
drivers/edac/Makefile +2 -0
@@ -64,3 +64,5 @@ obj-$(CONFIG_EDAC_OCTEON_PC) += octeon_edac-pc.o obj-$(CONFIG_EDAC_OCTEON_L2C) += octeon_edac-l2c.o obj-$(CONFIG_EDAC_OCTEON_LMC) += octeon_edac-lmc.o obj-$(CONFIG_EDAC_OCTEON_PCI) += octeon_edac-pci.o + +obj-$(CONFIG_EDAC_KRAIT_CACHE) += krait_edac.o
drivers/edac/krait_edac.c new file +370 -0
370 lines not on this page · raw message
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
Borislav Petkov
maintainerRe: [PATCH v6 4/5] edac: Add support for Krait CPU cache error detection
Quoted 104 lines · Stephen Boyd
Add support for the Krait CPU cache error detection. This is a simplified version of the code originally written by Stepan Moskovchenko[1] ported to the EDAC device framework.
[1] https://www.codeaurora.org/cgit/quic/la/kernel/msm/tree/arch/arm/mach-msm/cache_erp.c?h=msm-3.4
Cc Stepan Moskovchenko <[email protected]>Signed-off-by Stephen Boyd <[email protected]>--- drivers/edac/Kconfig | 8 + drivers/edac/Makefile | 2 + drivers/edac/krait_edac.c | 370 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 380 insertions(+) create mode 100644 drivers/edac/krait_edac.cdrivers/edac/Kconfig +8
-0@@ -368,4 +368,12 @@ config EDAC_OCTEON_PCI Support for error detection and correction on the Cavium Octeon family of SOCs. +config EDAC_KRAIT_CACHE + tristate "Krait L1/L2 Cache" + depends on EDAC_MM_EDAC && ARM && OF + select KRAIT_L2_ACCESSORS + help + Support for error detection and correction on the + Krait L1/L2 cache controller. + endif # EDACdrivers/edac/Makefile +2
-0@@ -64,3 +64,5 @@ obj-$(CONFIG_EDAC_OCTEON_PC) += octeon_edac-pc.o obj-$(CONFIG_EDAC_OCTEON_L2C) += octeon_edac-l2c.o obj-$(CONFIG_EDAC_OCTEON_LMC) += octeon_edac-lmc.o obj-$(CONFIG_EDAC_OCTEON_PCI) += octeon_edac-pci.o + +obj-$(CONFIG_EDAC_KRAIT_CACHE) += krait_edac.odrivers/edac/krait_edac.c new file +56
-0@@ -0,0 +1,370 @@ +/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 and +* only version 2 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. +*/ + +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/platform_device.h> +#include <linux/module.h> +#include <linux/err.h> +#include <linux/cpu.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> + +#include <asm/krait-l2-accessors.h> + +#include "edac_core.h" + +#define CESR_DCTPE BIT(0) +#define CESR_DCDPE BIT(1) +#define CESR_ICTPE BIT(2) +#define CESR_ICDPE BIT(3) +#define CESR_DCTE (BIT(4) | BIT(5)) +#define CESR_ICTE (BIT(6) | BIT(7)) +#define CESR_TLBMH BIT(16) +#define CESR_I_MASK 0x000000cc +/* Print a message for everything but TLB MH events */ +#define CESR_PRINT_MASK 0x000000ff + +#define L2ESR 0x204 +#define L2ESR_MPDCD BIT(0) +#define L2ESR_MPSLV BIT(1) +#define L2ESR_TSESB BIT(2) +#define L2ESR_TSEDB BIT(3) +#define L2ESR_DSESB BIT(4) +#define L2ESR_DSEDB BIT(5) +#define L2ESR_MSE BIT(6) +#define L2ESR_MPLDREXNOK BIT(8) +#define L2ESR_CPU_MASK 0xf +#define L2ESR_CPU_SHIFT 16 +#define L2ESR_SP BIT(20) + +#define L2ESYNR0 0x208 +#define L2ESYNR1 0x209 +#define L2EAR0 0x20c +#define L2EAR1 0x20d +
drivers/edac/krait_edac.c line 66
Quoted 10 lines
drivers/edac/krait_edac.c new file +10
-0+struct krait_edac { +int l1_irq; +struct edac_device_ctl_info *__percpu *edev; +struct notifier_block notifier; +}; + +struct krait_edac_error { +const char *const msg; +void (*func)(struct edac_device_ctl_info *edac_dev, +int inst_nr,int block_nr,const char *msg);
arg alignment (please start new line at the opening brace).
Quoted 34 lines
drivers/edac/krait_edac.c new file +34
-0+}; + +static unsigned int read_cesr (void ) +{ +unsigned int cesr; + + asmvolatile ("mrc p15, 7, %0, c15, c0, 1 @ cesr" :"=r" (cesr)); +return cesr; +} + +static void write_cesr (unsigned int cesr) +{ + asmvolatile ("mcr p15, 7, %0, c15, c0, 1 @ cesr" : :"r" (cesr)); +} + +static unsigned int read_cesynr (void ) +{ +unsigned int cesynr; + + asmvolatile ("mrc p15, 7, %0, c15, c0, 3 @ cesynr" :"=r" (cesynr)); +return cesynr; +} + +static irqreturn_t krait_l1_irq (int irq,void *dev_id) +{ +struct edac_device_ctl_info **edac_p = dev_id; +struct edac_device_ctl_info *edac = *edac_p; +unsigned int cesr =read_cesr (); +unsigned int i_cesynr, d_cesynr; +unsigned int cpu =smp_processor_id (); +int print_regs = cesr &CESR_PRINT_MASK ; +int i; +static const struct krait_edac_error errors[] = { + {"D-cache tag parity error" , edac_device_handle_ue },
drivers/edac/krait_edac.c line 110
Quoted 10 lines
drivers/edac/krait_edac.c new file +10
-0+ { "D-cache data parity error", edac_device_handle_ue }, + { "I-cache tag parity error", edac_device_handle_ce }, + { "I-cache data parity error", edac_device_handle_ce }, + { "D-cache tag timing error", edac_device_handle_ue }, + { "D-cache data timing error", edac_device_handle_ue }, + { "I-cache tag timing error", edac_device_handle_ce }, + { "I-cache data timing error", edac_device_handle_ce } + }; + +if (print_regs) {
This variable is used only once here, you can simply do the binary and test then and drop it:
if (cesr & CESR_PRINT_MASK)
drivers/edac/krait_edac.c line 112
Quoted 2 lines
drivers/edac/krait_edac.c new file +2
-0+pr_alert ("L1 / TLB Error detected on CPU %d!\n" , cpu); +pr_alert ("CESR = 0x%08x\n" , cesr);
You can use the edac_*_printk with KERN_ALERT as level which adds proper prefixes.
drivers/edac/krait_edac.c line 117
Quoted 5 lines
drivers/edac/krait_edac.c new file +5
-0+ } + +for (i =0 ; i <ARRAY_SIZE (errors); i++) +if (BIT (i) & cesr) + errors[i].func (edac, cpu,0 , errors[i].msg);
Nice! Func ptr per error type :)
drivers/edac/krait_edac.c line 126
Quoted 9 lines
drivers/edac/krait_edac.c new file +9
-0+ +if (cesr &CESR_TLBMH ) { + asm ("mcr p15, 0, r0, c8, c7, 0" ); +edac_device_handle_ce (edac, cpu,0 ,"TLB Multi-Hit error" ); + } + +if (cesr & (CESR_ICTPE |CESR_ICDPE |CESR_ICTE )) { + i_cesynr =read_cesynr (); +pr_alert ("I-side CESYNR = 0x%08x\n" , i_cesynr);
edac_printk
and also, this message looks a bit cryptic for issuing it at ALERT level. I'm ssuming people won't come to you and ask you what it means...? :)
drivers/edac/krait_edac.c line 139
Quoted 13 lines
drivers/edac/krait_edac.c new file +13
-0+write_cesr (CESR_I_MASK ); + +/* +* Clear the I-side bits from the captured CESR value so that we +* don't accidentally clear any new I-side errors when we do +* the CESR write-clear operation. +*/ + cesr &= ~CESR_I_MASK ; + } + +if (cesr & (CESR_DCTPE |CESR_DCDPE |CESR_DCTE )) { + d_cesynr =read_cesynr (); +pr_alert ("D-side CESYNR = 0x%08x\n" , d_cesynr);
Ditto.
Quoted 24 lines
drivers/edac/krait_edac.c new file +24
-0+ } + +/* Clear the interrupt bits we processed */ +write_cesr (cesr); + +return IRQ_HANDLED ; +} + +static irqreturn_t krait_l2_irq (int irq,void *dev_id) +{ +struct edac_device_ctl_info *edac = dev_id; +unsigned int l2esr; +unsigned int l2esynr0; +unsigned int l2esynr1; +unsigned int l2ear0; +unsigned int l2ear1; +unsigned long cpu; +int i; +static const struct krait_edac_error errors[] = { + {"master port decode error" , edac_device_handle_ce }, + {"master port slave error" , edac_device_handle_ce }, + {"tag soft error, single-bit" , edac_device_handle_ce }, + {"tag soft error, double-bit" , edac_device_handle_ue }, + {"data soft error, single-bit" , edac_device_handle_ce },
drivers/edac/krait_edac.c line 173
Quoted 10 lines
drivers/edac/krait_edac.c new file +10
-0+ { "data soft error, double-bit", edac_device_handle_ue }, + { "modified soft error", edac_device_handle_ce }, + { "slave port exclusive monitor not available", + edac_device_handle_ue}, + { "master port LDREX received Normal OK response", + edac_device_handle_ce }, + }; + + l2esr =krait_get_l2_indirect_reg (L2ESR ); +pr_alert ("Error detected!\n" );
Why print this not very telling message here if errors[i].func() will get the proper .msg later?
drivers/edac/krait_edac.c line 185
Quoted 12 lines
drivers/edac/krait_edac.c new file +12
-0+pr_alert ("L2ESR = 0x%08x\n" , l2esr); + +if (l2esr & (L2ESR_TSESB |L2ESR_TSEDB |L2ESR_MSE |L2ESR_SP )) { + l2esynr0 =krait_get_l2_indirect_reg (L2ESYNR0 ); + l2esynr1 =krait_get_l2_indirect_reg (L2ESYNR1 ); + l2ear0 =krait_get_l2_indirect_reg (L2EAR0 ); + l2ear1 =krait_get_l2_indirect_reg (L2EAR1 ); + +pr_alert ("L2ESYNR0 = 0x%08x\n" , l2esynr0); +pr_alert ("L2ESYNR1 = 0x%08x\n" , l2esynr1); +pr_alert ("L2EAR0 = 0x%08x\n" , l2ear0); +pr_alert ("L2EAR1 = 0x%08x\n" , l2ear1);
Also, please use edac_printk and consider making those messages human-readable, otherwise it only confuses users.
Quoted 6 lines
drivers/edac/krait_edac.c new file +6
-0+ } + + cpu = (l2esr >>L2ESR_CPU_SHIFT ) &L2ESR_CPU_MASK ; + cpu =__ffs (cpu); +if (cpu) + cpu--;
...
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--Re: [PATCH v6 4/5] edac: Add support for Krait CPU cache error detection
Quoted 7 lines · Borislav Petkov
drivers/edac/krait_edac.c line 66
Quoted 5 lines · Stephen Boyd
drivers/edac/krait_edac.c new file +5
-0+ +struct krait_edac_error { +const char *const msg; +void (*func)(struct edac_device_ctl_info *edac_dev, +int inst_nr,int block_nr,const char *msg);arg alignment (please start new line at the opening brace).
Done.
Quoted 17 lines
Quoted 4 lines
drivers/edac/krait_edac.c new file +4
-0+int print_regs = cesr &CESR_PRINT_MASK ; +int i; +static const struct krait_edac_error errors[] = { + {"D-cache tag parity error" , edac_device_handle_ue },drivers/edac/krait_edac.c line 110
Quoted 10 lines
drivers/edac/krait_edac.c new file +10
-0+ { "D-cache data parity error", edac_device_handle_ue }, + { "I-cache tag parity error", edac_device_handle_ce }, + { "I-cache data parity error", edac_device_handle_ce }, + { "D-cache tag timing error", edac_device_handle_ue }, + { "D-cache data timing error", edac_device_handle_ue }, + { "I-cache tag timing error", edac_device_handle_ce }, + { "I-cache data timing error", edac_device_handle_ce } + }; + +if (print_regs) {This variable is used only once here, you can simply do the binary and test then and drop it:
Quoted 1 line
if (cesr &
CESR_PRINT_MASK)
Done.
Quoted 5 lines
drivers/edac/krait_edac.c line 112
Quoted 3 lines
drivers/edac/krait_edac.c new file +2
-0+pr_alert ("L1 / TLB Error detected on CPU %d!\n" , cpu); +pr_alert ("CESR = 0x%08x\n" , cesr);You can use the edac_*_printk with
KERN_ALERTas level which adds proper prefixes.
Done.
Quoted 13 lines
drivers/edac/krait_edac.c line 126
Quoted 11 lines
drivers/edac/krait_edac.c new file +9
-0+ +if (cesr &CESR_TLBMH ) { + asm ("mcr p15, 0, r0, c8, c7, 0" ); +edac_device_handle_ce (edac, cpu,0 ,"TLB Multi-Hit error" ); + } + +if (cesr & (CESR_ICTPE |CESR_ICDPE |CESR_ICTE )) { + i_cesynr =read_cesynr (); +pr_alert ("I-side CESYNR = 0x%08x\n" , i_cesynr);
edac_printk
Quoted 3 lines
and also, this message looks a bit cryptic for issuing it at ALERT level. I'm ssuming people won't come to you and ask you what it means...? :)
Ok. I can lower it to error level?
Quoted 44 lines
Quoted 4 lines
drivers/edac/krait_edac.c new file +3
-0+write_cesr (CESR_I_MASK ); + +/* drivers/edac/krait_edac.c line 139
Quoted 10 lines
drivers/edac/krait_edac.c new file +10
-0+* Clear the I-side bits from the captured CESR value so that we +* don't accidentally clear any new I-side errors when we do +* the CESR write-clear operation. +*/ + cesr &= ~CESR_I_MASK ; + } + +if (cesr & (CESR_DCTPE |CESR_DCDPE |CESR_DCTE )) { + d_cesynr =read_cesynr (); +pr_alert ("D-side CESYNR = 0x%08x\n" , d_cesynr);Ditto.
Quoted 28 lines
drivers/edac/krait_edac.c new file +28
-0+ } + +/* Clear the interrupt bits we processed */ +write_cesr (cesr); + +return IRQ_HANDLED ; +} + +static irqreturn_t krait_l2_irq (int irq,void *dev_id) +{ +struct edac_device_ctl_info *edac = dev_id; +unsigned int l2esr; +unsigned int l2esynr0; +unsigned int l2esynr1; +unsigned int l2ear0; +unsigned int l2ear1; +unsigned long cpu; +int i; +static const struct krait_edac_error errors[] = { + {"master port decode error" , edac_device_handle_ce }, + {"master port slave error" , edac_device_handle_ce }, + {"tag soft error, single-bit" , edac_device_handle_ce }, + {"tag soft error, double-bit" , edac_device_handle_ue }, + {"data soft error, single-bit" , edac_device_handle_ce }, + {"data soft error, double-bit" , edac_device_handle_ue }, + {"modified soft error" , edac_device_handle_ce }, + {"slave port exclusive monitor not available" , + edac_device_handle_ue},
Quoted 8 lines
drivers/edac/krait_edac.c line 173
Quoted 6 lines
drivers/edac/krait_edac.c new file +6
-0+ {"master port LDREX received Normal OK response" , + edac_device_handle_ce }, + }; + + l2esr =krait_get_l2_indirect_reg (L2ESR ); +pr_alert ("Error detected!\n" );Why print this not very telling message here if errors[i].func() will get the proper .msg later?
Sure I can drop it.
Quoted 15 lines
drivers/edac/krait_edac.c line 185
Quoted 13 lines
drivers/edac/krait_edac.c new file +12
-0+pr_alert ("L2ESR = 0x%08x\n" , l2esr); + +if (l2esr & (L2ESR_TSESB |L2ESR_TSEDB |L2ESR_MSE |L2ESR_SP )) { + l2esynr0 =krait_get_l2_indirect_reg (L2ESYNR0 ); + l2esynr1 =krait_get_l2_indirect_reg (L2ESYNR1 ); + l2ear0 =krait_get_l2_indirect_reg (L2EAR0 ); + l2ear1 =krait_get_l2_indirect_reg (L2EAR1 ); + +pr_alert ("L2ESYNR0 = 0x%08x\n" , l2esynr0); +pr_alert ("L2ESYNR1 = 0x%08x\n" , l2esynr1); +pr_alert ("L2EAR0 = 0x%08x\n" , l2ear0); +pr_alert ("L2EAR1 = 0x%08x\n" , l2ear1);Also, please use
edac_printkand consider making those messages human-readable, otherwise it only confuses users.
Ok.
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Borislav Petkov
maintainerRe: [PATCH v6 4/5] edac: Add support for Krait CPU cache error detection
Quoted 5 lines · Stephen Boyd
Quoted 3 lines
and also, this message looks a bit cryptic for issuing it at ALERT level. I'm ssuming people won't come to you and ask you what it means...? :)
Ok. I can lower it to error level?
I'm just trying to put you in the user's shoes and make you take a critical look at your error messages and ask yourself whether people seeing this would know what's going on or not?
We've had the experience on x86 where people would have the *whole* error message which would say, "error corrected, bla" and they still would come and ask whether their hw is b0rked. We had to add stuff like:
"Corrected error, no action required."
to let them know there was no affect on execution. And they'd still come and ask. Even other kernel people! :-)
So please make sure your error messages are as understandable as possible.
:-)
Thanks.
Signature · 5 lines
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--PATCH v6 5/5 ARM: dts: msm: Fix Krait CPU/L2 nodes
In reply to Stephen BoydThe error interrupt binding wasn't properly accepted when this was originally written. Fix the dts to match the binding.
--- arch/arm/boot/dts/qcom-msm8960.dtsi | 29 +++++++++++++++------- arch/arm/boot/dts/qcom-msm8974.dtsi | 49 ++++++++++++++++++++++++++++--------- 2 files changed, 57 insertions(+), 21 deletions(-)
arch/arm/boot/dts/qcom-msm8960.dtsi +20 -9
@@ -12,30 +12,41 @@ cpus { #address-cells = <1>; #size-cells = <0>; - interrupts = <1 14 0x304>; - compatible = "qcom,krait"; enable-method = "qcom,kpss-acc-v1"; cpu at 0 { + compatible = "qcom,krait"; device_type = "cpu"; reg = <0>; - next-level-cache = <&L2>; + next-level-cache = <&L1_0>; qcom,acc = <&acc0>; qcom,saw = <&saw0>; + + L1_0: l1-cache { + compatible = "qcom,arch-cache"; + interrupts = <1 14 0x104>; + next-level-cache = <&L2>; + }; + + L2: l2-cache { + compatible = "qcom,arch-cache"; + interrupts = <0 2 0x4>; + }; }; cpu at 1 { + compatible = "qcom,krait"; device_type = "cpu"; reg = <1>; - next-level-cache = <&L2>; + next-level-cache = <&L1_1>; qcom,acc = <&acc1>; qcom,saw = <&saw1>; - }; - L2: l2-cache { - compatible = "cache"; - cache-level = <2>; - interrupts = <0 2 0x4>; + L1_1: l1-cache { + compatible = "qcom,arch-cache"; + interrupts = <1 14 0x104>; + next-level-cache = <&L2>; + }; }; };
arch/arm/boot/dts/qcom-msm8974.dtsi +37 -12
80 lines not on this page · raw message
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation