File indexing completed on 2025-05-11 08:23:05
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
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 #include <assert.h>
0056 #include <bsp.h>
0057 #include <bsp/fatal.h>
0058 #include <libcpu/arm-cp15.h>
0059 #include <rtems.h>
0060 #include <rtems/score/smpimpl.h>
0061 #include <bsp/arm-release-id.h>
0062 #include <bsp/arm-errata.h>
0063
0064 #include "cache-cp15.h"
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 #define CPU_DATA_CACHE_ALIGNMENT ARM_CACHE_L1_CPU_DATA_ALIGNMENT
0078 #define CPU_INSTRUCTION_CACHE_ALIGNMENT ARM_CACHE_L1_CPU_INSTRUCTION_ALIGNMENT
0079 #if defined(__ARM_ARCH_7A__)
0080
0081 #define CPU_MAXIMAL_CACHE_ALIGNMENT 64
0082 #endif
0083 #define CPU_CACHE_SUPPORT_PROVIDES_RANGE_FUNCTIONS
0084 #define CPU_CACHE_SUPPORT_PROVIDES_CACHE_SIZE_FUNCTIONS
0085
0086 #define L2C_310_DATA_LINE_MASK ( CPU_DATA_CACHE_ALIGNMENT - 1 )
0087 #define L2C_310_INSTRUCTION_LINE_MASK \
0088 ( CPU_INSTRUCTION_CACHE_ALIGNMENT \
0089 - 1 )
0090 #define L2C_310_NUM_WAYS 8
0091 #define L2C_310_WAY_MASK ( ( 1 << L2C_310_NUM_WAYS ) - 1 )
0092
0093 #define L2C_310_MIN( a, b ) \
0094 ((a < b) ? (a) : (b))
0095
0096 #define L2C_310_MAX_LOCKING_BYTES (4 * 1024)
0097
0098
0099
0100 #define L2C_310_RTL_RELEASE_R0_P0 0x0
0101 #define L2C_310_RTL_RELEASE_R1_P0 0x2
0102 #define L2C_310_RTL_RELEASE_R2_P0 0x4
0103 #define L2C_310_RTL_RELEASE_R3_P0 0x5
0104 #define L2C_310_RTL_RELEASE_R3_P1 0x6
0105 #define L2C_310_RTL_RELEASE_R3_P2 0x8
0106 #define L2C_310_RTL_RELEASE_R3_P3 0x9
0107
0108 #define BSP_ARM_L2C_310_RTL_RELEASE (BSP_ARM_L2C_310_ID & L2C_310_ID_RTL_MASK)
0109
0110
0111
0112
0113 typedef struct {
0114
0115 uint32_t cache_id;
0116 #define L2C_310_ID_RTL_MASK 0x3f
0117 #define L2C_310_ID_PART_MASK ( 0xf << 6 )
0118 #define L2C_310_ID_PART_L210 ( 1 << 6 )
0119 #define L2C_310_ID_PART_L310 ( 3 << 6 )
0120 #define L2C_310_ID_IMPL_MASK ( 0xff << 24 )
0121
0122 uint32_t cache_type;
0123
0124 #define L2C_310_TYPE_DATA_BANKING_MASK 0x80000000
0125
0126 #define L2C_310_TYPE_CTYPE_MASK 0x1E000000
0127
0128 #define L2C_310_TYPE_CTYPE_SHIFT 25
0129
0130 #define L2C_310_TYPE_HARVARD_MASK 0x01000000
0131
0132 #define L2C_310_TYPE_SIZE_D_WAYS_MASK 0x00700000
0133 #define L2C_310_TYPE_SIZE_D_WAYS_SHIFT 20
0134
0135 #define L2C_310_TYPE_NUM_D_WAYS_MASK 0x00040000
0136 #define L2C_310_TYPE_NUM_D_WAYS_SHIFT 18
0137
0138 #define L2C_310_TYPE_LENGTH_D_LINE_MASK 0x00003000
0139 #define L2C_310_TYPE_LENGTH_D_LINE_SHIFT 12
0140 #define L2C_310_TYPE_LENGTH_D_LINE_VAL_32 0x0
0141
0142 #define L2C_310_TYPE_SIZE_I_WAYS_MASK 0x00000700
0143 #define L2C_310_TYPE_SIZE_I_WAYS_SHIFT 8
0144
0145 #define L2C_310_TYPE_NUM_I_WAYS_MASK 0x00000040
0146 #define L2C_310_TYPE_NUM_I_WAYS_SHIFT 6
0147
0148 #define L2C_310_TYPE_LENGTH_I_LINE_MASK 0x00000003
0149 #define L2C_310_TYPE_LENGTH_I_LINE_SHIFT 0
0150 #define L2C_310_TYPE_LENGTH_I_LINE_VAL_32 0x0
0151
0152 uint8_t reserved_8[0x100 - 8];
0153 uint32_t ctrl;
0154
0155 #define L2C_310_CTRL_ENABLE 0x00000001
0156
0157 #define L2C_310_CTRL_EXCL_CONFIG (1 << 12)
0158
0159
0160 uint32_t aux_ctrl;
0161
0162
0163 #define L2C_310_AUX_EBRESPE_MASK 0x40000000
0164
0165
0166 #define L2C_310_AUX_IPFE_MASK 0x20000000
0167
0168
0169 #define L2C_310_AUX_DPFE_MASK 0x10000000
0170
0171
0172 #define L2C_310_AUX_NSIC_MASK 0x08000000
0173
0174
0175 #define L2C_310_AUX_NSLE_MASK 0x04000000
0176
0177
0178 #define L2C_310_AUX_CRP_MASK 0x02000000
0179
0180
0181 #define L2C_310_AUX_FWE_MASK 0x01800000
0182
0183
0184 #define L2C_310_AUX_SAOE_MASK 0x00400000
0185
0186
0187 #define L2C_310_AUX_PE_MASK 0x00200000
0188
0189
0190 #define L2C_310_AUX_EMBE_MASK 0x00100000
0191
0192
0193 #define L2C_310_AUX_WAY_SIZE_MASK 0x000E0000
0194 #define L2C_310_AUX_WAY_SIZE_SHIFT 17
0195
0196
0197 #define L2C_310_AUX_ASSOC_MASK 0x00010000
0198
0199
0200 #define L2C_310_AUX_SAIE_MASK 0x00002000
0201
0202
0203 #define L2C_310_AUX_EXCL_CACHE_MASK 0x00001000
0204
0205
0206 #define L2C_310_AUX_SBDLE_MASK 0x00000800
0207
0208
0209 #define L2C_310_AUX_HPSODRE_MASK 0x00000400
0210
0211
0212 #define L2C_310_AUX_FLZE_MASK 0x00000001
0213
0214
0215 #define L2C_310_AUX_REG_DEFAULT_MASK \
0216 ( L2C_310_AUX_WAY_SIZE_MASK & ( 0x3 << L2C_310_AUX_WAY_SIZE_SHIFT ) ) \
0217 | L2C_310_AUX_PE_MASK \
0218 | L2C_310_AUX_SAOE_MASK \
0219 | L2C_310_AUX_CRP_MASK \
0220 | L2C_310_AUX_DPFE_MASK \
0221 | L2C_310_AUX_IPFE_MASK \
0222 | L2C_310_AUX_EBRESPE_MASK
0223
0224 #define L2C_310_AUX_REG_ZERO_MASK 0xFFF1FFFF
0225
0226
0227 #define L2C_310_RAM_1_CYCLE_LAT_VAL 0x00000000
0228
0229 #define L2C_310_RAM_2_CYCLE_LAT_VAL 0x00000001
0230
0231 #define L2C_310_RAM_3_CYCLE_LAT_VAL 0x00000002
0232
0233 #define L2C_310_RAM_4_CYCLE_LAT_VAL 0x00000003
0234
0235 #define L2C_310_RAM_5_CYCLE_LAT_VAL 0x00000004
0236
0237 #define L2C_310_RAM_6_CYCLE_LAT_VAL 0x00000005
0238
0239 #define L2C_310_RAM_7_CYCLE_LAT_VAL 0x00000006
0240
0241 #define L2C_310_RAM_8_CYCLE_LAT_VAL 0x00000007
0242
0243 #define L2C_310_RAM_SETUP_SHIFT 0x00000000
0244
0245 #define L2C_310_RAM_READ_SHIFT 0x00000004
0246
0247 #define L2C_310_RAM_WRITE_SHIFT 0x00000008
0248
0249 #define L2C_310_RAM_SETUP_LAT_MASK 0x00000007
0250
0251 #define L2C_310_RAM_READ_LAT_MASK 0x00000070
0252
0253 #define L2C_310_RAM_WRITE_LAT_MASK 0x00000700
0254
0255 uint32_t tag_ram_ctrl;
0256
0257 #define L2C_310_TAG_RAM_DEFAULT_LAT \
0258 ( ( L2C_310_RAM_2_CYCLE_LAT_VAL << L2C_310_RAM_SETUP_SHIFT ) \
0259 | ( L2C_310_RAM_2_CYCLE_LAT_VAL << L2C_310_RAM_READ_SHIFT ) \
0260 | ( L2C_310_RAM_2_CYCLE_LAT_VAL << L2C_310_RAM_WRITE_SHIFT ) )
0261
0262 uint32_t data_ram_ctrl;
0263
0264 #define L2C_310_DATA_RAM_DEFAULT_MASK \
0265 ( ( L2C_310_RAM_2_CYCLE_LAT_VAL << L2C_310_RAM_SETUP_SHIFT ) \
0266 | ( L2C_310_RAM_3_CYCLE_LAT_VAL << L2C_310_RAM_READ_SHIFT ) \
0267 | ( L2C_310_RAM_2_CYCLE_LAT_VAL << L2C_310_RAM_WRITE_SHIFT ) )
0268
0269 uint8_t reserved_110[0x200 - 0x110];
0270
0271
0272 uint32_t ev_ctrl;
0273
0274
0275 uint32_t ev_cnt1_cfg;
0276
0277
0278 uint32_t ev_cnt0_cfg;
0279
0280
0281 uint32_t ev_cnt1;
0282
0283
0284 uint32_t ev_cnt0;
0285
0286
0287 uint32_t int_mask;
0288
0289
0290 uint32_t int_mask_status;
0291
0292
0293 uint32_t int_raw_status;
0294
0295
0296 uint32_t int_clr;
0297
0298
0299
0300
0301
0302
0303
0304
0305 #define L2C_310_INT_DECERR_MASK 0x00000100
0306
0307
0308 #define L2C_310_INT_SLVERR_MASK 0x00000080
0309
0310
0311 #define L2C_310_INT_ERRRD_MASK 0x00000040
0312
0313
0314 #define L2C_310_INT_ERRRT_MASK 0x00000020
0315
0316
0317 #define L2C_310_INT_ERRWD_MASK 0x00000010
0318
0319
0320 #define L2C_310_INT_ERRWT_MASK 0x00000008
0321
0322
0323 #define L2C_310_INT_PARRD_MASK 0x00000004
0324
0325
0326 #define L2C_310_INT_PARRT_MASK 0x00000002
0327
0328
0329 #define L2C_310_INT_ECNTR_MASK 0x00000001
0330
0331
0332
0333 uint8_t reserved_224[0x730 - 0x224];
0334
0335
0336 uint32_t cache_sync;
0337 uint8_t reserved_734[0x740 - 0x734];
0338
0339 uint32_t dummy_cache_sync_reg;
0340 uint8_t reserved_744[0x770 - 0x744];
0341
0342
0343 uint32_t inv_pa;
0344 uint8_t reserved_774[0x77c - 0x774];
0345
0346
0347 uint32_t inv_way;
0348 uint8_t reserved_780[0x7b0 - 0x780];
0349
0350
0351 uint32_t clean_pa;
0352 uint8_t reserved_7b4[0x7b8 - 0x7b4];
0353
0354
0355 uint32_t clean_index;
0356
0357
0358 uint32_t clean_way;
0359 uint8_t reserved_7c0[0x7f0 - 0x7c0];
0360
0361
0362 uint32_t clean_inv_pa;
0363 uint8_t reserved_7f4[0x7f8 - 0x7f4];
0364
0365
0366 uint32_t clean_inv_indx;
0367
0368
0369 uint32_t clean_inv_way;
0370
0371
0372 uint32_t d_lockdown_0;
0373
0374
0375 uint32_t i_lockdown_0;
0376
0377
0378 uint32_t d_lockdown_1;
0379
0380
0381 uint32_t i_lockdown_1;
0382
0383
0384 uint32_t d_lockdown_2;
0385
0386
0387 uint32_t i_lockdown_2;
0388
0389
0390 uint32_t d_lockdown_3;
0391
0392
0393 uint32_t i_lockdown_3;
0394
0395
0396 uint32_t d_lockdown_4;
0397
0398
0399 uint32_t i_lockdown_4;
0400
0401
0402 uint32_t d_lockdown_5;
0403
0404
0405 uint32_t i_lockdown_5;
0406
0407
0408 uint32_t d_lockdown_6;
0409
0410
0411 uint32_t i_lockdown_6;
0412
0413
0414 uint32_t d_lockdown_7;
0415
0416
0417 uint32_t i_lockdown_7;
0418
0419 uint8_t reserved_940[0x950 - 0x940];
0420
0421
0422 uint32_t lock_line_en;
0423
0424
0425 uint32_t unlock_way;
0426
0427 uint8_t reserved_958[0xc00 - 0x958];
0428
0429
0430 uint32_t addr_filtering_start;
0431
0432
0433 uint32_t addr_filtering_end;
0434
0435
0436 #define L2C_310_ADDR_FILTER_VALID_MASK 0xFFF00000
0437
0438
0439 #define L2C_310_ADDR_FILTER_ENABLE_MASK 0x00000001
0440
0441 uint8_t reserved_c08[0xf40 - 0xc08];
0442
0443
0444 uint32_t debug_ctrl;
0445
0446
0447 #define L2C_310_DEBUG_SPIDEN_MASK 0x00000004
0448
0449
0450 #define L2C_310_DEBUG_DWB_MASK 0x00000002
0451
0452
0453 #define L2C_310_DEBUG_DCL_MASK 0x00000002
0454
0455 uint8_t reserved_f44[0xf60 - 0xf44];
0456
0457
0458 uint32_t prefetch_ctrl;
0459
0460 #define L2C_310_PREFETCH_OFFSET_MASK 0x0000001F
0461 uint8_t reserved_f64[0xf80 - 0xf64];
0462
0463
0464 uint32_t power_ctrl;
0465 } L2CC;
0466
0467 rtems_interrupt_lock l2c_310_lock = RTEMS_INTERRUPT_LOCK_INITIALIZER(
0468 "L2-310 cache controller"
0469 );
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481 #if BSP_ARM_L2C_310_RTL_RELEASE == L2C_310_RTL_RELEASE_R3_P0
0482 #define L2C_310_ERRATA_IS_APPLICABLE_753970
0483 #endif
0484
0485 static bool l2c_310_errata_is_applicable_727913(
0486 uint32_t rtl_release
0487 )
0488 {
0489 bool is_applicable = false;
0490
0491 switch ( rtl_release ) {
0492 case L2C_310_RTL_RELEASE_R3_P3:
0493 case L2C_310_RTL_RELEASE_R3_P2:
0494 case L2C_310_RTL_RELEASE_R3_P1:
0495 case L2C_310_RTL_RELEASE_R2_P0:
0496 case L2C_310_RTL_RELEASE_R1_P0:
0497 case L2C_310_RTL_RELEASE_R0_P0:
0498 is_applicable = false;
0499 break;
0500 case L2C_310_RTL_RELEASE_R3_P0:
0501 is_applicable = true;
0502 break;
0503 default:
0504 assert( 0 );
0505 break;
0506 }
0507
0508 return is_applicable;
0509 }
0510
0511 static bool l2c_310_errata_is_applicable_727914(
0512 uint32_t rtl_release
0513 )
0514 {
0515 bool is_applicable = false;
0516
0517 switch ( rtl_release ) {
0518 case L2C_310_RTL_RELEASE_R3_P3:
0519 case L2C_310_RTL_RELEASE_R3_P2:
0520 case L2C_310_RTL_RELEASE_R3_P1:
0521 case L2C_310_RTL_RELEASE_R2_P0:
0522 case L2C_310_RTL_RELEASE_R1_P0:
0523 case L2C_310_RTL_RELEASE_R0_P0:
0524 is_applicable = false;
0525 break;
0526 case L2C_310_RTL_RELEASE_R3_P0:
0527 is_applicable = true;
0528 break;
0529 default:
0530 assert( 0 );
0531 break;
0532 }
0533
0534 return is_applicable;
0535 }
0536
0537 static bool l2c_310_errata_is_applicable_727915(
0538 uint32_t rtl_release
0539 )
0540 {
0541 bool is_applicable = false;
0542
0543 switch ( rtl_release ) {
0544 case L2C_310_RTL_RELEASE_R3_P3:
0545 case L2C_310_RTL_RELEASE_R3_P2:
0546 case L2C_310_RTL_RELEASE_R3_P1:
0547 case L2C_310_RTL_RELEASE_R1_P0:
0548 case L2C_310_RTL_RELEASE_R0_P0:
0549 is_applicable = false;
0550 break;
0551 case L2C_310_RTL_RELEASE_R3_P0:
0552 case L2C_310_RTL_RELEASE_R2_P0:
0553 is_applicable = true;
0554 break;
0555 default:
0556 assert( 0 );
0557 break;
0558 }
0559
0560 return is_applicable;
0561 }
0562
0563 static bool l2c_310_errata_is_applicable_729806(
0564 uint32_t rtl_release
0565 )
0566 {
0567 bool is_applicable = false;
0568
0569 switch ( rtl_release ) {
0570 case L2C_310_RTL_RELEASE_R3_P3:
0571 case L2C_310_RTL_RELEASE_R3_P2:
0572 case L2C_310_RTL_RELEASE_R2_P0:
0573 case L2C_310_RTL_RELEASE_R1_P0:
0574 case L2C_310_RTL_RELEASE_R0_P0:
0575 is_applicable = false;
0576 break;
0577 case L2C_310_RTL_RELEASE_R3_P1:
0578 case L2C_310_RTL_RELEASE_R3_P0:
0579 is_applicable = true;
0580 break;
0581 default:
0582 assert( 0 );
0583 break;
0584 }
0585
0586 return is_applicable;
0587 }
0588
0589 static bool l2c_310_errata_is_applicable_729815(
0590 uint32_t rtl_release
0591 )
0592 {
0593 bool is_applicable = false;
0594
0595 switch ( rtl_release ) {
0596 case L2C_310_RTL_RELEASE_R3_P3:
0597 case L2C_310_RTL_RELEASE_R1_P0:
0598 case L2C_310_RTL_RELEASE_R0_P0:
0599 is_applicable = false;
0600 break;
0601 case L2C_310_RTL_RELEASE_R3_P2:
0602 case L2C_310_RTL_RELEASE_R3_P1:
0603 case L2C_310_RTL_RELEASE_R3_P0:
0604 case L2C_310_RTL_RELEASE_R2_P0:
0605 is_applicable = true;
0606 break;
0607 default:
0608 assert( 0 );
0609 break;
0610 }
0611
0612 return is_applicable;
0613 }
0614
0615 static bool l2c_310_errata_is_applicable_742884(
0616 uint32_t rtl_release
0617 )
0618 {
0619 bool is_applicable = false;
0620
0621 switch ( rtl_release ) {
0622 case L2C_310_RTL_RELEASE_R3_P3:
0623 case L2C_310_RTL_RELEASE_R3_P2:
0624 case L2C_310_RTL_RELEASE_R3_P0:
0625 case L2C_310_RTL_RELEASE_R2_P0:
0626 case L2C_310_RTL_RELEASE_R1_P0:
0627 case L2C_310_RTL_RELEASE_R0_P0:
0628 is_applicable = false;
0629 break;
0630 case L2C_310_RTL_RELEASE_R3_P1:
0631 is_applicable = true;
0632 break;
0633 default:
0634 assert( 0 );
0635 break;
0636 }
0637
0638 return is_applicable;
0639 }
0640
0641 static bool l2c_310_errata_is_applicable_752271(
0642 uint32_t rtl_release
0643 )
0644 {
0645 bool is_applicable = false;
0646
0647 switch ( rtl_release ) {
0648 case L2C_310_RTL_RELEASE_R3_P3:
0649 case L2C_310_RTL_RELEASE_R3_P2:
0650 case L2C_310_RTL_RELEASE_R2_P0:
0651 case L2C_310_RTL_RELEASE_R1_P0:
0652 case L2C_310_RTL_RELEASE_R0_P0:
0653 is_applicable = false;
0654 break;
0655 case L2C_310_RTL_RELEASE_R3_P1:
0656 case L2C_310_RTL_RELEASE_R3_P0:
0657 is_applicable = true;
0658 break;
0659 default:
0660 assert( 0 );
0661 break;
0662 }
0663
0664 return is_applicable;
0665 }
0666
0667 static bool l2c_310_errata_is_applicable_765569(
0668 uint32_t rtl_release
0669 )
0670 {
0671 bool is_applicable = false;
0672
0673 switch ( rtl_release ) {
0674 case L2C_310_RTL_RELEASE_R3_P3:
0675 case L2C_310_RTL_RELEASE_R3_P2:
0676 case L2C_310_RTL_RELEASE_R3_P1:
0677 case L2C_310_RTL_RELEASE_R3_P0:
0678 case L2C_310_RTL_RELEASE_R2_P0:
0679 case L2C_310_RTL_RELEASE_R1_P0:
0680 case L2C_310_RTL_RELEASE_R0_P0:
0681 is_applicable = true;
0682 break;
0683 default:
0684 assert( 0 );
0685 break;
0686 }
0687
0688 return is_applicable;
0689 }
0690
0691 static bool l2c_310_errata_is_applicable_769419(
0692 uint32_t rtl_release
0693 )
0694 {
0695 bool is_applicable = false;
0696
0697 switch ( rtl_release ) {
0698 case L2C_310_RTL_RELEASE_R3_P3:
0699 case L2C_310_RTL_RELEASE_R3_P2:
0700 is_applicable = false;
0701 break;
0702 case L2C_310_RTL_RELEASE_R3_P1:
0703 case L2C_310_RTL_RELEASE_R3_P0:
0704 case L2C_310_RTL_RELEASE_R2_P0:
0705 case L2C_310_RTL_RELEASE_R1_P0:
0706 case L2C_310_RTL_RELEASE_R0_P0:
0707 is_applicable = true;
0708 break;
0709 default:
0710 assert( 0 );
0711 break;
0712 }
0713
0714 return is_applicable;
0715 }
0716
0717 #if BSP_ARM_L2C_310_RTL_RELEASE == L2C_310_RTL_RELEASE_R0_P0 \
0718 || BSP_ARM_L2C_310_RTL_RELEASE == L2C_310_RTL_RELEASE_R1_P0
0719 #define L2C_310_ERRATA_IS_APPLICABLE_588369
0720 #endif
0721
0722 #ifdef CACHE_ERRATA_CHECKS_FOR_IMPLEMENTED_ERRATAS
0723 static bool l2c_310_errata_is_applicable_754670(
0724 uint32_t rtl_release
0725 )
0726 {
0727 bool is_applicable = false;
0728
0729 switch ( rtl_release ) {
0730 case L2C_310_RTL_RELEASE_R3_P3:
0731 case L2C_310_RTL_RELEASE_R3_P2:
0732 case L2C_310_RTL_RELEASE_R3_P1:
0733 case L2C_310_RTL_RELEASE_R3_P0:
0734 case L2C_310_RTL_RELEASE_R2_P0:
0735 case L2C_310_RTL_RELEASE_R1_P0:
0736 case L2C_310_RTL_RELEASE_R0_P0:
0737 is_applicable = true;
0738 break;
0739 default:
0740 assert( 0 );
0741 break;
0742 }
0743
0744 return is_applicable;
0745 }
0746 #endif
0747
0748
0749
0750
0751
0752 #define CACHE_ARM_ERRATA_775420_HANDLER() \
0753 if( arm_errata_is_applicable_processor_errata_775420 ) { \
0754 } \
0755
0756 static void l2c_310_check_errata( uint32_t rtl_release )
0757 {
0758
0759
0760
0761
0762
0763
0764
0765
0766
0767 assert( ! l2c_310_errata_is_applicable_727913( rtl_release ) );
0768
0769
0770
0771 assert( ! l2c_310_errata_is_applicable_727914( rtl_release ) );
0772
0773
0774
0775 assert( ! l2c_310_errata_is_applicable_727915( rtl_release ) );
0776
0777
0778
0779 assert( ! l2c_310_errata_is_applicable_729806( rtl_release ) );
0780
0781 if( l2c_310_errata_is_applicable_729815( rtl_release ) )
0782 {
0783 volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
0784
0785 assert( 0 == ( l2cc->aux_ctrl & L2C_310_AUX_HPSODRE_MASK ) );
0786
0787
0788
0789
0790
0791
0792
0793
0794
0795
0796
0797
0798
0799
0800
0801
0802 }
0803
0804
0805
0806 assert( ! l2c_310_errata_is_applicable_742884( rtl_release ) );
0807
0808
0809
0810 assert( ! l2c_310_errata_is_applicable_752271( rtl_release ) );
0811
0812
0813
0814
0815
0816
0817 if( l2c_310_errata_is_applicable_765569( rtl_release ) )
0818 {
0819 volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
0820
0821 assert( !( ( l2cc->aux_ctrl & L2C_310_AUX_IPFE_MASK
0822 || l2cc->aux_ctrl & L2C_310_AUX_DPFE_MASK )
0823 && ( ( l2cc->prefetch_ctrl & L2C_310_PREFETCH_OFFSET_MASK )
0824 == 23 ) ) );
0825
0826
0827
0828
0829
0830
0831
0832
0833
0834
0835
0836
0837 }
0838
0839
0840
0841 assert( ! l2c_310_errata_is_applicable_769419( rtl_release ) );
0842 }
0843
0844 static inline void
0845 l2c_310_sync( volatile L2CC *l2cc )
0846 {
0847 #ifdef L2C_310_ERRATA_IS_APPLICABLE_753970
0848 l2cc->dummy_cache_sync_reg = 0;
0849 #else
0850 l2cc->cache_sync = 0;
0851 #endif
0852 }
0853
0854 static inline void
0855 l2c_310_flush_1_line( volatile L2CC *l2cc, uint32_t d_addr )
0856 {
0857 #ifdef L2C_310_ERRATA_IS_APPLICABLE_588369
0858
0859
0860
0861
0862
0863
0864 l2cc->clean_pa = d_addr;
0865 l2c_310_sync( l2cc );
0866 l2cc->inv_pa = d_addr;
0867 #else
0868 l2cc->clean_inv_pa = d_addr;
0869 #endif
0870 }
0871
0872 static inline void
0873 l2c_310_flush_range( const void* d_addr, const size_t n_bytes )
0874 {
0875
0876 uint32_t adx = (uint32_t)d_addr
0877 & ~L2C_310_DATA_LINE_MASK;
0878 const uint32_t ADDR_LAST =
0879 (uint32_t)( (size_t)d_addr + n_bytes - 1 );
0880 volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
0881
0882 if ( n_bytes == 0 ) {
0883 return;
0884 }
0885
0886 for (; adx <= ADDR_LAST; adx += CPU_DATA_CACHE_ALIGNMENT ) {
0887 l2c_310_flush_1_line( l2cc, adx );
0888 }
0889
0890 l2c_310_sync( l2cc );
0891 }
0892
0893 static inline void
0894 l2c_310_flush_entire( void )
0895 {
0896 volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
0897 rtems_interrupt_lock_context lock_context;
0898
0899
0900 if( ( l2cc->ctrl & L2C_310_CTRL_ENABLE ) != 0 ) {
0901
0902
0903 _ARM_Data_memory_barrier();
0904
0905 rtems_interrupt_lock_acquire( &l2c_310_lock, &lock_context );
0906 l2cc->clean_inv_way = L2C_310_WAY_MASK;
0907
0908 while ( l2cc->clean_inv_way & L2C_310_WAY_MASK ) {};
0909
0910
0911 l2c_310_sync( l2cc );
0912
0913 rtems_interrupt_lock_release( &l2c_310_lock, &lock_context );
0914 }
0915 }
0916
0917 static inline void
0918 l2c_310_invalidate_1_line( const void *d_addr )
0919 {
0920 volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
0921
0922
0923 l2cc->inv_pa = (uint32_t) d_addr;
0924 l2c_310_sync( l2cc );
0925 }
0926
0927 static inline void
0928 l2c_310_invalidate_range( const void* d_addr, const size_t n_bytes )
0929 {
0930
0931 uint32_t adx = (uint32_t)d_addr
0932 & ~L2C_310_DATA_LINE_MASK;
0933 const uint32_t ADDR_LAST =
0934 (uint32_t)( (size_t)d_addr + n_bytes - 1 );
0935 volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
0936
0937 if ( n_bytes == 0 ) {
0938 return;
0939 }
0940
0941 for (; adx <= ADDR_LAST; adx += CPU_DATA_CACHE_ALIGNMENT ) {
0942
0943 l2cc->inv_pa = adx;
0944 }
0945
0946 l2c_310_sync( l2cc );
0947 }
0948
0949
0950 static inline void
0951 l2c_310_invalidate_entire( void )
0952 {
0953 volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
0954
0955
0956
0957
0958 _ARM_Data_memory_barrier();
0959
0960 l2cc->inv_way = L2C_310_WAY_MASK;
0961
0962 while ( l2cc->inv_way & L2C_310_WAY_MASK ) ;
0963
0964
0965 l2c_310_sync( l2cc );
0966 }
0967
0968 static inline void
0969 l2c_310_clean_and_invalidate_entire( void )
0970 {
0971 volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
0972 rtems_interrupt_lock_context lock_context;
0973
0974 if( ( l2cc->ctrl & L2C_310_CTRL_ENABLE ) != 0 ) {
0975
0976
0977
0978 _ARM_Data_memory_barrier();
0979
0980 rtems_interrupt_lock_acquire( &l2c_310_lock, &lock_context );
0981 l2cc->clean_inv_way = L2C_310_WAY_MASK;
0982
0983 while ( l2cc->clean_inv_way & L2C_310_WAY_MASK ) ;
0984
0985
0986 l2c_310_sync( l2cc );
0987
0988 rtems_interrupt_lock_release( &l2c_310_lock, &lock_context );
0989 }
0990 }
0991
0992 static inline void
0993 l2c_310_freeze( void )
0994 {
0995
0996
0997 }
0998
0999 static inline void
1000 l2c_310_unfreeze( void )
1001 {
1002
1003
1004 }
1005
1006 static inline size_t
1007 l2c_310_get_cache_size( void )
1008 {
1009 size_t size = 0;
1010 volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
1011 uint32_t cache_type = l2cc->cache_type;
1012 uint32_t way_size;
1013 uint32_t num_ways;
1014
1015 way_size = (cache_type & L2C_310_TYPE_SIZE_D_WAYS_MASK)
1016 >> L2C_310_TYPE_SIZE_D_WAYS_SHIFT;
1017 num_ways = (cache_type & L2C_310_TYPE_NUM_D_WAYS_MASK)
1018 >> L2C_310_TYPE_NUM_D_WAYS_SHIFT;
1019
1020 assert( way_size <= 0x07 );
1021 assert( num_ways <= 0x01 );
1022 if( way_size <= 0x07 && num_ways <= 0x01 ) {
1023 if( way_size == 0x00 ) {
1024 way_size = 16 * 1024;
1025 } else if( way_size == 0x07 ) {
1026 way_size = 512 * 1024;
1027 } else {
1028 way_size = (1 << (way_size - 1)) * 16 * 1024;
1029 }
1030 switch( num_ways ) {
1031 case 0:
1032 num_ways = 8;
1033 break;
1034 case 1:
1035 num_ways = 16;
1036 break;
1037 default:
1038 num_ways = 0;
1039 break;
1040 }
1041 size = way_size * num_ways;
1042 }
1043 return size;
1044 }
1045
1046 static void l2c_310_unlock( volatile L2CC *l2cc )
1047 {
1048 l2cc->d_lockdown_0 = 0;
1049 l2cc->i_lockdown_0 = 0;
1050 l2cc->d_lockdown_1 = 0;
1051 l2cc->i_lockdown_1 = 0;
1052 l2cc->d_lockdown_2 = 0;
1053 l2cc->i_lockdown_2 = 0;
1054 l2cc->d_lockdown_3 = 0;
1055 l2cc->i_lockdown_3 = 0;
1056 l2cc->d_lockdown_4 = 0;
1057 l2cc->i_lockdown_4 = 0;
1058 l2cc->d_lockdown_5 = 0;
1059 l2cc->i_lockdown_5 = 0;
1060 l2cc->d_lockdown_6 = 0;
1061 l2cc->i_lockdown_6 = 0;
1062 l2cc->d_lockdown_7 = 0;
1063 l2cc->i_lockdown_7 = 0;
1064 }
1065
1066 static void l2c_310_wait_for_background_ops( volatile L2CC *l2cc )
1067 {
1068 while ( l2cc->inv_way & L2C_310_WAY_MASK ) ;
1069
1070 while ( l2cc->clean_way & L2C_310_WAY_MASK ) ;
1071
1072 while ( l2cc->clean_inv_way & L2C_310_WAY_MASK ) ;
1073 }
1074
1075
1076
1077 #if (BSP_ARM_L2C_310_ID & L2C_310_ID_PART_MASK) \
1078 != L2C_310_ID_PART_L310
1079 #error "invalid L2-310 cache controller part number"
1080 #endif
1081
1082 #if (BSP_ARM_L2C_310_RTL_RELEASE != L2C_310_RTL_RELEASE_R3_P2) \
1083 && (BSP_ARM_L2C_310_RTL_RELEASE != L2C_310_RTL_RELEASE_R3_P3)
1084 #error "invalid L2-310 cache controller RTL revision"
1085 #endif
1086
1087 static inline void
1088 l2c_310_enable( void )
1089 {
1090 volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
1091 uint32_t cache_id = l2cc->cache_id;
1092 uint32_t rtl_release = cache_id & L2C_310_ID_RTL_MASK;
1093 uint32_t id_mask = L2C_310_ID_IMPL_MASK | L2C_310_ID_PART_MASK;
1094 uint32_t ctrl;
1095
1096
1097
1098
1099
1100 if (
1101 (BSP_ARM_L2C_310_ID & id_mask) != (cache_id & id_mask)
1102 || rtl_release < BSP_ARM_L2C_310_RTL_RELEASE
1103 ) {
1104 bsp_fatal( ARM_FATAL_L2C_310_UNEXPECTED_ID );
1105 }
1106
1107 l2c_310_check_errata( rtl_release );
1108
1109 ctrl = l2cc->ctrl;
1110
1111 if ( ( ctrl & L2C_310_CTRL_EXCL_CONFIG ) != 0 ) {
1112 bsp_fatal( ARM_FATAL_L2C_310_EXCLUSIVE_CONFIG );
1113 }
1114
1115
1116 if( ( ctrl & L2C_310_CTRL_ENABLE ) == 0 ) {
1117 uint32_t aux_ctrl;
1118 int ways;
1119
1120
1121 l2c_310_unlock( l2cc );
1122
1123 l2c_310_wait_for_background_ops( l2cc );
1124
1125 aux_ctrl = l2cc->aux_ctrl;
1126
1127 if ( (aux_ctrl & ( 1 << 16 )) != 0 ) {
1128 ways = 16;
1129 } else {
1130 ways = 8;
1131 }
1132
1133 if ( ways != L2C_310_NUM_WAYS ) {
1134 bsp_fatal( ARM_FATAL_L2C_310_UNEXPECTED_NUM_WAYS );
1135 }
1136
1137
1138 aux_ctrl &= L2C_310_AUX_REG_ZERO_MASK;
1139 aux_ctrl |= L2C_310_AUX_REG_DEFAULT_MASK;
1140
1141 l2cc->aux_ctrl = aux_ctrl;
1142
1143
1144 l2cc->tag_ram_ctrl = L2C_310_TAG_RAM_DEFAULT_LAT;
1145 l2cc->data_ram_ctrl = L2C_310_DATA_RAM_DEFAULT_MASK;
1146
1147 l2c_310_invalidate_entire();
1148
1149
1150 l2cc->int_clr = l2cc->int_raw_status;
1151
1152
1153 l2cc->ctrl = ctrl | L2C_310_CTRL_ENABLE;
1154 }
1155 }
1156
1157 static inline void
1158 _CPU_cache_enable_data( void )
1159 {
1160 l2c_310_enable();
1161 }
1162
1163 static inline void
1164 _CPU_cache_disable_data( void )
1165 {
1166 _Internal_error( INTERNAL_ERROR_CANNOT_DISABLE_DATA_CACHE );
1167 }
1168
1169 static void l2c_310_enable_instruction( void *arg )
1170 {
1171 rtems_interrupt_level level;
1172
1173 (void) arg;
1174
1175 rtems_interrupt_local_disable(level);
1176 arm_cp15_set_control( arm_cp15_get_control() | ARM_CP15_CTRL_I );
1177 rtems_interrupt_local_enable(level);
1178 }
1179
1180 static inline void
1181 _CPU_cache_enable_instruction( void )
1182 {
1183 #ifdef RTEMS_SMP
1184 rtems_interrupt_level level;
1185
1186 rtems_interrupt_local_disable( level );
1187 _SMP_Broadcast_action( l2c_310_enable_instruction, NULL );
1188 rtems_interrupt_local_enable( level );
1189 #else
1190 l2c_310_enable_instruction( NULL );
1191 #endif
1192 }
1193
1194 static void l2c_310_disable_instruction( void *arg )
1195 {
1196 rtems_interrupt_level level;
1197
1198 (void) arg;
1199
1200 rtems_interrupt_local_disable(level);
1201 arm_cp15_set_control( arm_cp15_get_control() & ~ARM_CP15_CTRL_I );
1202 rtems_interrupt_local_enable(level);
1203
1204 arm_cache_l1_invalidate_entire_instruction();
1205 }
1206
1207 static inline void
1208 _CPU_cache_disable_instruction( void )
1209 {
1210 l2c_310_flush_entire();
1211
1212 #ifdef RTEMS_SMP
1213 rtems_interrupt_level level;
1214
1215 rtems_interrupt_local_disable( level );
1216 _SMP_Broadcast_action( l2c_310_disable_instruction, NULL );
1217 rtems_interrupt_local_enable( level );
1218 #else
1219 l2c_310_disable_instruction( NULL );
1220 #endif
1221 }
1222
1223 static inline void
1224 _CPU_cache_flush_data_range(
1225 const void *d_addr,
1226 size_t n_bytes
1227 )
1228 {
1229 arm_cache_l1_flush_data_range(
1230 d_addr,
1231 n_bytes
1232 );
1233 l2c_310_flush_range(
1234 d_addr,
1235 n_bytes
1236 );
1237 }
1238
1239 static inline void
1240 _CPU_cache_flush_entire_data( void )
1241 {
1242 arm_cache_l1_flush_entire_data();
1243 l2c_310_flush_entire();
1244 }
1245
1246 static inline void
1247 _CPU_cache_invalidate_data_range(
1248 const void *addr_first,
1249 size_t n_bytes
1250 )
1251 {
1252 l2c_310_invalidate_range(
1253 addr_first,
1254 n_bytes
1255 );
1256 arm_cache_l1_invalidate_data_range(
1257 addr_first,
1258 n_bytes
1259 );
1260 }
1261
1262 static inline void
1263 _CPU_cache_invalidate_entire_data( void )
1264 {
1265
1266 arm_cache_l1_flush_entire_data();
1267
1268
1269 l2c_310_clean_and_invalidate_entire();
1270
1271
1272 arm_cache_l1_clean_and_invalidate_entire_data();
1273 }
1274
1275 static inline void
1276 _CPU_cache_freeze_data( void )
1277 {
1278 arm_cache_l1_freeze_data();
1279 l2c_310_freeze();
1280 }
1281
1282 static inline void
1283 _CPU_cache_unfreeze_data( void )
1284 {
1285 arm_cache_l1_unfreeze_data();
1286 l2c_310_unfreeze();
1287 }
1288
1289 static inline void
1290 _CPU_cache_invalidate_instruction_range( const void *i_addr, size_t n_bytes)
1291 {
1292 arm_cache_l1_invalidate_instruction_range( i_addr, n_bytes );
1293 }
1294
1295 static inline void
1296 _CPU_cache_invalidate_entire_instruction( void )
1297 {
1298 arm_cache_l1_invalidate_entire_instruction();
1299 }
1300
1301 static inline void
1302 _CPU_cache_freeze_instruction( void )
1303 {
1304 arm_cache_l1_freeze_instruction();
1305 l2c_310_freeze();
1306 }
1307
1308 static inline void
1309 _CPU_cache_unfreeze_instruction( void )
1310 {
1311 arm_cache_l1_unfreeze_instruction();
1312 l2c_310_unfreeze();
1313 }
1314
1315 static inline size_t
1316 _CPU_cache_get_data_cache_size( const uint32_t level )
1317 {
1318 size_t size = 0;
1319
1320 switch( level )
1321 {
1322 case 1:
1323 size = arm_cache_l1_get_data_cache_size();
1324 break;
1325 case 0:
1326 case 2:
1327 size = l2c_310_get_cache_size();
1328 break;
1329 default:
1330 size = 0;
1331 break;
1332 }
1333 return size;
1334 }
1335
1336 static inline size_t
1337 _CPU_cache_get_instruction_cache_size( const uint32_t level )
1338 {
1339 size_t size = 0;
1340
1341 switch( level )
1342 {
1343 case 1:
1344 size = arm_cache_l1_get_instruction_cache_size();
1345 break;
1346 case 0:
1347 case 2:
1348 size = l2c_310_get_cache_size();
1349 break;
1350 default:
1351 size = 0;
1352 break;
1353 }
1354 return size;
1355 }
1356
1357
1358
1359 #include "../../shared/cache/cacheimpl.h"