1 /*
2  * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /*
8  The cache has an interrupt that can be raised as soon as an access to a cached
9  region (flash, psram) is done without the cache being enabled. We use that here
10  to panic the CPU, which from a debugging perspective is better than grabbing bad
11  data from the bus.
12 */
13 
14 #include <stdint.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <stdbool.h>
18 
19 #include "esp_err.h"
20 #include "esp_attr.h"
21 #include "esp_cpu.h"
22 
23 #include "esp_intr_alloc.h"
24 
25 #include "soc/extmem_reg.h"
26 #include "soc/dport_reg.h"
27 #include "soc/periph_defs.h"
28 
29 #include "esp_rom_sys.h"
30 
31 #include "sdkconfig.h"
32 
esp_cache_err_int_init(void)33 void esp_cache_err_int_init(void)
34 {
35     uint32_t core_id = esp_cpu_get_core_id();
36     ESP_INTR_DISABLE(ETS_MEMACCESS_ERR_INUM);
37 
38     // We do not register a handler for the interrupt because it is interrupt
39     // level 4 which is not serviceable from C. Instead, xtensa_vectors.S has
40     // a call to the panic handler for
41     // this interrupt.
42     esp_rom_route_intr_matrix(core_id, ETS_CACHE_IA_INTR_SOURCE, ETS_MEMACCESS_ERR_INUM);
43 
44     // Enable invalid cache access interrupt when the cache is disabled.
45     // The status bits are cleared first, in case we are restarting after
46     // a cache error has triggered.
47     DPORT_SET_PERI_REG_MASK(EXTMEM_CACHE_DBG_INT_CLR_REG,
48                             EXTMEM_MMU_ENTRY_FAULT_INT_CLR |
49                             EXTMEM_DCACHE_REJECT_INT_CLR |
50                             EXTMEM_DCACHE_WRITE_FLASH_INT_CLR |
51                             EXTMEM_DC_PRELOAD_SIZE_FAULT_INT_CLR |
52                             EXTMEM_DC_SYNC_SIZE_FAULT_INT_CLR |
53                             EXTMEM_ICACHE_REJECT_INT_CLR |
54                             EXTMEM_IC_PRELOAD_SIZE_FAULT_INT_CLR |
55                             EXTMEM_IC_SYNC_SIZE_FAULT_INT_CLR);
56     DPORT_SET_PERI_REG_MASK(EXTMEM_CACHE_DBG_INT_ENA_REG,
57                             EXTMEM_MMU_ENTRY_FAULT_INT_ENA |
58                             EXTMEM_DCACHE_REJECT_INT_ENA |
59                             EXTMEM_DCACHE_WRITE_FLASH_INT_ENA |
60                             EXTMEM_DC_PRELOAD_SIZE_FAULT_INT_ENA |
61                             EXTMEM_DC_SYNC_SIZE_FAULT_INT_ENA |
62                             EXTMEM_ICACHE_REJECT_INT_ENA |
63                             EXTMEM_IC_PRELOAD_SIZE_FAULT_INT_ENA |
64                             EXTMEM_IC_SYNC_SIZE_FAULT_INT_ENA |
65                             EXTMEM_CACHE_DBG_EN);
66 
67     ESP_INTR_ENABLE(ETS_MEMACCESS_ERR_INUM);
68 }
69 
esp_cache_err_get_cpuid(void)70 int esp_cache_err_get_cpuid(void)
71 {
72     if (REG_READ(EXTMEM_CACHE_DBG_STATUS0_REG) != 0 ||
73         REG_READ(EXTMEM_CACHE_DBG_STATUS1_REG) != 0) {
74             return PRO_CPU_NUM;
75     }
76     return -1;
77 }
78