File indexing completed on 2025-05-11 08:22:42
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #include <bsp.h>
0038 #include <bsp/ecc_priv.h>
0039 #include <bsp/irq.h>
0040 #include <bsp/utility.h>
0041 #include <rtems/score/aarch64-system-registers.h>
0042
0043 static Cache_Error_RAM_ID get_l1_ramid(uint64_t ramid)
0044 {
0045 switch (ramid) {
0046 case 0x0:
0047 return RAM_ID_L1I_TAG;
0048 case 0x1:
0049 return RAM_ID_L1I_DATA;
0050 case 0x8:
0051 return RAM_ID_L1D_TAG;
0052 case 0x9:
0053 return RAM_ID_L1D_DATA;
0054 case 0xa:
0055 return RAM_ID_L1D_DIRTY;
0056 case 0x18:
0057 return RAM_ID_TLB;
0058 default:
0059 return RAM_ID_UNKNOWN;
0060 }
0061 }
0062
0063 static Cache_Error_RAM_ID get_l2_ramid(uint64_t ramid)
0064 {
0065 switch (ramid) {
0066 case 0x10:
0067 return RAM_ID_L2_TAG;
0068 case 0x11:
0069 return RAM_ID_L2_DATA;
0070 case 0x12:
0071 return RAM_ID_SCU;
0072 default:
0073 return RAM_ID_UNKNOWN;
0074 }
0075 }
0076
0077 static void cache_handler(void *arg)
0078 {
0079 uint64_t l1val = _AArch64_Read_cpumerrsr_el1();
0080 _AArch64_Write_cpumerrsr_el1(l1val);
0081 uint64_t l2val = _AArch64_Read_l2merrsr_el1();
0082 _AArch64_Write_l2merrsr_el1(l2val);
0083
0084 (void) arg;
0085
0086 if (l1val & AARCH64_CPUMERRSR_EL1_VALID) {
0087
0088 Cache_Error_Info cerr = {0, };
0089 cerr.abort = l1val & AARCH64_CPUMERRSR_EL1_FATAL;
0090 cerr.repeats = AARCH64_CPUMERRSR_EL1_REPEATERR_GET(l1val);
0091 cerr.other_errors = AARCH64_CPUMERRSR_EL1_OTHERERR_GET(l1val);
0092 cerr.ramid = get_l1_ramid(AARCH64_CPUMERRSR_EL1_RAMID_GET(l1val));
0093 cerr.segment = AARCH64_CPUMERRSR_EL1_CPUIDWAY_GET(l1val);
0094 cerr.address = AARCH64_CPUMERRSR_EL1_ADDR_GET(l1val);
0095
0096 zynqmp_invoke_ecc_handler(L1_CACHE, &cerr);
0097 }
0098
0099 if (l2val & AARCH64_L2MERRSR_EL1_VALID) {
0100
0101 Cache_Error_Info cerr = {0, };
0102 cerr.abort = l2val & AARCH64_L2MERRSR_EL1_FATAL;
0103 cerr.repeats = AARCH64_L2MERRSR_EL1_REPEATERR_GET(l2val);
0104 cerr.other_errors = AARCH64_L2MERRSR_EL1_OTHERERR_GET(l2val);
0105 cerr.ramid = get_l2_ramid(AARCH64_L2MERRSR_EL1_RAMID_GET(l2val));
0106 cerr.segment = AARCH64_L2MERRSR_EL1_CPUIDWAY_GET(l2val);
0107 cerr.address = AARCH64_L2MERRSR_EL1_ADDR_GET(l2val);
0108
0109 zynqmp_invoke_ecc_handler(L2_CACHE, &cerr);
0110 }
0111 }
0112
0113 static rtems_interrupt_entry zynqmp_cache_ecc_entry;
0114
0115 rtems_status_code zynqmp_configure_cache_ecc( void )
0116 {
0117 rtems_interrupt_entry_initialize(
0118 &zynqmp_cache_ecc_entry,
0119 cache_handler,
0120 NULL,
0121 "L1/L2 Cache Errors"
0122 );
0123
0124 return rtems_interrupt_entry_install(
0125 ZYNQMP_IRQ_CACHE,
0126 RTEMS_INTERRUPT_SHARED,
0127 &zynqmp_cache_ecc_entry
0128 );
0129 }