/ components / esp32s2 / cache_err_int.c
cache_err_int.c
 1  // Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
 2  //
 3  // Licensed under the Apache License, Version 2.0 (the "License");
 4  // you may not use this file except in compliance with the License.
 5  // You may obtain a copy of the License at
 6  //
 7  //     http://www.apache.org/licenses/LICENSE-2.0
 8  //
 9  // Unless required by applicable law or agreed to in writing, software
10  // distributed under the License is distributed on an "AS IS" BASIS,
11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  // See the License for the specific language governing permissions and
13  // limitations under the License.
14  
15  /*
16   The cache has an interrupt that can be raised as soon as an access to a cached
17   region (flash, psram) is done without the cache being enabled. We use that here
18   to panic the CPU, which from a debugging perspective is better than grabbing bad
19   data from the bus.
20  */
21  
22  #include <stdint.h>
23  #include <stdio.h>
24  #include <stdlib.h>
25  #include <stdbool.h>
26  
27  #include "esp_err.h"
28  #include "esp_attr.h"
29  
30  #include "esp_intr_alloc.h"
31  
32  #include "soc/extmem_reg.h"
33  #include "soc/dport_reg.h"
34  #include "soc/periph_defs.h"
35  #include "hal/cpu_hal.h"
36  
37  #include "esp32s2/dport_access.h"
38  #include "esp32s2/rom/ets_sys.h"  // for intr_matrix_set
39  
40  #include "sdkconfig.h"
41  
42  void esp_cache_err_int_init(void)
43  {
44      uint32_t core_id = cpu_hal_get_core_id();
45      ESP_INTR_DISABLE(ETS_MEMACCESS_ERR_INUM);
46  
47      // We do not register a handler for the interrupt because it is interrupt
48      // level 4 which is not serviceable from C. Instead, xtensa_vectors.S has
49      // a call to the panic handler for
50      // this interrupt.
51      intr_matrix_set(core_id, ETS_CACHE_IA_INTR_SOURCE, ETS_MEMACCESS_ERR_INUM);
52  
53      // Enable invalid cache access interrupt when the cache is disabled.
54      // The status bits are cleared first, in case we are restarting after
55      // a cache error has triggered.
56      DPORT_SET_PERI_REG_MASK(EXTMEM_CACHE_DBG_INT_CLR_REG,
57                              EXTMEM_MMU_ENTRY_FAULT_INT_CLR |
58                              EXTMEM_DCACHE_REJECT_INT_CLR |
59                              EXTMEM_DCACHE_WRITE_FLASH_INT_CLR |
60                              EXTMEM_DC_PRELOAD_SIZE_FAULT_INT_CLR |
61                              EXTMEM_DC_SYNC_SIZE_FAULT_INT_CLR |
62                              EXTMEM_ICACHE_REJECT_INT_CLR |
63                              EXTMEM_IC_PRELOAD_SIZE_FAULT_INT_CLR |
64                              EXTMEM_IC_SYNC_SIZE_FAULT_INT_CLR);
65      DPORT_SET_PERI_REG_MASK(EXTMEM_CACHE_DBG_INT_ENA_REG,
66                              EXTMEM_MMU_ENTRY_FAULT_INT_ENA |
67                              EXTMEM_DCACHE_REJECT_INT_ENA |
68                              EXTMEM_DCACHE_WRITE_FLASH_INT_ENA |
69                              EXTMEM_DC_PRELOAD_SIZE_FAULT_INT_ENA |
70                              EXTMEM_DC_SYNC_SIZE_FAULT_INT_ENA |
71                              EXTMEM_ICACHE_REJECT_INT_ENA |
72                              EXTMEM_IC_PRELOAD_SIZE_FAULT_INT_ENA |
73                              EXTMEM_IC_SYNC_SIZE_FAULT_INT_ENA |
74                              EXTMEM_CACHE_DBG_EN);
75  
76      ESP_INTR_ENABLE(ETS_MEMACCESS_ERR_INUM);
77  }
78  
79  int IRAM_ATTR esp_cache_err_get_cpuid(void)
80  {
81      if (REG_READ(EXTMEM_CACHE_DBG_STATUS0_REG) != 0 ||
82          REG_READ(EXTMEM_CACHE_DBG_STATUS1_REG) != 0) {
83              return PRO_CPU_NUM;
84      }
85      return -1;
86  }