memprot.c
1 // Copyright 2020 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 /* INTERNAL API 16 * implementation of generic interface to MMU memory protection features 17 */ 18 19 #include <stdio.h> 20 #include "sdkconfig.h" 21 #include "soc/sensitive_reg.h" 22 #include "soc/dport_access.h" 23 #include "soc/periph_defs.h" 24 #include "esp_intr_alloc.h" 25 26 #include "esp_log.h" 27 static const char *TAG = "memprot"; 28 29 #include "esp32s2/memprot.h" 30 #include "hal/memprot_ll.h" 31 #include "hal/memprot_peri_ll.h" 32 #include "esp_fault.h" 33 34 #include "soc/cpu.h" 35 36 extern int _iram_text_end; 37 extern int _data_start; 38 extern int _rtc_text_end; 39 extern int _rtc_dummy_end; 40 41 42 uint32_t *esp_memprot_iram0_sram_get_min_split_addr(void) 43 { 44 return (uint32_t *)&_iram_text_end; 45 } 46 47 uint32_t *esp_memprot_iram0_rtcfast_get_min_split_addr(void) 48 { 49 return (uint32_t *)&_rtc_text_end; 50 } 51 52 uint32_t *esp_memprot_dram0_sram_get_min_split_addr(void) 53 { 54 return (uint32_t *)&_data_start; 55 } 56 57 uint32_t *esp_memprot_dram0_rtcfast_get_min_split_addr(void) 58 { 59 return (uint32_t *)&_rtc_dummy_end; 60 } 61 62 uint32_t *esp_memprot_peri1_rtcslow_get_min_split_addr(void) 63 { 64 return (uint32_t *)(PERI1_RTCSLOW_ADDRESS_BASE); 65 } 66 67 uint32_t *esp_memprot_peri2_rtcslow_0_get_min_split_addr(void) 68 { 69 return (uint32_t *)(PERI2_RTCSLOW_0_ADDRESS_BASE); 70 } 71 72 uint32_t *esp_memprot_peri2_rtcslow_1_get_min_split_addr(void) 73 { 74 return (uint32_t *)(PERI2_RTCSLOW_1_ADDRESS_BASE); 75 } 76 77 uint32_t *esp_memprot_get_split_addr(mem_type_prot_t mem_type) 78 { 79 switch (mem_type) { 80 case MEMPROT_IRAM0_SRAM: 81 return esp_memprot_iram0_sram_get_min_split_addr(); 82 case MEMPROT_DRAM0_SRAM: 83 return esp_memprot_dram0_sram_get_min_split_addr(); 84 case MEMPROT_IRAM0_RTCFAST: 85 return esp_memprot_iram0_rtcfast_get_min_split_addr(); 86 case MEMPROT_DRAM0_RTCFAST: 87 return esp_memprot_dram0_rtcfast_get_min_split_addr(); 88 case MEMPROT_PERI1_RTCSLOW: 89 return esp_memprot_peri1_rtcslow_get_min_split_addr(); 90 case MEMPROT_PERI2_RTCSLOW_0: 91 return esp_memprot_peri2_rtcslow_0_get_min_split_addr(); 92 case MEMPROT_PERI2_RTCSLOW_1: 93 return esp_memprot_peri2_rtcslow_1_get_min_split_addr(); 94 default: 95 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 96 abort(); 97 } 98 } 99 100 const char *esp_memprot_type_to_str(mem_type_prot_t mem_type) 101 { 102 switch (mem_type) { 103 case MEMPROT_IRAM0_SRAM: 104 return "IRAM0_SRAM"; 105 case MEMPROT_DRAM0_SRAM: 106 return "DRAM0_SRAM"; 107 case MEMPROT_IRAM0_RTCFAST: 108 return "IRAM0_RTCFAST"; 109 case MEMPROT_DRAM0_RTCFAST: 110 return "DRAM0_RTCFAST"; 111 case MEMPROT_PERI1_RTCSLOW: 112 return "PERI1_RTCSLOW"; 113 case MEMPROT_PERI2_RTCSLOW_0: 114 return "PERI2_RTCSLOW_0"; 115 case MEMPROT_PERI2_RTCSLOW_1: 116 return "PERI2_RTCSLOW_1"; 117 default: 118 return "UNKOWN"; 119 } 120 } 121 122 void esp_memprot_intr_init(mem_type_prot_t mem_type) 123 { 124 ESP_INTR_DISABLE(ETS_MEMACCESS_ERR_INUM); 125 126 switch (mem_type) { 127 case MEMPROT_IRAM0_SRAM: 128 case MEMPROT_IRAM0_RTCFAST: 129 intr_matrix_set(PRO_CPU_NUM, esp_memprot_iram0_get_intr_source_num(), ETS_MEMACCESS_ERR_INUM); 130 break; 131 case MEMPROT_DRAM0_SRAM: 132 case MEMPROT_DRAM0_RTCFAST: 133 intr_matrix_set(PRO_CPU_NUM, esp_memprot_dram0_get_intr_source_num(), ETS_MEMACCESS_ERR_INUM); 134 break; 135 case MEMPROT_PERI1_RTCSLOW: 136 intr_matrix_set(PRO_CPU_NUM, esp_memprot_peri1_get_intr_source_num(), ETS_MEMACCESS_ERR_INUM); 137 break; 138 case MEMPROT_PERI2_RTCSLOW_0: 139 case MEMPROT_PERI2_RTCSLOW_1: 140 intr_matrix_set(PRO_CPU_NUM, esp_memprot_peri2_get_intr_source_num(), ETS_MEMACCESS_ERR_INUM); 141 break; 142 default: 143 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 144 abort(); 145 } 146 147 ESP_INTR_ENABLE(ETS_MEMACCESS_ERR_INUM); 148 } 149 150 void esp_memprot_intr_ena(mem_type_prot_t mem_type, bool enable) 151 { 152 switch (mem_type) { 153 case MEMPROT_IRAM0_SRAM: 154 case MEMPROT_IRAM0_RTCFAST: 155 esp_memprot_iram0_intr_ena(enable); 156 break; 157 case MEMPROT_DRAM0_SRAM: 158 case MEMPROT_DRAM0_RTCFAST: 159 esp_memprot_dram0_intr_ena(enable); 160 break; 161 case MEMPROT_PERI1_RTCSLOW: 162 esp_memprot_peri1_intr_ena(enable); 163 break; 164 case MEMPROT_PERI2_RTCSLOW_0: 165 case MEMPROT_PERI2_RTCSLOW_1: 166 esp_memprot_peri2_intr_ena(enable); 167 break; 168 default: 169 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 170 abort(); 171 } 172 } 173 174 mem_type_prot_t esp_memprot_get_active_intr_memtype() 175 { 176 if (esp_memprot_iram0_sram_is_intr_mine()) { 177 return MEMPROT_IRAM0_SRAM; 178 } else if (esp_memprot_iram0_rtcfast_is_intr_mine()) { 179 return MEMPROT_IRAM0_RTCFAST; 180 } else if (esp_memprot_dram0_sram_is_intr_mine()) { 181 return MEMPROT_DRAM0_SRAM; 182 } else if (esp_memprot_dram0_rtcfast_is_intr_mine()) { 183 return MEMPROT_DRAM0_RTCFAST; 184 } else if (esp_memprot_peri1_rtcslow_is_intr_mine()) { 185 return MEMPROT_PERI1_RTCSLOW; 186 } else if (esp_memprot_peri2_rtcslow_0_is_intr_mine()) { 187 return MEMPROT_PERI2_RTCSLOW_0; 188 } else if (esp_memprot_peri2_rtcslow_1_is_intr_mine()) { 189 return MEMPROT_PERI2_RTCSLOW_1; 190 } 191 192 return MEMPROT_NONE; 193 } 194 195 void esp_memprot_clear_intr(mem_type_prot_t mem_type) 196 { 197 switch (mem_type) { 198 case MEMPROT_IRAM0_SRAM: 199 case MEMPROT_IRAM0_RTCFAST: 200 esp_memprot_iram0_clear_intr(); 201 break; 202 case MEMPROT_DRAM0_SRAM: 203 case MEMPROT_DRAM0_RTCFAST: 204 esp_memprot_dram0_clear_intr(); 205 break; 206 case MEMPROT_PERI1_RTCSLOW: 207 esp_memprot_peri1_clear_intr(); 208 break; 209 case MEMPROT_PERI2_RTCSLOW_0: 210 case MEMPROT_PERI2_RTCSLOW_1: 211 esp_memprot_peri2_clear_intr(); 212 break; 213 default: 214 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 215 abort(); 216 } 217 } 218 219 void esp_memprot_set_lock(mem_type_prot_t mem_type) 220 { 221 switch (mem_type) { 222 case MEMPROT_IRAM0_SRAM: 223 case MEMPROT_IRAM0_RTCFAST: 224 esp_memprot_iram0_set_lock(); 225 break; 226 case MEMPROT_DRAM0_SRAM: 227 case MEMPROT_DRAM0_RTCFAST: 228 esp_memprot_dram0_set_lock(); 229 break; 230 case MEMPROT_PERI1_RTCSLOW: 231 esp_memprot_peri1_set_lock(); 232 break; 233 case MEMPROT_PERI2_RTCSLOW_0: 234 case MEMPROT_PERI2_RTCSLOW_1: 235 esp_memprot_peri2_set_lock(); 236 break; 237 default: 238 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 239 abort(); 240 } 241 } 242 243 bool esp_memprot_get_lock(mem_type_prot_t mem_type) 244 { 245 switch (mem_type) { 246 case MEMPROT_IRAM0_SRAM: 247 case MEMPROT_IRAM0_RTCFAST: 248 return esp_memprot_iram0_get_lock_bit() > 0; 249 case MEMPROT_DRAM0_SRAM: 250 case MEMPROT_DRAM0_RTCFAST: 251 return esp_memprot_dram0_get_lock_bit() > 0; 252 case MEMPROT_PERI1_RTCSLOW: 253 return esp_memprot_peri1_get_lock_bit() > 0; 254 case MEMPROT_PERI2_RTCSLOW_0: 255 case MEMPROT_PERI2_RTCSLOW_1: 256 return esp_memprot_peri2_get_lock_bit() > 0; 257 default: 258 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 259 abort(); 260 } 261 } 262 263 bool esp_memprot_is_locked_any() 264 { 265 return 266 esp_memprot_iram0_get_lock_bit() > 0 || 267 esp_memprot_dram0_get_lock_bit() > 0 || 268 esp_memprot_peri1_get_lock_bit() > 0 || 269 esp_memprot_peri2_get_lock_bit() > 0; 270 } 271 272 uint32_t esp_memprot_get_lock_bit(mem_type_prot_t mem_type) 273 { 274 switch (mem_type) { 275 case MEMPROT_IRAM0_SRAM: 276 case MEMPROT_IRAM0_RTCFAST: 277 return esp_memprot_iram0_get_lock_bit(); 278 case MEMPROT_DRAM0_SRAM: 279 case MEMPROT_DRAM0_RTCFAST: 280 return esp_memprot_dram0_get_lock_bit(); 281 case MEMPROT_PERI1_RTCSLOW: 282 return esp_memprot_peri1_get_lock_bit(); 283 case MEMPROT_PERI2_RTCSLOW_0: 284 case MEMPROT_PERI2_RTCSLOW_1: 285 return esp_memprot_peri2_get_lock_bit(); 286 default: 287 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 288 abort(); 289 } 290 } 291 292 uint32_t esp_memprot_get_conf_reg(mem_type_prot_t mem_type) 293 { 294 switch (mem_type) { 295 case MEMPROT_IRAM0_SRAM: 296 case MEMPROT_IRAM0_RTCFAST: 297 return esp_memprot_iram0_get_conf_reg(); 298 case MEMPROT_DRAM0_SRAM: 299 case MEMPROT_DRAM0_RTCFAST: 300 return esp_memprot_dram0_get_conf_reg(); 301 case MEMPROT_PERI1_RTCSLOW: 302 return esp_memprot_peri1_rtcslow_get_conf_reg(); 303 case MEMPROT_PERI2_RTCSLOW_0: 304 return esp_memprot_peri2_rtcslow_0_get_conf_reg(); 305 case MEMPROT_PERI2_RTCSLOW_1: 306 return esp_memprot_peri2_rtcslow_1_get_conf_reg(); 307 default: 308 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 309 abort(); 310 } 311 } 312 313 uint32_t esp_memprot_get_fault_reg(mem_type_prot_t mem_type) 314 { 315 switch (mem_type) { 316 case MEMPROT_IRAM0_SRAM: 317 case MEMPROT_IRAM0_RTCFAST: 318 return esp_memprot_iram0_get_fault_reg(); 319 case MEMPROT_DRAM0_SRAM: 320 case MEMPROT_DRAM0_RTCFAST: 321 return esp_memprot_dram0_get_fault_reg(); 322 case MEMPROT_PERI1_RTCSLOW: 323 return esp_memprot_peri1_get_fault_reg(); 324 case MEMPROT_PERI2_RTCSLOW_0: 325 case MEMPROT_PERI2_RTCSLOW_1: 326 return esp_memprot_peri2_get_fault_reg(); 327 default: 328 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 329 abort(); 330 } 331 } 332 333 void esp_memprot_get_fault_status(mem_type_prot_t mem_type, uint32_t **faulting_address, uint32_t *op_type, uint32_t *op_subtype) 334 { 335 switch (mem_type) { 336 case MEMPROT_IRAM0_SRAM: 337 *faulting_address = esp_memprot_iram0_sram_get_fault_address(); 338 break; 339 case MEMPROT_IRAM0_RTCFAST: 340 *faulting_address = esp_memprot_iram0_rtcfast_get_fault_address(); 341 break; 342 case MEMPROT_DRAM0_SRAM: 343 *faulting_address = esp_memprot_dram0_sram_get_fault_address(); 344 break; 345 case MEMPROT_DRAM0_RTCFAST: 346 *faulting_address = esp_memprot_dram0_rtcfast_get_fault_address(); 347 break; 348 case MEMPROT_PERI1_RTCSLOW: 349 *faulting_address = esp_memprot_peri1_rtcslow_get_fault_address(); 350 break; 351 case MEMPROT_PERI2_RTCSLOW_0: 352 case MEMPROT_PERI2_RTCSLOW_1: 353 *faulting_address = esp_memprot_peri2_rtcslow_get_fault_address(); 354 break; 355 default: 356 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 357 abort(); 358 } 359 360 if (mem_type == MEMPROT_IRAM0_SRAM || mem_type == MEMPROT_IRAM0_RTCFAST) { 361 esp_memprot_iram0_get_fault_op_type(op_type, op_subtype); 362 } else if (mem_type == MEMPROT_DRAM0_SRAM || mem_type == MEMPROT_DRAM0_RTCFAST) { 363 esp_memprot_dram0_get_fault_op_type(op_type, op_subtype); 364 } else if (mem_type == MEMPROT_PERI1_RTCSLOW) { 365 esp_memprot_peri1_get_fault_op_type(op_type, op_subtype); 366 } else if (mem_type == MEMPROT_PERI2_RTCSLOW_0 || mem_type == MEMPROT_PERI2_RTCSLOW_1) { 367 esp_memprot_peri2_get_fault_op_type(op_type, op_subtype); 368 } 369 } 370 371 bool esp_memprot_is_intr_ena_any() 372 { 373 return 374 esp_memprot_iram0_get_intr_ena_bit() > 0 || 375 esp_memprot_dram0_get_intr_ena_bit() > 0 || 376 esp_memprot_peri1_get_intr_ena_bit() > 0 || 377 esp_memprot_peri2_get_intr_ena_bit() > 0; 378 } 379 380 uint32_t esp_memprot_get_intr_ena_bit(mem_type_prot_t mem_type) 381 { 382 switch (mem_type) { 383 case MEMPROT_IRAM0_SRAM: 384 case MEMPROT_IRAM0_RTCFAST: 385 return esp_memprot_iram0_get_intr_ena_bit(); 386 case MEMPROT_DRAM0_SRAM: 387 case MEMPROT_DRAM0_RTCFAST: 388 return esp_memprot_dram0_get_intr_ena_bit(); 389 case MEMPROT_PERI1_RTCSLOW: 390 return esp_memprot_peri1_get_intr_ena_bit(); 391 case MEMPROT_PERI2_RTCSLOW_0: 392 case MEMPROT_PERI2_RTCSLOW_1: 393 return esp_memprot_peri2_get_intr_ena_bit(); 394 default: 395 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 396 abort(); 397 } 398 } 399 400 uint32_t esp_memprot_get_intr_on_bit(mem_type_prot_t mem_type) 401 { 402 switch (mem_type) { 403 case MEMPROT_IRAM0_SRAM: 404 case MEMPROT_IRAM0_RTCFAST: 405 return esp_memprot_iram0_get_intr_on_bit(); 406 case MEMPROT_DRAM0_SRAM: 407 case MEMPROT_DRAM0_RTCFAST: 408 return esp_memprot_dram0_get_intr_on_bit(); 409 case MEMPROT_PERI1_RTCSLOW: 410 return esp_memprot_peri1_get_intr_on_bit(); 411 case MEMPROT_PERI2_RTCSLOW_0: 412 case MEMPROT_PERI2_RTCSLOW_1: 413 return esp_memprot_peri2_get_intr_on_bit(); 414 default: 415 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 416 abort(); 417 } 418 } 419 420 uint32_t esp_memprot_get_intr_clr_bit(mem_type_prot_t mem_type) 421 { 422 switch (mem_type) { 423 case MEMPROT_IRAM0_SRAM: 424 case MEMPROT_IRAM0_RTCFAST: 425 return esp_memprot_iram0_get_intr_clr_bit(); 426 case MEMPROT_DRAM0_SRAM: 427 case MEMPROT_DRAM0_RTCFAST: 428 return esp_memprot_dram0_get_intr_clr_bit(); 429 case MEMPROT_PERI1_RTCSLOW: 430 return esp_memprot_peri1_get_intr_clr_bit(); 431 case MEMPROT_PERI2_RTCSLOW_0: 432 case MEMPROT_PERI2_RTCSLOW_1: 433 return esp_memprot_peri2_get_intr_clr_bit(); 434 default: 435 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 436 abort(); 437 } 438 } 439 440 uint32_t esp_memprot_get_uni_block_read_bit(mem_type_prot_t mem_type, uint32_t block) 441 { 442 switch (mem_type) { 443 case MEMPROT_IRAM0_SRAM: 444 return esp_memprot_iram0_sram_get_uni_block_read_bit(block); 445 case MEMPROT_DRAM0_SRAM: 446 return esp_memprot_dram0_sram_get_uni_block_read_bit(block); 447 default: 448 ESP_LOGE(TAG, "Invalid mem_type %d (unified block management not supported)", mem_type); 449 abort(); 450 } 451 } 452 453 uint32_t esp_memprot_get_uni_block_write_bit(mem_type_prot_t mem_type, uint32_t block) 454 { 455 switch (mem_type) { 456 case MEMPROT_IRAM0_SRAM: 457 return esp_memprot_iram0_sram_get_uni_block_write_bit(block); 458 case MEMPROT_DRAM0_SRAM: 459 return esp_memprot_dram0_sram_get_uni_block_write_bit(block); 460 default: 461 ESP_LOGE(TAG, "Invalid mem_type %d (unified block management not supported)", mem_type); 462 abort(); 463 } 464 } 465 466 uint32_t esp_memprot_get_uni_block_exec_bit(mem_type_prot_t mem_type, uint32_t block) 467 { 468 switch (mem_type) { 469 case MEMPROT_IRAM0_SRAM: 470 return esp_memprot_iram0_sram_get_uni_block_exec_bit(block); 471 default: 472 ESP_LOGE(TAG, "Invalid mem_type %d (unified block management not supported)", mem_type); 473 abort(); 474 } 475 } 476 477 void esp_memprot_set_uni_block_perm_dram(mem_type_prot_t mem_type, uint32_t block, bool write_perm, bool read_perm) 478 { 479 switch (mem_type) { 480 case MEMPROT_DRAM0_SRAM: 481 esp_memprot_dram0_sram_set_uni_block_perm(block, write_perm, read_perm); 482 break; 483 default: 484 ESP_LOGE(TAG, "Invalid mem_type %d (unified block management not supported)", mem_type); 485 abort(); 486 } 487 } 488 489 uint32_t esp_memprot_get_perm_uni_reg(mem_type_prot_t mem_type) 490 { 491 switch (mem_type) { 492 case MEMPROT_IRAM0_SRAM: 493 return esp_memprot_iram0_sram_get_perm_uni_reg(); 494 case MEMPROT_DRAM0_SRAM: 495 return esp_memprot_dram0_sram_get_perm_reg(); 496 default: 497 ESP_LOGE(TAG, "Invalid mem_type %d (unified block management not supported)", mem_type); 498 abort(); 499 } 500 } 501 502 uint32_t esp_memprot_get_perm_split_reg(mem_type_prot_t mem_type) 503 { 504 switch (mem_type) { 505 case MEMPROT_IRAM0_SRAM: 506 return esp_memprot_iram0_sram_get_perm_split_reg(); 507 case MEMPROT_IRAM0_RTCFAST: 508 return esp_memprot_iram0_rtcfast_get_perm_split_reg(); 509 case MEMPROT_DRAM0_SRAM: 510 return esp_memprot_dram0_sram_get_perm_reg(); 511 case MEMPROT_DRAM0_RTCFAST: 512 return esp_memprot_dram0_rtcfast_get_perm_split_reg(); 513 case MEMPROT_PERI1_RTCSLOW: 514 return esp_memprot_peri1_rtcslow_get_conf_reg(); 515 case MEMPROT_PERI2_RTCSLOW_0: 516 return esp_memprot_peri2_rtcslow_0_get_conf_reg(); 517 case MEMPROT_PERI2_RTCSLOW_1: 518 return esp_memprot_peri2_rtcslow_1_get_conf_reg(); 519 default: 520 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 521 abort(); 522 } 523 } 524 525 void esp_memprot_set_prot_dram(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool hw, bool hr) 526 { 527 switch (mem_type) { 528 case MEMPROT_DRAM0_SRAM: 529 esp_memprot_dram0_sram_set_prot(split_addr != NULL ? split_addr : esp_memprot_dram0_sram_get_min_split_addr(), lw, lr, hw, hr); 530 break; 531 case MEMPROT_DRAM0_RTCFAST: 532 esp_memprot_dram0_rtcfast_set_prot(split_addr != NULL ? split_addr : esp_memprot_dram0_rtcfast_get_min_split_addr(), lw, lr, hw, hr); 533 break; 534 default: 535 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 536 abort(); 537 } 538 } 539 540 void esp_memprot_set_uni_block_perm_iram(mem_type_prot_t mem_type, uint32_t block, bool write_perm, bool read_perm, bool exec_perm) 541 { 542 switch (mem_type) { 543 case MEMPROT_IRAM0_SRAM: 544 esp_memprot_iram0_sram_set_uni_block_perm(block, write_perm, read_perm, exec_perm); 545 break; 546 default: 547 ESP_LOGE(TAG, "Invalid mem_type %d (unified block management not supported)", mem_type); 548 abort(); 549 } 550 } 551 552 void esp_memprot_set_prot_iram(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool lx, bool hw, bool hr, bool hx) 553 { 554 switch (mem_type) { 555 case MEMPROT_IRAM0_SRAM: 556 esp_memprot_iram0_sram_set_prot(split_addr != NULL ? split_addr : esp_memprot_iram0_sram_get_min_split_addr(), lw, lr, lx, hw, hr, hx); 557 break; 558 case MEMPROT_IRAM0_RTCFAST: 559 esp_memprot_iram0_rtcfast_set_prot(split_addr != NULL ? split_addr : esp_memprot_iram0_rtcfast_get_min_split_addr(), lw, lr, lx, hw, hr, hx); 560 break; 561 default: 562 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 563 abort(); 564 } 565 } 566 567 void esp_memprot_get_perm_split_bits_iram(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *lx, bool *hw, bool *hr, bool *hx) 568 { 569 switch (mem_type) { 570 case MEMPROT_IRAM0_SRAM: 571 esp_memprot_iram0_sram_get_split_sgnf_bits(lw, lr, lx, hw, hr, hx); 572 break; 573 case MEMPROT_IRAM0_RTCFAST: 574 esp_memprot_iram0_rtcfast_get_split_sgnf_bits(lw, lr, lx, hw, hr, hx); 575 break; 576 default: 577 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 578 abort(); 579 } 580 } 581 582 void esp_memprot_get_perm_split_bits_dram(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *hw, bool *hr) 583 { 584 switch (mem_type) { 585 case MEMPROT_DRAM0_SRAM: 586 esp_memprot_dram0_sram_get_split_sgnf_bits(lw, lr, hw, hr); 587 break; 588 case MEMPROT_DRAM0_RTCFAST: 589 esp_memprot_dram0_rtcfast_get_split_sgnf_bits(lw, lr, hw, hr); 590 break; 591 default: 592 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 593 abort(); 594 } 595 } 596 597 void esp_memprot_get_perm_split_bits_peri1(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *hw, bool *hr) 598 { 599 switch (mem_type) { 600 case MEMPROT_PERI1_RTCSLOW: 601 esp_memprot_peri1_rtcslow_get_split_sgnf_bits(lw, lr, hw, hr); 602 break; 603 default: 604 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 605 abort(); 606 } 607 } 608 609 void esp_memprot_set_prot_peri1(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool hw, bool hr) 610 { 611 switch (mem_type) { 612 case MEMPROT_PERI1_RTCSLOW: 613 esp_memprot_peri1_rtcslow_set_prot(split_addr != NULL ? split_addr : esp_memprot_peri1_rtcslow_get_min_split_addr(), lw, lr, hw, hr); 614 break; 615 default: 616 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 617 abort(); 618 } 619 } 620 621 void esp_memprot_get_perm_split_bits_peri2(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *lx, bool *hw, bool *hr, bool *hx) 622 { 623 switch (mem_type) { 624 case MEMPROT_PERI2_RTCSLOW_0: 625 esp_memprot_peri2_rtcslow_0_get_split_sgnf_bits(lw, lr, lx, hw, hr, hx); 626 break; 627 case MEMPROT_PERI2_RTCSLOW_1: 628 esp_memprot_peri2_rtcslow_1_get_split_sgnf_bits(lw, lr, lx, hw, hr, hx); 629 break; 630 default: 631 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 632 abort(); 633 } 634 } 635 636 void esp_memprot_set_prot_peri2(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool lx, bool hw, bool hr, bool hx) 637 { 638 switch (mem_type) { 639 case MEMPROT_PERI2_RTCSLOW_0: 640 esp_memprot_peri2_rtcslow_0_set_prot(split_addr != NULL ? split_addr : esp_memprot_peri2_rtcslow_0_get_min_split_addr(), lw, lr, lx, hw, hr, hx); 641 break; 642 case MEMPROT_PERI2_RTCSLOW_1: 643 esp_memprot_peri2_rtcslow_1_set_prot(split_addr != NULL ? split_addr : esp_memprot_peri2_rtcslow_1_get_min_split_addr(), lw, lr, lx, hw, hr, hx); 644 break; 645 default: 646 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 647 abort(); 648 } 649 } 650 651 void esp_memprot_set_prot(bool invoke_panic_handler, bool lock_feature, uint32_t *mem_type_mask) 652 { 653 //any IRAM0/DRAM0 enable/disable call applies to all memory modules connected 654 uint32_t required_mem_prot = mem_type_mask == NULL ? (uint32_t)MEMPROT_ALL : *mem_type_mask; 655 bool use_iram0 = required_mem_prot & MEMPROT_IRAM0_SRAM || required_mem_prot & MEMPROT_IRAM0_RTCFAST; 656 bool use_dram0 = required_mem_prot & MEMPROT_DRAM0_SRAM || required_mem_prot & MEMPROT_DRAM0_RTCFAST; 657 bool use_peri1 = required_mem_prot & MEMPROT_PERI1_RTCSLOW; 658 bool use_peri2 = required_mem_prot & MEMPROT_PERI2_RTCSLOW_0 || required_mem_prot & MEMPROT_PERI2_RTCSLOW_1; 659 660 //disable protection 661 if (use_iram0) { 662 esp_memprot_intr_ena(MEMPROT_IRAM0_SRAM, false); 663 } 664 if (use_dram0) { 665 esp_memprot_intr_ena(MEMPROT_DRAM0_SRAM, false); 666 } 667 if (use_peri1) { 668 esp_memprot_intr_ena(MEMPROT_PERI1_RTCSLOW, false); 669 } 670 if (use_peri2) { 671 esp_memprot_intr_ena(MEMPROT_PERI2_RTCSLOW_0, false); 672 } 673 674 //connect to intr. matrix if not being debugged 675 if (!esp_cpu_in_ocd_debug_mode()) { 676 677 ESP_FAULT_ASSERT(!esp_cpu_in_ocd_debug_mode()); 678 679 //initialize for specific buses (any memory type does the job) 680 if (invoke_panic_handler) { 681 if (use_iram0) { 682 esp_memprot_intr_init(MEMPROT_IRAM0_SRAM); 683 } 684 if (use_dram0) { 685 esp_memprot_intr_init(MEMPROT_DRAM0_SRAM); 686 } 687 if (use_peri1) { 688 esp_memprot_intr_init(MEMPROT_PERI1_RTCSLOW); 689 } 690 if (use_peri2) { 691 esp_memprot_intr_init(MEMPROT_PERI2_RTCSLOW_0); 692 } 693 } 694 695 //set permissions 696 if (required_mem_prot & MEMPROT_IRAM0_SRAM) { 697 esp_memprot_set_prot_iram(MEMPROT_IRAM0_SRAM, NULL, false, true, true, true, true, true); 698 } 699 if (required_mem_prot & MEMPROT_IRAM0_RTCFAST) { 700 esp_memprot_set_prot_iram(MEMPROT_IRAM0_RTCFAST, NULL, false, true, true, true, true, true); 701 } 702 if (required_mem_prot & MEMPROT_DRAM0_SRAM) { 703 esp_memprot_set_prot_dram(MEMPROT_DRAM0_SRAM, NULL, false, true, true, true); 704 } 705 if (required_mem_prot & MEMPROT_DRAM0_RTCFAST) { 706 esp_memprot_set_prot_dram(MEMPROT_DRAM0_RTCFAST, NULL, false, true, true, true); 707 } 708 if (required_mem_prot & MEMPROT_PERI1_RTCSLOW) { 709 esp_memprot_set_prot_peri1(MEMPROT_PERI1_RTCSLOW, NULL, true, true, true, true); 710 } 711 if (required_mem_prot & MEMPROT_PERI2_RTCSLOW_0) { 712 esp_memprot_set_prot_peri2(MEMPROT_PERI2_RTCSLOW_0, NULL, true, true, false, true, true, false); 713 } 714 if (required_mem_prot & MEMPROT_PERI2_RTCSLOW_1) { 715 esp_memprot_set_prot_peri2(MEMPROT_PERI2_RTCSLOW_1, NULL, true, true, false, true, true, false); 716 } 717 718 //reenable protection (bus based) 719 if (use_iram0) { 720 esp_memprot_intr_ena(MEMPROT_IRAM0_SRAM, true); 721 } 722 if (use_dram0) { 723 esp_memprot_intr_ena(MEMPROT_DRAM0_SRAM, true); 724 } 725 if (use_peri1) { 726 esp_memprot_intr_ena(MEMPROT_PERI1_RTCSLOW, true); 727 } 728 if (use_peri2) { 729 esp_memprot_intr_ena(MEMPROT_PERI2_RTCSLOW_0, true); 730 } 731 732 //lock if required (bus based) 733 if (lock_feature) { 734 if (use_iram0) { 735 esp_memprot_set_lock(MEMPROT_IRAM0_SRAM); 736 } 737 if (use_dram0) { 738 esp_memprot_set_lock(MEMPROT_DRAM0_SRAM); 739 } 740 if (use_peri1) { 741 esp_memprot_set_lock(MEMPROT_PERI1_RTCSLOW); 742 } 743 if (use_peri2) { 744 esp_memprot_set_lock(MEMPROT_PERI2_RTCSLOW_0); 745 } 746 } 747 } 748 } 749 750 void esp_memprot_get_permissions(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *lx, bool *hw, bool *hr, bool *hx) 751 { 752 switch (mem_type) { 753 case MEMPROT_IRAM0_SRAM: 754 esp_memprot_iram0_sram_get_split_sgnf_bits(lw, lr, lx, hw, hr, hx); 755 break; 756 case MEMPROT_DRAM0_SRAM: 757 esp_memprot_dram0_sram_get_split_sgnf_bits(lw, lr, hw, hr); 758 break; 759 case MEMPROT_IRAM0_RTCFAST: 760 esp_memprot_iram0_rtcfast_get_split_sgnf_bits(lw, lr, lx, hw, hr, hx); 761 break; 762 case MEMPROT_DRAM0_RTCFAST: 763 esp_memprot_dram0_rtcfast_get_split_sgnf_bits(lw, lr, hw, hr); 764 break; 765 case MEMPROT_PERI1_RTCSLOW: 766 esp_memprot_peri1_rtcslow_get_split_sgnf_bits(lw, lr, hw, hr); 767 break; 768 case MEMPROT_PERI2_RTCSLOW_0: 769 esp_memprot_peri2_rtcslow_0_get_split_sgnf_bits(lw, lr, lx, hw, hr, hx); 770 break; 771 case MEMPROT_PERI2_RTCSLOW_1: 772 esp_memprot_peri2_rtcslow_1_get_split_sgnf_bits(lw, lr, lx, hw, hr, hx); 773 break; 774 default: 775 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 776 abort(); 777 } 778 } 779 780 void esp_memprot_get_perm_read(mem_type_prot_t mem_type, bool *lr, bool *hr) 781 { 782 bool _lw, _lr, _lx, _hw, _hr, _hx; 783 esp_memprot_get_permissions(mem_type, &_lw, &_lr, &_lx, &_hw, &_hr, &_hx); 784 *lr = _lr; 785 *hr = _hr; 786 } 787 788 void esp_memprot_get_perm_write(mem_type_prot_t mem_type, bool *lw, bool *hw) 789 { 790 bool _lw, _lr, _lx, _hw, _hr, _hx; 791 esp_memprot_get_permissions(mem_type, &_lw, &_lr, &_lx, &_hw, &_hr, &_hx); 792 *lw = _lw; 793 *hw = _hw; 794 } 795 796 void esp_memprot_get_perm_exec(mem_type_prot_t mem_type, bool *lx, bool *hx) 797 { 798 if ( mem_type == MEMPROT_DRAM0_SRAM || 799 mem_type == MEMPROT_DRAM0_RTCFAST || 800 mem_type == MEMPROT_PERI1_RTCSLOW ) { 801 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 802 abort(); 803 } 804 805 bool _lw, _lr, _lx, _hw, _hr, _hx; 806 esp_memprot_get_permissions(mem_type, &_lw, &_lr, &_lx, &_hw, &_hr, &_hx); 807 *lx = _lx; 808 *hx = _hx; 809 } 810 811 uint32_t esp_memprot_get_low_limit(mem_type_prot_t mem_type) 812 { 813 switch (mem_type) { 814 case MEMPROT_IRAM0_SRAM: 815 return IRAM0_SRAM_ADDRESS_LOW; 816 case MEMPROT_DRAM0_SRAM: 817 return DRAM0_SRAM_ADDRESS_LOW; 818 case MEMPROT_IRAM0_RTCFAST: 819 return IRAM0_RTCFAST_ADDRESS_LOW; 820 case MEMPROT_DRAM0_RTCFAST: 821 return DRAM0_RTCFAST_ADDRESS_LOW; 822 case MEMPROT_PERI1_RTCSLOW: 823 return PERI1_RTCSLOW_ADDRESS_LOW; 824 case MEMPROT_PERI2_RTCSLOW_0: 825 return PERI2_RTCSLOW_0_ADDRESS_LOW; 826 case MEMPROT_PERI2_RTCSLOW_1: 827 return PERI2_RTCSLOW_1_ADDRESS_LOW; 828 default: 829 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 830 abort(); 831 } 832 } 833 834 uint32_t esp_memprot_get_high_limit(mem_type_prot_t mem_type) 835 { 836 switch (mem_type) { 837 case MEMPROT_IRAM0_SRAM: 838 return IRAM0_SRAM_ADDRESS_HIGH; 839 case MEMPROT_DRAM0_SRAM: 840 return DRAM0_SRAM_ADDRESS_HIGH; 841 case MEMPROT_IRAM0_RTCFAST: 842 return IRAM0_RTCFAST_ADDRESS_HIGH; 843 case MEMPROT_DRAM0_RTCFAST: 844 return DRAM0_RTCFAST_ADDRESS_HIGH; 845 case MEMPROT_PERI1_RTCSLOW: 846 return PERI1_RTCSLOW_ADDRESS_HIGH; 847 case MEMPROT_PERI2_RTCSLOW_0: 848 return PERI2_RTCSLOW_0_ADDRESS_HIGH; 849 case MEMPROT_PERI2_RTCSLOW_1: 850 return PERI2_RTCSLOW_1_ADDRESS_HIGH; 851 default: 852 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 853 abort(); 854 } 855 } 856 857 void esp_memprot_set_read_perm(mem_type_prot_t mem_type, bool lr, bool hr) 858 { 859 switch (mem_type) { 860 case MEMPROT_IRAM0_SRAM: 861 esp_memprot_iram0_sram_set_read_perm(lr, hr); 862 break; 863 case MEMPROT_DRAM0_SRAM: 864 esp_memprot_dram0_sram_set_read_perm(lr, hr); 865 break; 866 case MEMPROT_IRAM0_RTCFAST: 867 esp_memprot_iram0_rtcfast_set_read_perm(lr, hr); 868 break; 869 case MEMPROT_DRAM0_RTCFAST: 870 esp_memprot_dram0_rtcfast_set_read_perm(lr, hr); 871 break; 872 case MEMPROT_PERI1_RTCSLOW: 873 esp_memprot_peri1_rtcslow_set_read_perm(lr, hr); 874 break; 875 case MEMPROT_PERI2_RTCSLOW_0: 876 esp_memprot_peri2_rtcslow_0_set_read_perm(lr, hr); 877 break; 878 case MEMPROT_PERI2_RTCSLOW_1: 879 esp_memprot_peri2_rtcslow_1_set_read_perm(lr, hr); 880 break; 881 default: 882 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 883 abort(); 884 } 885 } 886 887 void esp_memprot_set_write_perm(mem_type_prot_t mem_type, bool lw, bool hw) 888 { 889 switch (mem_type) { 890 case MEMPROT_IRAM0_SRAM: 891 esp_memprot_iram0_sram_set_write_perm(lw, hw); 892 break; 893 case MEMPROT_DRAM0_SRAM: 894 esp_memprot_dram0_sram_set_write_perm(lw, hw); 895 break; 896 case MEMPROT_IRAM0_RTCFAST: 897 esp_memprot_iram0_rtcfast_set_write_perm(lw, hw); 898 break; 899 case MEMPROT_DRAM0_RTCFAST: 900 esp_memprot_dram0_rtcfast_set_write_perm(lw, hw); 901 break; 902 case MEMPROT_PERI1_RTCSLOW: 903 esp_memprot_peri1_rtcslow_set_write_perm(lw, hw); 904 break; 905 case MEMPROT_PERI2_RTCSLOW_0: 906 esp_memprot_peri2_rtcslow_0_set_write_perm(lw, hw); 907 break; 908 case MEMPROT_PERI2_RTCSLOW_1: 909 esp_memprot_peri2_rtcslow_1_set_write_perm(lw, hw); 910 break; 911 default: 912 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 913 abort(); 914 } 915 } 916 917 void esp_memprot_set_exec_perm(mem_type_prot_t mem_type, bool lx, bool hx) 918 { 919 switch (mem_type) { 920 case MEMPROT_IRAM0_SRAM: 921 esp_memprot_iram0_sram_set_exec_perm(lx, hx); 922 break; 923 case MEMPROT_IRAM0_RTCFAST: 924 esp_memprot_iram0_rtcfast_set_exec_perm(lx, hx); 925 break; 926 case MEMPROT_PERI2_RTCSLOW_0: 927 esp_memprot_peri2_rtcslow_0_set_exec_perm(lx, hx); 928 break; 929 case MEMPROT_PERI2_RTCSLOW_1: 930 esp_memprot_peri2_rtcslow_1_set_exec_perm(lx, hx); 931 break; 932 default: 933 ESP_LOGE(TAG, "Invalid mem_type %d", mem_type); 934 abort(); 935 } 936 }