From: Marek Majtyka <marekx.majt...@intel.com> Added cache L1/L2/L3, SMEM and CMEM drivers. Added linux style debug CMEM option. Changes: - added dtsi/dts definition for XLF board - separated configuration between X9 and XLF - fix issue with nca ring access - added tracepoints for L3 cache - other small code adjustments. - changed from CMEM debug local define to Kconfig parameter
Signed-off-by: Marek Majtyka <marekx.majt...@intel.com> --- .../devicetree/bindings/arm/axxia/edac_l1.txt | 15 +++ .../devicetree/bindings/arm/axxia/edac_l2.txt | 5 +- .../devicetree/bindings/arm/axxia/edac_l3.txt | 11 +- arch/arm64/boot/dts/intel/axc6732-waco.dts | 32 +++++ arch/arm64/boot/dts/intel/axc67xx.dtsi | 68 +++++++++++ drivers/edac/Kconfig | 45 ++++++- drivers/edac/Makefile | 4 + drivers/edac/axxia_edac-cmc_56xx.c | 135 +++++++++++++++++---- drivers/edac/axxia_edac-l2_cpu_56xx.c | 98 ++++++++++----- drivers/edac/axxia_edac-l3_56xx.c | 94 ++++++++++---- drivers/edac/axxia_edac-mc_56xx.c | 35 +++--- drivers/edac/edac_core.h | 7 ++ drivers/edac/edac_device.c | 97 ++++++++++++++- drivers/misc/lsi-ncr.c | 4 +- include/trace/events/edac.h | 77 ++++++++++++ include/trace/events/edacl3.h | 109 +++++++++++++++++ 16 files changed, 740 insertions(+), 96 deletions(-) create mode 100644 Documentation/devicetree/bindings/arm/axxia/edac_l1.txt create mode 100644 include/trace/events/edac.h create mode 100644 include/trace/events/edacl3.h diff --git a/Documentation/devicetree/bindings/arm/axxia/edac_l1.txt b/Documentation/devicetree/bindings/arm/axxia/edac_l1.txt new file mode 100644 index 0000000..5e0a8dc --- /dev/null +++ b/Documentation/devicetree/bindings/arm/axxia/edac_l1.txt @@ -0,0 +1,15 @@ +Axxia Error Detection & Correction [EDAC] +The EDAC accesses ARM v7/v8 L2MERRSR_EL1 register data. + +Required properties: +- compatible : should contain "intel,cortex-a53-cpu" for AXM67xx + : should contain "intel,cortex-a57-cpu" for AXM56xx + : should contain "lsi,cortex-a15-cpu" for AXM55xx +- syscon : should referernce syscon node for both 55xx/56xx/67xx + +Example: + edac_l2: edac_l2 { + compatible = "intel,cortex-a57-cpu"; + syscon = <&syscon>; + status = "disabled"; + }; diff --git a/Documentation/devicetree/bindings/arm/axxia/edac_l2.txt b/Documentation/devicetree/bindings/arm/axxia/edac_l2.txt index d90629c..b99e77a 100644 --- a/Documentation/devicetree/bindings/arm/axxia/edac_l2.txt +++ b/Documentation/devicetree/bindings/arm/axxia/edac_l2.txt @@ -2,9 +2,10 @@ Axxia Error Detection & Correction [EDAC] The EDAC accesses ARM v7/v8 L2MERRSR_EL1 register data. Required properties: -- compatible : should contain "intel,cortex-a57-l2-cache" for AXM56xx +- compatible : should contain "intel,cortex-a53-l2-cache" for AXM67xx + : should contain "intel,cortex-a57-l2-cache" for AXM56xx : should contain "lsi,cortex-a15-l2-cache" for AXM55xx -- syscon : should referernce syscon node for both 55xx/56xx +- syscon : should referernce syscon node for both 55xx/56xx/67xx Example: edac_l2: edac_l2 { diff --git a/Documentation/devicetree/bindings/arm/axxia/edac_l3.txt b/Documentation/devicetree/bindings/arm/axxia/edac_l3.txt index e37b5b8..5b80f21 100644 --- a/Documentation/devicetree/bindings/arm/axxia/edac_l3.txt +++ b/Documentation/devicetree/bindings/arm/axxia/edac_l3.txt @@ -2,7 +2,8 @@ Axxia Error Detection & Correction [EDAC] The EDAC accesses a range of registers in the dickens l3 controller Required properties: -- compatible : should contain "intel,ccn504-l3-cache" +- compatible : should contain "intel,ccn504-l3-cache" + : should contain "intel,ccn512-l3-cache" - reg : should contain address of ccn first node; its range shall contain all ccn nodes registers ( 0x1000000 ). - interrupts : if given driver uses interrupts, if not poll mechanism applies @@ -15,3 +16,11 @@ Example: syscon = <&syscon>; status = "disabled"; }; + + edac_l3: edac_l3 { + compatible = "intel,ccn512-l3-cache"; + reg = <0x40 0x00000000 0 0x1000000>; + interrupts = <0 432 4>; + syscon = <&syscon>; + status = "disabled"; + }; diff --git a/arch/arm64/boot/dts/intel/axc6732-waco.dts b/arch/arm64/boot/dts/intel/axc6732-waco.dts index 9208bab..93ef965 100644 --- a/arch/arm64/boot/dts/intel/axc6732-waco.dts +++ b/arch/arm64/boot/dts/intel/axc6732-waco.dts @@ -251,6 +251,18 @@ status = "okay"; }; +&edac_cpu { + status = "okay"; +}; + +&edac_l2 { + status = "okay"; +}; + +&edac_l3 { + status = "okay"; +}; + &mtc { status = "okay"; }; @@ -258,3 +270,23 @@ &trng { status = "okay"; }; + +&sm0 { + status = "okay"; +}; + +&sm1 { + status = "okay"; +}; + +&sm2 { + status = "okay"; +}; + +&sm3 { + status = "okay"; +}; + +&cm0 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/intel/axc67xx.dtsi b/arch/arm64/boot/dts/intel/axc67xx.dtsi index 8370a1c..d4d3171 100644 --- a/arch/arm64/boot/dts/intel/axc67xx.dtsi +++ b/arch/arm64/boot/dts/intel/axc67xx.dtsi @@ -49,6 +49,14 @@ spi2 = &spi2; gpdma0 = &gpdma0; gpdma1 = &gpdma1; + edac_cpu = &edac_cpu; + edac_l2 = &edac_l2; + edac_l3 = &edac_l3; + sm0 = &sm0; + sm1 = &sm1; + sm2 = &sm2; + sm3 = &sm3; + cm0 = &cm0; }; clocks { @@ -104,6 +112,26 @@ reg = <0x80 0x02c00000 0 0x40000>; }; + edac_cpu: edac_cpu { + compatible = "intel,cortex-a53-cpu"; + syscon = <&syscon>; + status = "disabled"; + }; + + edac_l2: edac_l2 { + compatible = "intel,cortex-a53-l2-cache"; + syscon = <&syscon>; + status = "disabled"; + }; + + edac_l3: edac_l3 { + compatible = "intel,ccn512-l3-cache"; + reg = <0x40 0x00000000 0 0x1000000>; + interrupts = <0 432 4>; + syscon = <&syscon>; + status = "disabled"; + }; + reset: reset@2010031000 { compatible = "intel,axm56xx-reset"; syscon = <&syscon>; @@ -135,6 +163,46 @@ status = "disabled"; }; + sm0: sm0@00220000 { + compatible = "intel,smmon"; + reg = <0 0x00220000 0 0x1000>; + syscon = <&syscon>; + interrupts = <0 451 4>; + status = "disabled"; + }; + + sm1: sm1@000f0000 { + compatible = "intel,smmon"; + reg = <0 0x000f0000 0 0x1000>; + syscon = <&syscon>; + interrupts = <0 452 4>; + status = "disabled"; + }; + + sm2: sm2@00230000 { + compatible = "intel,smmon"; + reg = <0 0x00230000 0 0x1000>; + syscon = <&syscon>; + interrupts = <0 453 4>; + status = "disabled"; + }; + + sm3: sm3@00240000 { + compatible = "intel,smmon"; + reg = <0 0x00240000 0 0x1000>; + syscon = <&syscon>; + interrupts = <0 454 4>; + status = "disabled"; + }; + + cm0: cm0@00080009 { + compatible = "intel,cmmon"; + reg = <0 0x00080009 0 0x1000>; + syscon = <&syscon>; + interrupts = <0 386 4>; + status = "disabled"; + }; + usb0: usb@9000000000 { compatible = "intel,axxia-dwc3"; dma-coherent; diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index fb10774..aa91dda 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -400,6 +400,15 @@ config EDAC_AXXIA_SYSMEM_5500 the System Memory error detection. System Memory error detection is interrupt driven. +config EDAC_AXXIA_SYSMEM_6700 + depends on ARCH_AXXIA + bool "AXXIA EDAC SysMem Controller for 6700" + help + Support for System Memory Denali controller error + detection on the AXXIA AXM67xx devices. This enables + the System Memory error detection. System Memory error + detection is interrupt driven. + config EDAC_AXXIA_CMEM_5600 depends on ARCH_AXXIA bool "AXXIA EDAC CMem Controller for 5600" @@ -409,6 +418,24 @@ config EDAC_AXXIA_CMEM_5600 the Configuration Memory error detection. Configuration Memory error detection is interrupt driven. +config EDAC_AXXIA_CMEM_6700 + depends on ARCH_AXXIA + bool "AXXIA EDAC CMem Controller for 6700" + help + Support for Configuration Memory Denali controller error + detection on the AXXIA AXM67xx devices. This enables + the Configuration Memory error detection. Configuration Memory error + detection is interrupt driven. + +config DEBUG_EDAC_AXXIA_CMEM + depends on ARCH_AXXIA + bool "AXXIA EDAC CMEM error injection interface." + help + Support for configuration of CMEM edac error injection functionality. + It works for both 5600 and 6700 board families. + Enables error injection functionality for CMEM over procfs + interface (/proc/driver/). + config EDAC_AXXIA_L3_5500 tristate "AXXIA EDAC L3 Controller for 5500" help @@ -421,10 +448,18 @@ config EDAC_AXXIA_L3_5600 tristate "AXXIA EDAC L3 Controller for 5600" help Support for the eight L3 caches error detection - on the AXXIA AXM55xx devices. This enables the + on the AXXIA AXM56xx devices. This enables the L3 cache error detection. L3 cache error detection uses polling mechanism. +config EDAC_AXXIA_L3_6700 + tristate "AXXIA EDAC L3 Controller for 6700" + help + Support for the eight L3 caches error detection + on the AXXIA AXM67xx devices. This enables the + L3 cache error detection. L3 cache error detection + can use polling mechanism or be interrupt driven. + config EDAC_AXXIA_L2_CPU_5500 tristate "AXXIA EDAC L2/CPU Controller for 5500" help @@ -441,6 +476,14 @@ config EDAC_AXXIA_L2_CPU_5600 cache and A57 CPU error detction. L2 cache and A57 CPU error detection uses polling mechanism. +config EDAC_AXXIA_L2_CPU_6700 + tristate "AXXIA EDAC L2/CPU Controller for 6700" + help + Support for L2 cache and A53 CPU error detection + on AXXIA AXM67xx devices. This enables the L2 + cache and A53 CPU error detction. L2 cache and A53 + CPU error detection uses polling mechanism. + config EDAC_ALTERA bool "Altera SOCFPGA ECC" depends on EDAC_MM_EDAC=y && ARCH_SOCFPGA diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile index c545959..5209c9a 100644 --- a/drivers/edac/Makefile +++ b/drivers/edac/Makefile @@ -20,11 +20,15 @@ endif obj-$(CONFIG_EDAC_AXXIA_SYSMEM_5500) += axxia_edac-mc.o obj-$(CONFIG_EDAC_AXXIA_SYSMEM_5600) += axxia_edac-mc_56xx.o +obj-$(CONFIG_EDAC_AXXIA_SYSMEM_6700) += axxia_edac-mc_56xx.o obj-$(CONFIG_EDAC_AXXIA_CMEM_5600) += axxia_edac-cmc_56xx.o +obj-$(CONFIG_EDAC_AXXIA_CMEM_6700) += axxia_edac-cmc_56xx.o obj-$(CONFIG_EDAC_AXXIA_L3_5500) += axxia_edac-l3.o obj-$(CONFIG_EDAC_AXXIA_L3_5600) += axxia_edac-l3_56xx.o +obj-$(CONFIG_EDAC_AXXIA_L3_6700) += axxia_edac-l3_56xx.o obj-$(CONFIG_EDAC_AXXIA_L2_CPU_5500) += axxia_edac-l2_cpu.o obj-$(CONFIG_EDAC_AXXIA_L2_CPU_5600) += axxia_edac-l2_cpu_56xx.o +obj-$(CONFIG_EDAC_AXXIA_L2_CPU_6700) += axxia_edac-l2_cpu_56xx.o obj-$(CONFIG_EDAC_GHES) += ghes_edac.o edac_mce_amd-y := mce_amd.o diff --git a/drivers/edac/axxia_edac-cmc_56xx.c b/drivers/edac/axxia_edac-cmc_56xx.c index c4bf2d0..11c650af 100644 --- a/drivers/edac/axxia_edac-cmc_56xx.c +++ b/drivers/edac/axxia_edac-cmc_56xx.c @@ -39,7 +39,13 @@ #define MPR_HDR2 "Lp. dram0 dram1" #define MPR_HDR4 " dram2 dram3" -#define INTEL_EDAC_MOD_STR "axxia56xx_edac" +#if defined(CONFIG_EDAC_AXXIA_CMEM_5600) +#define INTEL_EDAC_MOD_STR "axxia56xx_edac" +#endif + +#if defined(CONFIG_EDAC_AXXIA_CMEM_6700) +#define INTEL_EDAC_MOD_STR "axxia67xx_edac" +#endif #define AXI2_SER3_PHY_ADDR 0x008002c00000ULL #define AXI2_SER3_PHY_SIZE PAGE_SIZE @@ -286,6 +292,31 @@ struct __packed cm_56xx_denali_ctl_34 #endif }; +#ifdef CONFIG_DEBUG_EDAC_AXXIA_CMEM + +#define CM_56XX_DENALI_CTL_62 0xf8 + +struct __packed cm_56xx_denali_ctl_62 +{ +#ifdef CPU_BIG_ENDIAN + unsigned reserved0 : 2; + unsigned xor_check_bits : 14; + unsigned reserved1 : 7; + unsigned fwc : 1; + unsigned reserved2 : 7; + unsigned ecc_en : 1; +#else /* Little Endian */ + unsigned ecc_en : 1; + unsigned reserved2 : 7; + unsigned fwc : 1; + unsigned reserved1 : 7; + unsigned xor_check_bits : 14; + unsigned reserved0 : 2; +#endif +}; + +#endif + struct __packed cm_56xx_denali_ctl_74 { #ifdef CPU_BIG_ENDIAN @@ -455,7 +486,7 @@ struct intel_edac_dev_info { char *ctl_name; char *blk_name; char *proc_name; -#ifdef CONFIG_DEBUG_CMEM +#ifdef CONFIG_DEBUG_EDAC_AXXIA_CMEM struct proc_dir_entry *dir_entry; #endif struct mutex state_machine_lock; @@ -475,7 +506,48 @@ struct intel_edac_dev_info { void (*check)(struct edac_device_ctl_info *edac_dev); }; -#ifdef CONFIG_DEBUG_CMEM +#ifdef CONFIG_DEBUG_EDAC_AXXIA_CMEM +static int setup_fault_injection(struct intel_edac_dev_info *dev_info, + int fault, int enable) +{ + struct cm_56xx_denali_ctl_62 denali_ctl_62; + + if (ncr_read(dev_info->cm_region, + CM_56XX_DENALI_CTL_62, + 4, &denali_ctl_62)) + goto error_read; + + denali_ctl_62.xor_check_bits = fault; + + if (ncr_write(dev_info->cm_region, + CM_56XX_DENALI_CTL_62, + 4, (u32 *) &denali_ctl_62)) + goto error_write; + + if (ncr_read(dev_info->cm_region, + CM_56XX_DENALI_CTL_62, + 4, &denali_ctl_62)) + goto error_read; + + denali_ctl_62.fwc = (enable > 0 ? 0x1 : 0x0); + + if (ncr_write(dev_info->cm_region, + CM_56XX_DENALI_CTL_62, + 4, (u32 *) &denali_ctl_62)) + goto error_write; + return 0; + +error_read: + printk_ratelimited("%s: Error reading denali_ctl_62\n", + dev_name(&dev_info->pdev->dev)); + return 1; + +error_write: + printk_ratelimited("%s: Error writing denali_ctl_62\n", + dev_name(&dev_info->pdev->dev)); + return 1; +} + static ssize_t mpr1_dump_show(struct edac_device_ctl_info *edac_dev, char *data) { @@ -832,7 +904,7 @@ static void intel_cm_alerts_error_check(struct edac_device_ctl_info *edac_dev) struct event_counter (*alerts)[MAX_DQ][MPR_ERRORS] = dev_info->data->alerts; struct cm_56xx_denali_ctl_34 denali_ctl_34; - int i, j, k, l, ret; + int i, j, k, ret; u32 counter; start: @@ -894,10 +966,10 @@ static void intel_cm_alerts_error_check(struct edac_device_ctl_info *edac_dev) */ counter = atomic_xchg(&alerts[i][j][k].counter, 0); - for (l = 0; l < counter; ++l) - edac_device_handle_ce(edac_dev, 0, + if (counter) + edac_device_handle_multi_ce(edac_dev, 0, alerts[i][j][k].edac_block_idx, - edac_dev->ctl_name); + counter, edac_dev->ctl_name); } } } @@ -927,7 +999,7 @@ static void intel_cm_events_error_check(struct edac_device_ctl_info *edac_dev) struct intel_edac_dev_info *dev_info = (struct intel_edac_dev_info *) edac_dev->pvt_info; struct event_counter *events = dev_info->data->events; - int i, j; + int i; u32 counter; while (1) { @@ -944,7 +1016,7 @@ static void intel_cm_events_error_check(struct edac_device_ctl_info *edac_dev) mutex_lock(&dev_info->data->edac_sysfs_data_lock); for (i = 0; i < NR_EVENTS; ++i) { counter = atomic_xchg(&events[i].counter, 0); - for (j = 0; j < counter; ++j) { + if (counter) switch (i) { /* * TODO - How can one determine event type? @@ -954,22 +1026,23 @@ static void intel_cm_events_error_check(struct edac_device_ctl_info *edac_dev) case EV_MULT_ILLEGAL: case EV_UNCORR_ECC: case EV_MULT_UNCORR_ECC: - edac_device_handle_ue(edac_dev, 0, i, - edac_dev->ctl_name); + edac_device_handle_multi_ue(edac_dev, + 0, i, counter, + edac_dev->ctl_name); break; case EV_CORR_ECC: case EV_MULT_CORR_ECC: case EV_PORT_ERROR: case EV_WRAP_ERROR: case EV_PARITY_ERROR: - edac_device_handle_ce(edac_dev, 0, i, - edac_dev->ctl_name); + edac_device_handle_multi_ce(edac_dev, + 0, i, counter, + edac_dev->ctl_name); break; default: printk_ratelimited( "ERROR EVENT MISSING.\n"); } - } } mutex_unlock(&dev_info->data->edac_sysfs_data_lock); } @@ -1209,7 +1282,7 @@ static int initialize(struct intel_edac_dev_info *dev_info) dev_info->edac_dev->dev_name = dev_name(&dev_info->pdev->dev); dev_info->edac_dev->edac_check = NULL; -#ifdef CONFIG_DEBUG_CMEM +#ifdef CONFIG_DEBUG_EDAC_AXXIA_CMEM if (dev_info->is_ddr4) axxia_mc_sysfs_attributes(dev_info->edac_dev); #endif @@ -1311,7 +1384,7 @@ static int enable_driver_irq(struct intel_edac_dev_info *dev_info) } -#ifdef CONFIG_DEBUG_CMEM +#ifdef CONFIG_DEBUG_EDAC_AXXIA_CMEM static ssize_t axxia_cmem_read(struct file *filp, char *buffer, size_t length, loff_t *offset) { @@ -1323,7 +1396,7 @@ axxia_cmem_read(struct file *filp, char *buffer, size_t length, loff_t *offset) if (*offset > 0) return 0; - buf = kmalloc(PAGE_SIZE, __GFP_WAIT); + buf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (buf == NULL) goto no_mem_buffer; @@ -1335,7 +1408,15 @@ axxia_cmem_read(struct file *filp, char *buffer, size_t length, loff_t *offset) */ len = snprintf(buf, PAGE_SIZE-1, "Node: 0x%x\n" "Command available:\n" - " dump - triggers mpr_page1 dump.\n", + " dump - triggers mpr_page1 dump.\n" + " cerror - enable correctable error injection.\n" + " uerror - enable uncorrectable error injection.\n" + " disable - disable errors injection\n" + " When error is enabled run a sequence:\n" + " ncpWrite -w 32 0x%x.0x0.0x4 0x11223344\n" + " ncpRead 0x%x.0x0.0x4\n", + (int) dev_info->cm_region >> 16, + (int) dev_info->cm_region >> 16, (int) dev_info->cm_region >> 16); mutex_unlock(&dev_info->state_machine_lock); @@ -1361,7 +1442,7 @@ axxia_cmem_write(struct file *file, const char __user *buffer, struct intel_edac_dev_info *dev_info = (struct intel_edac_dev_info *) file->private_data; - buf = kmalloc(count + 1, __GFP_WAIT); + buf = kmalloc(count + 1, GFP_KERNEL); if (buf == NULL) goto no_mem_buffer; @@ -1376,6 +1457,18 @@ axxia_cmem_write(struct file *file, const char __user *buffer, atomic_inc(&dev_info->data->dump_in_progress); wake_up(&dev_info->data->dump_wq); } + if (!strncmp(buf, "cerror", 6)) { + /* 0x75 0x75 */ + setup_fault_injection(dev_info, 0x3af5, 1); + } + if (!strncmp(buf, "uerror", 6)) { + /* 0x3 0x3 */ + setup_fault_injection(dev_info, 0x183, 1); + } + if (!strncmp(buf, "disable", 7)) { + /* disable injection */ + setup_fault_injection(dev_info, 0x0, 0); + } kfree(buf); return count; @@ -1548,7 +1641,7 @@ static int intel_edac_mc_probe(struct platform_device *pdev) dev_name(&dev_info->pdev->dev)); } -#ifdef CONFIG_DEBUG_CMEM +#ifdef CONFIG_DEBUG_EDAC_AXXIA_CMEM /* in this case create procfs file to be used by rte */ dev_info->proc_name = devm_kzalloc(&pdev->dev, 32*sizeof(char), @@ -1599,7 +1692,7 @@ static int intel_edac_mc_remove(struct platform_device *pdev) (struct intel_edac_dev_info *) &pdev->dev; if (dev_info) { -#ifdef CONFIG_DEBUG_CMEM +#ifdef CONFIG_DEBUG_EDAC_AXXIA_CMEM remove_procfs_entry(dev_info); #endif diff --git a/drivers/edac/axxia_edac-l2_cpu_56xx.c b/drivers/edac/axxia_edac-l2_cpu_56xx.c index 4b5f6bf..3248384 100644 --- a/drivers/edac/axxia_edac-l2_cpu_56xx.c +++ b/drivers/edac/axxia_edac-l2_cpu_56xx.c @@ -9,6 +9,8 @@ * GNU General Public License. */ +#define CREATE_TRACE_POINTS + #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> @@ -22,12 +24,20 @@ #include <linux/reboot.h> #include <linux/mfd/syscon.h> #include <linux/regmap.h> +#include <trace/events/edac.h> #include "edac_core.h" #include "edac_module.h" #include "axxia_l2_56xx.h" +#if defined(CONFIG_EDAC_AXXIA_L2_CPU_5600) #define INTEL_EDAC_MOD_STR "axxia56xx_edac" +#endif + +#if defined(CONFIG_EDAC_AXXIA_L2_CPU_6700) +#define INTEL_EDAC_MOD_STR "axxia67xx_edac" +#endif + #define CORES_PER_CLUSTER 4 #define SYSCON_PERSIST_SCRATCH 0xdc @@ -50,38 +60,41 @@ void log_cpumerrsr(void *edac) struct edac_device_ctl_info *edac_dev = edac; u64 val, clear_val; u32 count0, count1; - int i; struct intel_edac_dev_info *dev_info; dev_info = edac_dev->pvt_info; /* Read S3_1_c15_c2_2 for CPUMERRSR_EL1 counts */ val = read_cpumerrsr(); + trace_edac_l1cache_syndrome(val); + + if (val & 0x8000000000000000) { + regmap_update_bits(dev_info->syscon, + SYSCON_PERSIST_SCRATCH, + CPU_PERSIST_SCRATCH_BIT, + CPU_PERSIST_SCRATCH_BIT); + pr_emerg("CPU uncorrectable error\n"); + machine_restart(NULL); + } + if (val & 0x80000000) { int cpu = get_cpu(); - count0 = ((val) & 0x000000ff00000000) >> 31; - count1 = ((val) & 0x0000ff0000000000) >> 39; + count0 = ((val) & 0x000000ff00000000) >> 32; + count1 = ((val) & 0x0000ff0000000000) >> 40; /* increment correctable error counts */ - for (i = 0; i < count0+count1; i++) { - edac_device_handle_ce(edac_dev, 0, - cpu, edac_dev->ctl_name); - } + trace_edac_l1cache_counter(count0 + count1); + + if (count0 || count1) + edac_device_handle_multi_ce(edac_dev, 0, cpu, + count0 + count1, edac_dev->ctl_name); /* Clear the valid bit */ clear_val = 0x80000000; write_cpumerrsr(clear_val); put_cpu(); } - if (val & 0x8000000000000000) { - regmap_update_bits(dev_info->syscon, - SYSCON_PERSIST_SCRATCH, - CPU_PERSIST_SCRATCH_BIT, - CPU_PERSIST_SCRATCH_BIT); - pr_emerg("CPU uncorrectable error\n"); - machine_restart(NULL); - } } @@ -101,38 +114,38 @@ void log_l2merrsr(void *edac) struct edac_device_ctl_info *edac_dev = edac; u64 val, clear_val; u32 count0, count1; - int i; struct intel_edac_dev_info *dev_info; dev_info = edac_dev->pvt_info; val = read_l2merrsr(); + trace_edac_l2cache_syndrome(val); + if (val & 0x8000000000000000) { + regmap_update_bits(dev_info->syscon, + SYSCON_PERSIST_SCRATCH, + L2_PERSIST_SCRATCH_BIT, + L2_PERSIST_SCRATCH_BIT); + pr_emerg("L2 uncorrectable error\n"); + machine_restart(NULL); + } if (val & 0x80000000) { int cpu = get_cpu(); - count0 = ((val) & 0x000000ff00000000) >> 31; - count1 = ((val) & 0x0000ff0000000000) >> 39; + count0 = ((val) & 0x000000ff00000000) >> 32; + count1 = ((val) & 0x0000ff0000000000) >> 40; /* increment correctable error counts */ - for (i = 0; i < count0+count1; i++) { - edac_device_handle_ce(edac_dev, 0, + trace_edac_l2cache_counter(count0 + count1); + if (count0 || count1) + edac_device_handle_multi_ce(edac_dev, 0, cpu/CORES_PER_CLUSTER, - edac_dev->ctl_name); - } + count0 + count1, edac_dev->ctl_name); /* Clear the valid bit */ clear_val = 0x80000000; write_l2merrsr(clear_val); put_cpu(); } - if (val & 0x8000000000000000) { - regmap_update_bits(dev_info->syscon, - SYSCON_PERSIST_SCRATCH, - L2_PERSIST_SCRATCH_BIT, - L2_PERSIST_SCRATCH_BIT); - pr_emerg("L2 uncorrectable error\n"); - machine_restart(NULL); - } } /* Check for L2 Errors */ @@ -262,9 +275,22 @@ static int intel_edac_l2_remove(struct platform_device *pdev) } static const struct of_device_id intel_edac_l2_match[] = { +#if defined(CONFIG_EDAC_AXXIA_L2_CPU_5600) + { .compatible = "intel,cortex-a57-l2-cache", }, + +#endif + +#if defined(CONFIG_EDAC_AXXIA_L2_CPU_6700) + + { + .compatible = "intel,cortex-a53-l2-cache", + }, + +#endif + {}, }; @@ -277,9 +303,21 @@ static struct platform_driver intel_edac_l2_driver = { } }; static const struct of_device_id intel_edac_cpu_match[] = { +#if defined(CONFIG_EDAC_AXXIA_L2_CPU_5600) + { .compatible = "intel,cortex-a57-cpu", }, + +#endif + +#if defined(CONFIG_EDAC_AXXIA_L2_CPU_6700) + + { + .compatible = "intel,cortex-a53-cpu", + }, + +#endif {}, }; diff --git a/drivers/edac/axxia_edac-l3_56xx.c b/drivers/edac/axxia_edac-l3_56xx.c index fa9548b..af4ff16 100644 --- a/drivers/edac/axxia_edac-l3_56xx.c +++ b/drivers/edac/axxia_edac-l3_56xx.c @@ -2,12 +2,14 @@ * drivers/edac/axxia_edac-l3_56xx.c * * EDAC Driver for Intel's Axxia 5600 L3 (DICKENS) + * EDAC Driver for Intel's Axxia 6700 L3 (SHELLEY) * * Copyright (C) 2017 Intel Inc. * * This file may be distributed under the terms of the * GNU General Public License. */ +#define CREATE_TRACE_POINTS #include <linux/module.h> #include <linux/init.h> @@ -24,10 +26,21 @@ #include <linux/mfd/syscon.h> #include <linux/regmap.h> #include <linux/arm-smccc.h> +#include <trace/events/edacl3.h> #include "edac_core.h" #include "edac_module.h" +#if defined(CONFIG_EDAC_AXXIA_L3_5600) #define INTEL_EDAC_MOD_STR "axxia56xx_edac" +#define CCN_XP_NODES 11 +#define CCN_HNI_NODES 1 +#endif + +#if defined(CONFIG_EDAC_AXXIA_L3_6700) +#define INTEL_EDAC_MOD_STR "axxia67xx_edac" +#define CCN_XP_NODES 18 +#define CCN_HNI_NODES 2 +#endif #define SYSCON_PERSIST_SCRATCH 0xdc #define L3_PERSIST_SCRATCH_BIT (0x1 << 4) @@ -55,7 +68,6 @@ #define CCN_HNI_NODE_BIT 8 #define CCN_HNF_NODES 8 -#define CCN_XP_NODES 11 #define CCN_DT_NODE_BASE_ADDR (1 * CCN_REGION_SIZE) #define CCN_HNI_NODE_BASE_ADDR(i) (0x80000 + (i) * CCN_REGION_SIZE) #define CCN_HNF_NODE_BASE_ADDR(i) (0x200000 + (i) * CCN_REGION_SIZE) @@ -151,7 +163,7 @@ struct intel_edac_dev_info { int irq_used; struct event_data data[CCN_HNF_NODES]; struct event_data data_xp[CCN_XP_NODES]; - struct event_data data_hni; + struct event_data data_hni[CCN_HNI_NODES]; struct regmap *syscon; void __iomem *dickens_L3; struct edac_device_ctl_info *edac_dev; @@ -198,7 +210,7 @@ static irqreturn_t ccn_irq_thread(int irq, void *device) union dickens_hnf_err_syndrome_reg1 err_syndrome_reg1; struct arm_smccc_res r; unsigned int count = 0; - int i, j; + int i; /* only HNF nodes are of our interest */ for (i = 0; i < CCN_HNF_NODES; ++i) { @@ -222,10 +234,10 @@ static irqreturn_t ccn_irq_thread(int irq, void *device) machine_restart(NULL); } count = err_syndrome_reg0.reg0.err_count; - for (j = 0; j < count; j++) - edac_device_handle_ce(edac_dev, 0, + if (count) + edac_device_handle_multi_ce(edac_dev, 0, dev_info->data[i].idx, - edac_dev->ctl_name); + count, edac_dev->ctl_name); } } @@ -233,6 +245,8 @@ static irqreturn_t ccn_irq_thread(int irq, void *device) arm_smccc_smc(0xc4000027, CCN_MN_ERRINT_STATUS__INTREQ__DESSERT, 0, 0, 0, 0, 0, 0, &r); + trace_edacl3_smc_results(&r); + return IRQ_HANDLED; } @@ -262,24 +276,37 @@ static irqreturn_t ccn_irq_handler(int irq, void *device) err_or |= err_sig_val[i]; } - err_type_value[i] = readq(ccn_base + CCN_MN_ERROR_TYPE_VALUE); - err_type_value[i] = readq(ccn_base + CCN_MN_ERROR_TYPE_VALUE + 0x8); - err_type_value[i] = readq(ccn_base + CCN_MN_ERROR_TYPE_VALUE + 0x10); - err_type_value[i] = readq(ccn_base + CCN_MN_ERROR_TYPE_VALUE + 0x20); + trace_edacl3_sig_vals(err_sig_val[0], err_sig_val[1], + err_sig_val[2]); + + i = 0; + err_type_value[i] = readq(ccn_base + CCN_MN_ERROR_TYPE_VALUE); + err_type_value[++i] = readq(ccn_base + CCN_MN_ERROR_TYPE_VALUE + 0x8); + err_type_value[++i] = readq(ccn_base + CCN_MN_ERROR_TYPE_VALUE + 0x10); + err_type_value[++i] = readq(ccn_base + CCN_MN_ERROR_TYPE_VALUE + 0x20); + + trace_edacl3_error_types(err_type_value[0], err_type_value[1], + err_type_value[2], err_type_value[3]); /* check hni node */ - if ((0x1 << CCN_HNI_NODE_BIT) & err_sig_val[0]) { - err_synd_reg0 = readq(ccn_base + CCN_HNI_NODE_BASE_ADDR(0) + + for (i = 0; i < CCN_HNI_NODES; ++i) { + if ((0x1 << (CCN_HNI_NODE_BIT + i)) & err_sig_val[0]) { + err_synd_reg0 = readq(ccn_base + + CCN_HNI_NODE_BASE_ADDR(i) + CCN_NODE_ERR_SYND_REG0); - err_synd_reg1 = readq(ccn_base + CCN_HNI_NODE_BASE_ADDR(0) + + err_synd_reg1 = readq(ccn_base + + CCN_HNI_NODE_BASE_ADDR(i) + CCN_NODE_ERR_SYND_REG1); - dev_info->data_hni.err_synd_reg0 = err_synd_reg0; - dev_info->data_hni.err_synd_reg1 = err_synd_reg1; - dev_info->data_hni.idx = 0; + trace_edacl3_syndromes(err_synd_reg0, + err_synd_reg1); + dev_info->data_hni[i].err_synd_reg0 = err_synd_reg0; + dev_info->data_hni[i].err_synd_reg1 = err_synd_reg1; + dev_info->data_hni[i].idx = 0; - clear_node_error(ccn_base + CCN_HNI_NODE_BASE_ADDR(0) + - CCN_NODE_ERR_SYND_CLR); + clear_node_error(ccn_base + CCN_HNI_NODE_BASE_ADDR(i) + + CCN_NODE_ERR_SYND_CLR); + } } /* go through all hnf nodes */ @@ -293,6 +320,9 @@ static irqreturn_t ccn_irq_handler(int irq, void *device) CCN_HNF_NODE_BASE_ADDR(i) + CCN_NODE_ERR_SYND_REG1); + trace_edacl3_syndromes(err_synd_reg0, + err_synd_reg1); + dev_info->data[i].err_synd_reg0 = err_synd_reg0; dev_info->data[i].err_synd_reg1 = err_synd_reg1; dev_info->data[i].idx = i; @@ -313,6 +343,9 @@ static irqreturn_t ccn_irq_handler(int irq, void *device) dev_info->data_xp[i].err_synd_reg0 = err_synd_reg0; dev_info->data_xp[i].err_synd_reg1 = 0; + trace_edacl3_syndromes(err_synd_reg0, + err_synd_reg1); + clear_node_error(ccn_base + CCN_XP_NODE_BASE_ADDR(i) + CCN_NODE_ERR_SYND_CLR); } @@ -335,7 +368,7 @@ static void intel_l3_error_check(struct edac_device_ctl_info *edac_dev) union dickens_hnf_err_syndrome_reg0 err_syndrome_reg0; union dickens_hnf_err_syndrome_clr err_syndrome_clr; unsigned int count = 0; - int i, instance; + int instance; struct intel_edac_dev_info *dev_info; err_syndrome_clr.value = 0x0; @@ -351,6 +384,9 @@ static void intel_l3_error_check(struct edac_device_ctl_info *edac_dev) err_syndrome_reg0.value = readq(addr + CCN_NODE_ERR_SYND_REG0); + + trace_edacl3_syndromes(err_syndrome_reg0.value, + (u64) 0); /* First error valid */ if (err_syndrome_reg0.reg0.first_err_vld) { if (err_syndrome_reg0.reg0.err_class & 0x3) { @@ -363,9 +399,9 @@ static void intel_l3_error_check(struct edac_device_ctl_info *edac_dev) machine_restart(NULL); } count = err_syndrome_reg0.reg0.err_count; - for (i = 0; i < count; i++) - edac_device_handle_ce(edac_dev, 0, - instance, edac_dev->ctl_name); + if (count) + edac_device_handle_multi_ce(edac_dev, 0, + instance, count, edac_dev->ctl_name); /* clear the valid bit */ clear_node_error(addr + CCN_NODE_ERR_SYND_CLR); @@ -413,7 +449,7 @@ static int intel_edac_l3_probe(struct platform_device *pdev) dev_info->edac_dev = edac_device_alloc_ctl_info(0, dev_info->ctl_name, 1, dev_info->blk_name, - 8, 0, NULL, 0, + CCN_HNI_NODES, 0, NULL, 0, dev_info->edac_idx); if (!dev_info->edac_dev) { pr_info("No memory for edac device\n"); @@ -478,9 +514,21 @@ static int intel_edac_l3_remove(struct platform_device *pdev) } static const struct of_device_id intel_edac_l3_match[] = { +#if defined(CONFIG_EDAC_AXXIA_L2_CPU_5600) + { .compatible = "intel,ccn504-l3-cache", }, + +#endif + +#if defined(CONFIG_EDAC_AXXIA_L2_CPU_6700) + + { + .compatible = "intel,ccn512-l3-cache", + }, + +#endif {}, }; diff --git a/drivers/edac/axxia_edac-mc_56xx.c b/drivers/edac/axxia_edac-mc_56xx.c index fb1e742..fcc53bd 100644 --- a/drivers/edac/axxia_edac-mc_56xx.c +++ b/drivers/edac/axxia_edac-mc_56xx.c @@ -43,7 +43,13 @@ #define MPR_HDR18 " dram9 dram10 dram11 dram12"\ " dram13 dram14 dram15 dram16 dram17" -#define INTEL_EDAC_MOD_STR "axxia56xx_edac" +#if defined(CONFIG_EDAC_AXXIA_SYSMEM_5600) +#define INTEL_EDAC_MOD_STR "axxia56xx_edac" +#endif + +#if defined(CONFIG_EDAC_AXXIA_SYSMEM_6700) +#define INTEL_EDAC_MOD_STR "axxia67xx_edac" +#endif #define AXI2_SER3_PHY_ADDR 0x008002c00000ULL #define AXI2_SER3_PHY_SIZE PAGE_SIZE @@ -995,7 +1001,7 @@ static void intel_sm_alerts_error_check(struct edac_device_ctl_info *edac_dev) struct event_counter (*alerts)[MAX_DQ][MPR_ERRORS] = dev_info->data->alerts; struct sm_56xx_denali_ctl_57 denali_ctl_57; - int i, j, k, l; + int i, j, k; u32 counter; start: @@ -1052,12 +1058,12 @@ static void intel_sm_alerts_error_check(struct edac_device_ctl_info *edac_dev) * TODO - How can one determine event type? * recoverable/unrecoverable */ - counter = atomic_xchg(&alerts[i][j][k].counter, - 0); - for (l = 0; l < counter; ++l) - edac_device_handle_ce(edac_dev, 0, + counter = atomic_xchg( + &alerts[i][j][k].counter, 0); + if (counter) + edac_device_handle_multi_ce(edac_dev, 0, alerts[i][j][k].edac_block_idx, - edac_dev->ctl_name); + counter, edac_dev->ctl_name); } } } @@ -1081,7 +1087,7 @@ static void intel_sm_events_error_check(struct edac_device_ctl_info *edac_dev) struct intel_edac_dev_info *dev_info = (struct intel_edac_dev_info *) edac_dev->pvt_info; struct event_counter *events = dev_info->data->events; - int i, j; + int i; u32 counter; while (1) { @@ -1098,7 +1104,7 @@ static void intel_sm_events_error_check(struct edac_device_ctl_info *edac_dev) mutex_lock(&dev_info->data->edac_sysfs_data_lock); for (i = 0; i < NR_EVENTS; ++i) { counter = atomic_xchg(&events[i].counter, 0); - for (j = 0; j < counter; ++j) { + if (counter) switch (i) { /* * TODO - How can one determine event type? @@ -1108,22 +1114,23 @@ static void intel_sm_events_error_check(struct edac_device_ctl_info *edac_dev) case EV_MULT_ILLEGAL: case EV_UNCORR_ECC: case EV_MULT_UNCORR_ECC: - edac_device_handle_ue(edac_dev, 0, i, - edac_dev->ctl_name); + edac_device_handle_multi_ue(edac_dev, + 0, i, counter, + edac_dev->ctl_name); break; case EV_CORR_ECC: case EV_MULT_CORR_ECC: case EV_PORT_ERROR: case EV_WRAP_ERROR: case EV_PARITY_ERROR: - edac_device_handle_ce(edac_dev, 0, i, - edac_dev->ctl_name); + edac_device_handle_multi_ce(edac_dev, + 0, i, counter, + edac_dev->ctl_name); break; default: printk_ratelimited( "ERROR EVENT MISSING.\n"); } - } } mutex_unlock(&dev_info->data->edac_sysfs_data_lock); } diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h index 4861542..e2d64e1 100644 --- a/drivers/edac/edac_core.h +++ b/drivers/edac/edac_core.h @@ -481,8 +481,15 @@ extern int edac_device_add_device(struct edac_device_ctl_info *edac_dev); extern struct edac_device_ctl_info *edac_device_del_device(struct device *dev); extern void edac_device_handle_ue(struct edac_device_ctl_info *edac_dev, int inst_nr, int block_nr, const char *msg); +extern void edac_device_handle_multi_ue(struct edac_device_ctl_info *edac_dev, + int inst_nr, int block_nr, int events, + const char *msg); extern void edac_device_handle_ce(struct edac_device_ctl_info *edac_dev, int inst_nr, int block_nr, const char *msg); +extern void edac_device_handle_multi_ce(struct edac_device_ctl_info *edac_dev, + int inst_nr, int block_nr, int events, + const char *msg); + extern int edac_device_alloc_index(void); extern const char *edac_layer_name[]; diff --git a/drivers/edac/edac_device.c b/drivers/edac/edac_device.c index a979003..0f735ce 100644 --- a/drivers/edac/edac_device.c +++ b/drivers/edac/edac_device.c @@ -25,7 +25,7 @@ #include <linux/list.h> #include <linux/ctype.h> #include <linux/workqueue.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> #include <asm/page.h> #include "edac_core.h" @@ -154,7 +154,7 @@ struct edac_device_ctl_info *edac_device_alloc_ctl_info( dev_ctl->log_ue = 1; /* Name of this edac device */ - snprintf(dev_ctl->name,sizeof(dev_ctl->name),"%s",edac_device_name); + snprintf(dev_ctl->name, sizeof(dev_ctl->name), "%s", edac_device_name); edac_dbg(4, "edac_dev=%p next after end=%p\n", dev_ctl, pvt + sz_private); @@ -655,6 +655,50 @@ void edac_device_handle_ce(struct edac_device_ctl_info *edac_dev, EXPORT_SYMBOL_GPL(edac_device_handle_ce); /* + * edac_device_handle_multi_ce + * perform a common output and handling of an 'edac_dev' CE multiple events + */ +void edac_device_handle_multi_ce(struct edac_device_ctl_info *edac_dev, + int inst_nr, int block_nr, int events, const char *msg) +{ + struct edac_device_instance *instance; + struct edac_device_block *block = NULL; + + if ((inst_nr >= edac_dev->nr_instances) || (inst_nr < 0)) { + edac_device_printk(edac_dev, KERN_ERR, + "INTERNAL ERROR: 'instance' out of range (%d >= %d)\n", + inst_nr, edac_dev->nr_instances); + return; + } + + instance = edac_dev->instances + inst_nr; + + if ((block_nr >= instance->nr_blocks) || (block_nr < 0)) { + edac_device_printk(edac_dev, KERN_ERR, + "INTERNAL ERROR: instance %d 'block' out of range (%d >= %d)\n", + inst_nr, block_nr, + instance->nr_blocks); + return; + } + + if (instance->nr_blocks > 0) { + block = instance->blocks + block_nr; + block->counters.ce_count += events; + } + + /* Propagate the count up the 'totals' tree */ + instance->counters.ce_count += events; + edac_dev->counters.ce_count += events; + + if (edac_device_get_log_ce(edac_dev)) + edac_device_printk(edac_dev, KERN_WARNING, + "CE: %s instance: %s block: %s events: %d '%s'\n", + edac_dev->ctl_name, instance->name, + block ? block->name : "N/A", events, msg); +} +EXPORT_SYMBOL_GPL(edac_device_handle_multi_ce); + +/* * edac_device_handle_ue * perform a common output and handling of an 'edac_dev' UE event */ @@ -704,3 +748,52 @@ void edac_device_handle_ue(struct edac_device_ctl_info *edac_dev, block ? block->name : "N/A", msg); } EXPORT_SYMBOL_GPL(edac_device_handle_ue); + +/* + * edac_device_handle_multi_ue + * perform a common output and handling of an 'edac_dev' UE event + */ +void edac_device_handle_multi_ue(struct edac_device_ctl_info *edac_dev, + int inst_nr, int block_nr, int events, const char *msg) +{ + struct edac_device_instance *instance; + struct edac_device_block *block = NULL; + + if ((inst_nr >= edac_dev->nr_instances) || (inst_nr < 0)) { + edac_device_printk(edac_dev, KERN_ERR, + "INTERNAL ERROR: 'instance' out of range (%d >= %d)\n", + inst_nr, edac_dev->nr_instances); + return; + } + + instance = edac_dev->instances + inst_nr; + + if ((block_nr >= instance->nr_blocks) || (block_nr < 0)) { + edac_device_printk(edac_dev, KERN_ERR, + "INTERNAL ERROR: instance %d 'block' out of range (%d >= %d)\n", + inst_nr, block_nr, + instance->nr_blocks); + return; + } + + if (instance->nr_blocks > 0) { + block = instance->blocks + block_nr; + block->counters.ue_count += events; + } + + /* Propagate the count up the 'totals' tree */ + instance->counters.ue_count += events; + edac_dev->counters.ue_count += events; + + if (edac_device_get_log_ue(edac_dev)) + edac_device_printk(edac_dev, KERN_EMERG, + "UE: %s instance: %s block: %s events: %d '%s'\n", + edac_dev->ctl_name, instance->name, + block ? block->name : "N/A", events, msg); + + if (edac_device_get_panic_on_ue(edac_dev)) + panic("EDAC %s: UE instance: %s block %s events: %d '%s'\n", + edac_dev->ctl_name, instance->name, + block ? block->name : "N/A", events, msg); +} +EXPORT_SYMBOL_GPL(edac_device_handle_multi_ue); diff --git a/drivers/misc/lsi-ncr.c b/drivers/misc/lsi-ncr.c index d918ccb..a5fd0f3 100644 --- a/drivers/misc/lsi-ncr.c +++ b/drivers/misc/lsi-ncr.c @@ -172,8 +172,8 @@ ncr_register_write(const unsigned int value, unsigned int *address) if (0 == nca_big_endian) __raw_writel(value, address); - - __raw_writel(cpu_to_be32(value), address); + else + __raw_writel(cpu_to_be32(value), address); } /* diff --git a/include/trace/events/edac.h b/include/trace/events/edac.h new file mode 100644 index 0000000..29da0d1 --- /dev/null +++ b/include/trace/events/edac.h @@ -0,0 +1,77 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM edac + +#if !defined(_TRACE_EDAC_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_EDAC_H + +#include <linux/types.h> +#include <linux/tracepoint.h> + + +TRACE_EVENT(edac_l2cache_syndrome, + TP_PROTO(u64 syndrome), + + TP_ARGS(syndrome), + + TP_STRUCT__entry( + __field(u64, syndrome) + ), + + TP_fast_assign( + __entry->syndrome = syndrome; + ), + + TP_printk("L2MERRSR_EL1=0x%016llx", (u64) __entry->syndrome) +); + +TRACE_EVENT(edac_l2cache_counter, + TP_PROTO(int counter), + + TP_ARGS(counter), + + TP_STRUCT__entry( + __field(int, counter) + ), + + TP_fast_assign( + __entry->counter = counter; + ), + + TP_printk("l2 counter =%d", __entry->counter) +); + +TRACE_EVENT(edac_l1cache_syndrome, + TP_PROTO(u64 syndrome), + + TP_ARGS(syndrome), + + TP_STRUCT__entry( + __field(u64, syndrome) + ), + + TP_fast_assign( + __entry->syndrome = syndrome; + ), + + TP_printk("CPUMERRSR_EL1=0x%016llx", (u64) __entry->syndrome) +); + +TRACE_EVENT(edac_l1cache_counter, + TP_PROTO(int counter), + + TP_ARGS(counter), + + TP_STRUCT__entry( + __field(int, counter) + ), + + TP_fast_assign( + __entry->counter = counter; + ), + + TP_printk("l1 counter =%d", __entry->counter) +); +#endif /* _TRACE_EDAC_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/include/trace/events/edacl3.h b/include/trace/events/edacl3.h new file mode 100644 index 0000000..5b63278 --- /dev/null +++ b/include/trace/events/edacl3.h @@ -0,0 +1,109 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM edacl3 + +#if !defined(_TRACE_EDACL3_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_EDACL3_H + +#include <linux/types.h> +#include <linux/tracepoint.h> + + +TRACE_EVENT(edacl3_error_types, + TP_PROTO(u64 error_31_0, u64 error_63_32, + u64 error_95_64, u64 error_159_128), + + TP_ARGS(error_31_0, error_63_32, error_95_64, error_159_128), + + TP_STRUCT__entry( + __field(u64, error_31_0) + __field(u64, error_63_32) + __field(u64, error_95_64) + __field(u64, error_159_128) + ), + + TP_fast_assign( + __entry->error_31_0 = error_31_0; + __entry->error_63_32 = error_63_32; + __entry->error_95_64 = error_95_64; + __entry->error_159_128 = error_159_128; + ), + + TP_printk("Err types(0-3):(0x%016llx, 0x%016llx, 0x%016llx, 0x%016llx)", + (u64) __entry->error_31_0, (u64) __entry->error_63_32, + (u64) __entry->error_95_64, (u64) __entry->error_159_128 + ) +); + +TRACE_EVENT(edacl3_sig_vals, + TP_PROTO(u64 sig_val_63_0, u64 sig_val_127_64, u64 sig_val_191_128), + + TP_ARGS(sig_val_63_0, sig_val_127_64, sig_val_191_128), + + TP_STRUCT__entry( + __field(u64, sig_val_63_0) + __field(u64, sig_val_127_64) + __field(u64, sig_val_191_128) + ), + + TP_fast_assign( + __entry->sig_val_63_0 = sig_val_63_0; + __entry->sig_val_127_64 = sig_val_127_64; + __entry->sig_val_191_128 = sig_val_191_128; + ), + + TP_printk("Sig_val_regs(0-3):(0x%016llx, 0x%016llx, 0x%016llx)", + (u64) __entry->sig_val_63_0, (u64) __entry->sig_val_127_64, + (u64) __entry->sig_val_191_128 + ) +); + +TRACE_EVENT(edacl3_syndromes, + TP_PROTO(u64 syndrome0, u64 syndrome1), + + TP_ARGS(syndrome0, syndrome1), + + TP_STRUCT__entry( + __field(u64, syndrome0) + __field(u64, syndrome1) + ), + + TP_fast_assign( + __entry->syndrome0 = syndrome0; + __entry->syndrome1 = syndrome1; + ), + + TP_printk("Syndromes(0-1):(0x%016llx, 0x%016llx)", + (u64) __entry->syndrome0, (u64) __entry->syndrome1 + ) +); + + +TRACE_EVENT(edacl3_smc_results, + TP_PROTO(struct arm_smccc_res *ptr), + + TP_ARGS(ptr), + + TP_STRUCT__entry( + __field(u64, a0) + __field(u64, a1) + __field(u64, a2) + __field(u64, a3) + ), + + TP_fast_assign( + __entry->a0 = ptr->a0; + __entry->a1 = ptr->a1; + __entry->a2 = ptr->a2; + __entry->a3 = ptr->a3; + ), + + TP_printk("Smc(a0-a3):(0x%llx, 0x%llx, 0x%llx, 0x%llx)", + (u64) __entry->a0, (u64) __entry->a1, + (u64) __entry->a2, (u64) __entry->a3 + ) +); + +#endif /* _TRACE_EDACL3_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> -- 2.7.4 -- _______________________________________________ linux-yocto mailing list linux-yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/linux-yocto