1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2017-2024, STMicroelectronics 4 * Copyright (c) 2016-2018, Linaro Limited 5 */ 6 7 #include <boot_api.h> 8 #include <config.h> 9 #include <console.h> 10 #include <drivers/gic.h> 11 #include <drivers/pinctrl.h> 12 #include <drivers/stm32_bsec.h> 13 #include <drivers/stm32_etzpc.h> 14 #include <drivers/stm32_gpio.h> 15 #include <drivers/stm32_iwdg.h> 16 #include <drivers/stm32_tamp.h> 17 #include <drivers/stm32_uart.h> 18 #include <drivers/stm32mp_dt_bindings.h> 19 #ifdef CFG_STM32MP15 20 #include <drivers/stm32mp1_rcc.h> 21 #endif 22 #include <io.h> 23 #include <kernel/boot.h> 24 #include <kernel/dt.h> 25 #include <kernel/misc.h> 26 #include <kernel/panic.h> 27 #include <kernel/spinlock.h> 28 #include <kernel/tee_misc.h> 29 #include <libfdt.h> 30 #include <mm/core_memprot.h> 31 #include <platform_config.h> 32 #include <sm/psci.h> 33 #include <stm32_util.h> 34 #include <string.h> 35 #include <trace.h> 36 37 register_phys_mem_pgdir(MEM_AREA_IO_NSEC, APB1_BASE, APB1_SIZE); 38 register_phys_mem_pgdir(MEM_AREA_IO_NSEC, APB2_BASE, APB2_SIZE); 39 register_phys_mem_pgdir(MEM_AREA_IO_NSEC, APB3_BASE, APB3_SIZE); 40 register_phys_mem_pgdir(MEM_AREA_IO_NSEC, APB4_BASE, APB4_SIZE); 41 register_phys_mem_pgdir(MEM_AREA_IO_NSEC, APB5_BASE, APB5_SIZE); 42 register_phys_mem_pgdir(MEM_AREA_IO_NSEC, AHB4_BASE, AHB4_SIZE); 43 register_phys_mem_pgdir(MEM_AREA_IO_NSEC, AHB5_BASE, AHB5_SIZE); 44 45 register_phys_mem_pgdir(MEM_AREA_IO_SEC, APB1_BASE, APB1_SIZE); 46 register_phys_mem_pgdir(MEM_AREA_IO_SEC, APB3_BASE, APB3_SIZE); 47 register_phys_mem_pgdir(MEM_AREA_IO_SEC, APB4_BASE, APB4_SIZE); 48 register_phys_mem_pgdir(MEM_AREA_IO_SEC, APB5_BASE, APB5_SIZE); 49 #ifdef CFG_STM32MP13 50 register_phys_mem_pgdir(MEM_AREA_IO_SEC, APB6_BASE, APB6_SIZE); 51 #endif 52 register_phys_mem_pgdir(MEM_AREA_IO_SEC, AHB4_BASE, AHB4_SIZE); 53 register_phys_mem_pgdir(MEM_AREA_IO_SEC, AHB5_BASE, AHB5_SIZE); 54 register_phys_mem_pgdir(MEM_AREA_IO_SEC, GIC_BASE, GIC_SIZE); 55 56 register_ddr(DDR_BASE, CFG_DRAM_SIZE); 57 58 #define _ID2STR(id) (#id) 59 #define ID2STR(id) _ID2STR(id) 60 61 static TEE_Result platform_banner(void) 62 { 63 IMSG("Platform stm32mp1: flavor %s - DT %s", 64 ID2STR(PLATFORM_FLAVOR), 65 ID2STR(CFG_EMBED_DTB_SOURCE_FILE)); 66 67 return TEE_SUCCESS; 68 } 69 service_init(platform_banner); 70 71 /* 72 * Console 73 * 74 * CFG_STM32_EARLY_CONSOLE_UART specifies the ID of the UART used for 75 * trace console. Value 0 disables the early console. 76 * 77 * We cannot use the generic serial_console support since probing 78 * the console requires the platform clock driver to be already 79 * up and ready which is done only once service_init are completed. 80 */ 81 static struct stm32_uart_pdata console_data; 82 83 void plat_console_init(void) 84 { 85 /* Early console initialization before MMU setup */ 86 struct uart { 87 paddr_t pa; 88 bool secure; 89 } uarts[] = { 90 [0] = { .pa = 0 }, 91 [1] = { .pa = USART1_BASE, .secure = true, }, 92 [2] = { .pa = USART2_BASE, .secure = false, }, 93 [3] = { .pa = USART3_BASE, .secure = false, }, 94 [4] = { .pa = UART4_BASE, .secure = false, }, 95 [5] = { .pa = UART5_BASE, .secure = false, }, 96 [6] = { .pa = USART6_BASE, .secure = false, }, 97 [7] = { .pa = UART7_BASE, .secure = false, }, 98 [8] = { .pa = UART8_BASE, .secure = false, }, 99 }; 100 101 COMPILE_TIME_ASSERT(ARRAY_SIZE(uarts) > CFG_STM32_EARLY_CONSOLE_UART); 102 103 if (!uarts[CFG_STM32_EARLY_CONSOLE_UART].pa) 104 return; 105 106 /* No clock yet bound to the UART console */ 107 console_data.clock = NULL; 108 109 console_data.secure = uarts[CFG_STM32_EARLY_CONSOLE_UART].secure; 110 stm32_uart_init(&console_data, uarts[CFG_STM32_EARLY_CONSOLE_UART].pa); 111 112 register_serial_console(&console_data.chip); 113 114 IMSG("Early console on UART#%u", CFG_STM32_EARLY_CONSOLE_UART); 115 } 116 117 static TEE_Result init_console_from_dt(void) 118 { 119 struct stm32_uart_pdata *pd = NULL; 120 void *fdt = NULL; 121 int node = 0; 122 TEE_Result res = TEE_ERROR_GENERIC; 123 124 fdt = get_embedded_dt(); 125 res = get_console_node_from_dt(fdt, &node, NULL, NULL); 126 if (res == TEE_ERROR_ITEM_NOT_FOUND) { 127 fdt = get_external_dt(); 128 res = get_console_node_from_dt(fdt, &node, NULL, NULL); 129 if (res == TEE_ERROR_ITEM_NOT_FOUND) 130 return TEE_SUCCESS; 131 if (res != TEE_SUCCESS) 132 return res; 133 } 134 135 pd = stm32_uart_init_from_dt_node(fdt, node); 136 if (!pd) { 137 IMSG("DTB disables console"); 138 register_serial_console(NULL); 139 return TEE_SUCCESS; 140 } 141 142 /* Replace early console with the new one */ 143 console_flush(); 144 console_data = *pd; 145 register_serial_console(&console_data.chip); 146 IMSG("DTB enables console (%ssecure)", pd->secure ? "" : "non-"); 147 free(pd); 148 149 return TEE_SUCCESS; 150 } 151 152 /* Probe console from DT once clock inits (service init level) are completed */ 153 service_init_late(init_console_from_dt); 154 155 /* 156 * GIC init, used also for primary/secondary boot core wake completion 157 */ 158 void boot_primary_init_intc(void) 159 { 160 gic_init(GIC_BASE + GICC_OFFSET, GIC_BASE + GICD_OFFSET); 161 162 stm32mp_register_online_cpu(); 163 } 164 165 void boot_secondary_init_intc(void) 166 { 167 gic_init_per_cpu(); 168 169 stm32mp_register_online_cpu(); 170 } 171 172 #ifdef CFG_STM32MP15 173 /* 174 * This concerns OP-TEE pager for STM32MP1 to use secure internal 175 * RAMs to execute. TZSRAM refers the TZSRAM_BASE/TZSRAM_SIZE 176 * used in boot.c to locate secure unpaged memory. 177 * 178 * STM32MP15 variants embed 640kB of contiguous securable SRAMs 179 * 180 * +--------------+ <-- SYSRAM_BASE 181 * | | lower part can be assigned to secure world 182 * | SYSRAM 256kB | 4kB granule boundary 183 * | | upper part can be assigned to secure world 184 * +--------------+ <-- SRAM1_BASE (= SYSRAM_BASE + SYSRAM_SIZE) 185 | | full range assigned to non-secure world or 186 * | SRAM1 128kB | to secure world, or to- Cortex-M4 exclusive access 187 * +--------------+ <-- SRAM2_BASE (= SRAM1_BASE + SRAM1_SIZE) 188 | | full range assigned to non-secure world or 189 * | SRAM2 128kB | to secure world, or to- Cortex-M4 exclusive access 190 * +--------------+ <-- SRAM3_BASE (= SRAM2_BASE + SRAM2_SIZE) 191 | | full range assigned to non-secure world or 192 * | SRAM3 64kB | to secure world, or to- Cortex-M4 exclusive access 193 * +--------------+ <-- SRAM4_BASE (= SRAM3_BASE + SRAM3_SIZE) 194 | | full range assigned to non-secure world or 195 * | SRAM4 64kB | to secure world, or to- Cortex-M4 exclusive access 196 * +--------------+ <-- SRAM4_BASE + SRAM4_SIZE 197 * 198 * If SRAMx memories are not used for the companion Cortex-M4 199 * processor, OP-TEE can use this memory. 200 * 201 * SYSRAM configuration for secure/non-secure boundaries requires the 202 * secure SYSRAM memory to start at the SYSRAM physical base address and grow 203 * from there while the non-secure SYSRAM range lies at SYSRAM end addresses 204 * with a 4KB page granule. 205 * 206 * SRAM1, SRAM2, SRAM3 and SRAM4 are independently assigned to secure world, 207 * to non-secure world or possibly to Cortex-M4 exclusive access. Each 208 * assignment covers the full related SRAMx memory range. 209 * 210 * Using non-secure SYSRAM or one of the SRAMx for SCMI message communication 211 * can be done using CFG_STM32MP1_SCMI_SHM_BASE/CFG_STM32MP1_SCMI_SHM_SIZE. 212 * This imposes related memory area is assigned to non-secure world. 213 214 * Using secure internal memories (SYSRAM and/or some SRAMx) with STM32MP15 215 * shall meet this constraints known the TZSRAM physical memory range shall 216 * be contiguous. 217 */ 218 219 #define SYSRAM_END (SYSRAM_BASE + SYSRAM_SIZE) 220 #define SYSRAM_SEC_END (SYSRAM_BASE + SYSRAM_SEC_SIZE) 221 #define SRAMS_END (SRAM4_BASE + SRAM4_SIZE) 222 #define SRAMS_START SRAM1_BASE 223 #define TZSRAM_END (CFG_TZSRAM_START + CFG_TZSRAM_SIZE) 224 225 #define SCMI_SHM_IS_IN_SRAMX ((CFG_STM32MP1_SCMI_SHM_BASE >= SRAM1_BASE) && \ 226 (CFG_STM32MP1_SCMI_SHM_BASE + \ 227 CFG_STM32MP1_SCMI_SHM_SIZE) <= SRAMS_END) 228 229 #define TZSRAM_FITS_IN_SYSRAM_SEC ((CFG_TZSRAM_START >= SYSRAM_BASE) && \ 230 (TZSRAM_END <= SYSRAM_SEC_END)) 231 232 #define TZSRAM_FITS_IN_SYSRAM_AND_SRAMS ((CFG_TZSRAM_START >= SYSRAM_BASE) && \ 233 (CFG_TZSRAM_START < SYSRAM_END) && \ 234 (TZSRAM_END > SYSRAM_END) && \ 235 (TZSRAM_END <= SRAMS_END) && \ 236 (SYSRAM_SIZE == SYSRAM_SEC_SIZE)) 237 238 #define TZSRAM_FITS_IN_SRAMS ((CFG_TZSRAM_START >= SRAMS_START) && \ 239 (CFG_TZSRAM_START < SRAMS_END) && \ 240 (TZSRAM_END <= SRAMS_END)) 241 242 #define TZSRAM_IS_IN_DRAM (CFG_TZSRAM_START >= CFG_DRAM_BASE) 243 244 #ifdef CFG_WITH_PAGER 245 /* 246 * At build time, we enforce that, when pager is used, 247 * either TZSRAM fully fits inside SYSRAM secure address range, 248 * or TZSRAM fully fits inside the full SYSRAM and spread inside SRAMx orderly, 249 * or TZSRAM fully fits some inside SRAMs address range, 250 * or TZSRAM is in DDR for debug and test purpose. 251 */ 252 static_assert(TZSRAM_FITS_IN_SYSRAM_SEC || TZSRAM_FITS_IN_SYSRAM_AND_SRAMS || 253 TZSRAM_FITS_IN_SRAMS || TZSRAM_IS_IN_DRAM); 254 #endif 255 256 #if TZSRAM_FITS_IN_SYSRAM_AND_SRAMS || TZSRAM_FITS_IN_SRAMS || \ 257 SCMI_SHM_IS_IN_SRAMX 258 /* At run time we enforce that SRAM1 to SRAM4 are properly assigned if used */ 259 static TEE_Result init_stm32mp15_secure_srams(void) 260 { 261 if (IS_ENABLED(CFG_WITH_PAGER)) { 262 if (core_is_buffer_intersect(CFG_TZSRAM_START, CFG_TZSRAM_SIZE, 263 SRAM1_BASE, SRAM1_SIZE)) 264 stm32mp_register_secure_periph_iomem(SRAM1_BASE); 265 266 if (core_is_buffer_intersect(CFG_TZSRAM_START, CFG_TZSRAM_SIZE, 267 SRAM2_BASE, SRAM2_SIZE)) 268 stm32mp_register_secure_periph_iomem(SRAM2_BASE); 269 270 if (core_is_buffer_intersect(CFG_TZSRAM_START, CFG_TZSRAM_SIZE, 271 SRAM3_BASE, SRAM3_SIZE)) 272 stm32mp_register_secure_periph_iomem(SRAM3_BASE); 273 274 if (core_is_buffer_intersect(CFG_TZSRAM_START, CFG_TZSRAM_SIZE, 275 SRAM4_BASE, SRAM4_SIZE)) 276 stm32mp_register_secure_periph_iomem(SRAM4_BASE); 277 } 278 279 if (SCMI_SHM_IS_IN_SRAMX) { 280 if (core_is_buffer_intersect(CFG_STM32MP1_SCMI_SHM_BASE, 281 CFG_STM32MP1_SCMI_SHM_SIZE, 282 SRAM1_BASE, SRAM1_SIZE)) 283 stm32mp_register_non_secure_periph_iomem(SRAM1_BASE); 284 285 if (core_is_buffer_intersect(CFG_STM32MP1_SCMI_SHM_BASE, 286 CFG_STM32MP1_SCMI_SHM_SIZE, 287 SRAM2_BASE, SRAM2_SIZE)) 288 stm32mp_register_non_secure_periph_iomem(SRAM2_BASE); 289 290 if (core_is_buffer_intersect(CFG_STM32MP1_SCMI_SHM_BASE, 291 CFG_STM32MP1_SCMI_SHM_SIZE, 292 SRAM3_BASE, SRAM3_SIZE)) 293 stm32mp_register_non_secure_periph_iomem(SRAM3_BASE); 294 295 if (core_is_buffer_intersect(CFG_STM32MP1_SCMI_SHM_BASE, 296 CFG_STM32MP1_SCMI_SHM_SIZE, 297 SRAM4_BASE, SRAM4_SIZE)) 298 stm32mp_register_non_secure_periph_iomem(SRAM4_BASE); 299 } 300 301 return TEE_SUCCESS; 302 } 303 304 service_init_late(init_stm32mp15_secure_srams); 305 #endif /* TZSRAM_FITS_IN_SYSRAM_AND_SRAMS || TZSRAM_FITS_IN_SRAMS */ 306 #endif /* CFG_STM32MP15 && CFG_TZSRAM_START */ 307 308 static TEE_Result init_stm32mp1_drivers(void) 309 { 310 #if defined(CFG_STM32_ETZPC) 311 etzpc_configure_tzma(1, SYSRAM_SEC_SIZE >> SMALL_PAGE_SHIFT); 312 313 if (SYSRAM_SIZE > SYSRAM_SEC_SIZE) { 314 size_t nsec_size = SYSRAM_SIZE - SYSRAM_SEC_SIZE; 315 paddr_t nsec_start = SYSRAM_BASE + SYSRAM_SEC_SIZE; 316 uint8_t *va = phys_to_virt(nsec_start, MEM_AREA_IO_NSEC, 317 nsec_size); 318 319 IMSG("Non-secure SYSRAM [%p %p]", va, va + nsec_size - 1); 320 321 /* Clear content from the non-secure part */ 322 memset(va, 0, nsec_size); 323 } 324 #endif /* CFG_STM32_ETZPC */ 325 326 return TEE_SUCCESS; 327 } 328 329 service_init_late(init_stm32mp1_drivers); 330 331 static TEE_Result init_late_stm32mp1_drivers(void) 332 { 333 TEE_Result res = TEE_ERROR_GENERIC; 334 uint32_t __maybe_unused state = 0; 335 336 /* Set access permission to TAM backup registers */ 337 if (IS_ENABLED(CFG_STM32_TAMP)) { 338 struct stm32_bkpregs_conf conf = { 339 .nb_zone1_regs = TAMP_BKP_REGISTER_ZONE1_COUNT, 340 .nb_zone2_regs = TAMP_BKP_REGISTER_ZONE2_COUNT, 341 }; 342 343 res = stm32_tamp_set_secure_bkpregs(&conf); 344 if (res == TEE_ERROR_DEFER_DRIVER_INIT) { 345 /* TAMP driver was not probed if disabled in the DT */ 346 res = TEE_SUCCESS; 347 } 348 if (res) 349 panic(); 350 } 351 352 #ifdef CFG_STM32MP15 353 /* Device in Secure Closed state require RCC secure hardening */ 354 if (stm32_bsec_get_state(&state)) 355 panic(); 356 if (state == BSEC_STATE_SEC_CLOSED && !stm32_rcc_is_secure()) 357 panic("Closed device mandates secure RCC"); 358 #endif 359 360 return TEE_SUCCESS; 361 } 362 363 driver_init_late(init_late_stm32mp1_drivers); 364 365 vaddr_t stm32_rcc_base(void) 366 { 367 static struct io_pa_va base = { .pa = RCC_BASE }; 368 369 return io_pa_or_va_secure(&base, 1); 370 } 371 372 vaddr_t get_gicd_base(void) 373 { 374 struct io_pa_va base = { .pa = GIC_BASE + GICD_OFFSET }; 375 376 return io_pa_or_va_secure(&base, 1); 377 } 378 379 void stm32mp_get_bsec_static_cfg(struct stm32_bsec_static_cfg *cfg) 380 { 381 cfg->base = BSEC_BASE; 382 cfg->upper_start = STM32MP1_UPPER_OTP_START; 383 cfg->max_id = STM32MP1_OTP_MAX_ID; 384 } 385 386 bool __weak stm32mp_with_pmic(void) 387 { 388 return false; 389 } 390 391 uint32_t may_spin_lock(unsigned int *lock) 392 { 393 if (!lock || !cpu_mmu_enabled()) 394 return 0; 395 396 return cpu_spin_lock_xsave(lock); 397 } 398 399 void may_spin_unlock(unsigned int *lock, uint32_t exceptions) 400 { 401 if (!lock || !cpu_mmu_enabled()) 402 return; 403 404 cpu_spin_unlock_xrestore(lock, exceptions); 405 } 406 407 static vaddr_t stm32_tamp_base(void) 408 { 409 static struct io_pa_va base = { .pa = TAMP_BASE }; 410 411 return io_pa_or_va_secure(&base, 1); 412 } 413 414 static vaddr_t bkpreg_base(void) 415 { 416 return stm32_tamp_base() + TAMP_BKP_REGISTER_OFF; 417 } 418 419 vaddr_t stm32mp_bkpreg(unsigned int idx) 420 { 421 return bkpreg_base() + (idx * sizeof(uint32_t)); 422 } 423 424 static bool __maybe_unused bank_is_valid(unsigned int bank) 425 { 426 if (IS_ENABLED(CFG_STM32MP15)) 427 return bank == GPIO_BANK_Z || bank <= GPIO_BANK_K; 428 429 if (IS_ENABLED(CFG_STM32MP13)) 430 return bank <= GPIO_BANK_I; 431 432 panic(); 433 } 434 435 #ifdef CFG_STM32_IWDG 436 TEE_Result stm32_get_iwdg_otp_config(paddr_t pbase, 437 struct stm32_iwdg_otp_data *otp_data) 438 { 439 unsigned int idx = 0; 440 uint32_t otp_id = 0; 441 size_t bit_len = 0; 442 uint8_t bit_offset = 0; 443 uint32_t otp_value = 0; 444 445 switch (pbase) { 446 case IWDG1_BASE: 447 idx = 0; 448 break; 449 case IWDG2_BASE: 450 idx = 1; 451 break; 452 default: 453 panic(); 454 } 455 456 if (stm32_bsec_find_otp_in_nvmem_layout("hw2_otp", &otp_id, &bit_offset, 457 &bit_len) || 458 bit_len != 32 || bit_offset != 0) 459 panic(); 460 461 if (stm32_bsec_read_otp(&otp_value, otp_id)) 462 panic(); 463 464 otp_data->hw_enabled = otp_value & 465 BIT(idx + HW2_OTP_IWDG_HW_ENABLE_SHIFT); 466 otp_data->disable_on_stop = otp_value & 467 BIT(idx + HW2_OTP_IWDG_FZ_STOP_SHIFT); 468 otp_data->disable_on_standby = otp_value & 469 BIT(idx + HW2_OTP_IWDG_FZ_STANDBY_SHIFT); 470 471 return TEE_SUCCESS; 472 } 473 #endif /*CFG_STM32_IWDG*/ 474 475 #ifdef CFG_STM32_DEBUG_ACCESS 476 static TEE_Result init_debug(void) 477 { 478 TEE_Result res = TEE_SUCCESS; 479 uint32_t conf = stm32_bsec_read_debug_conf(); 480 struct clk *dbg_clk = stm32mp_rcc_clock_id_to_clk(CK_DBG); 481 uint32_t state = 0; 482 483 res = stm32_bsec_get_state(&state); 484 if (res) 485 return res; 486 487 if (state != BSEC_STATE_SEC_CLOSED && conf) { 488 if (IS_ENABLED(CFG_INSECURE)) 489 IMSG("WARNING: All debug accesses are allowed"); 490 491 res = stm32_bsec_write_debug_conf(conf | BSEC_DEBUG_ALL); 492 if (res) 493 return res; 494 495 /* 496 * Enable DBG clock as used to access coprocessor 497 * debug registers 498 */ 499 clk_enable(dbg_clk); 500 } 501 502 return TEE_SUCCESS; 503 } 504 early_init_late(init_debug); 505 #endif /* CFG_STM32_DEBUG_ACCESS */ 506 507 /* Some generic resources need to be unpaged */ 508 DECLARE_KEEP_PAGER(pinctrl_apply_state); 509 510 bool stm32mp_allow_probe_shared_device(const void *fdt, int node) 511 { 512 static int uart_console_node = -1; 513 const char *compat = NULL; 514 static bool once; 515 516 if (IS_ENABLED(CFG_STM32_ALLOW_UNSAFE_PROBE)) 517 return true; 518 519 if (!once) { 520 get_console_node_from_dt((void *)fdt, &uart_console_node, 521 NULL, NULL); 522 once = true; 523 } 524 525 compat = fdt_stringlist_get(fdt, node, "compatible", 0, NULL); 526 527 /* 528 * Allow OP-TEE console and MP15 I2C and RNG to be shared 529 * with non-secure world. 530 */ 531 if (node == uart_console_node || 532 !strcmp(compat, "st,stm32mp15-i2c-non-secure") || 533 (!strcmp(compat, "st,stm32-rng") && 534 IS_ENABLED(CFG_WITH_SOFTWARE_PRNG))) 535 return true; 536 537 return false; 538 } 539 540 #if defined(CFG_STM32MP15) && defined(CFG_WITH_PAGER) 541 paddr_t stm32mp1_pa_or_sram_alias_pa(paddr_t pa) 542 { 543 /* 544 * OP-TEE uses the alias physical addresses of SRAM1/2/3/4, 545 * not the standard physical addresses. This choice was initially 546 * driven by pager that needs physically contiguous memories 547 * for internal secure memories. 548 */ 549 if (core_is_buffer_inside(pa, 1, SRAM1_ALT_BASE, SRAM1_SIZE)) 550 pa += SRAM1_BASE - SRAM1_ALT_BASE; 551 else if (core_is_buffer_inside(pa, 1, SRAM2_ALT_BASE, SRAM2_SIZE)) 552 pa += SRAM2_BASE - SRAM2_ALT_BASE; 553 else if (core_is_buffer_inside(pa, 1, SRAM3_ALT_BASE, SRAM3_SIZE)) 554 pa += SRAM3_BASE - SRAM3_ALT_BASE; 555 else if (core_is_buffer_inside(pa, 1, SRAM4_ALT_BASE, SRAM4_SIZE)) 556 pa += SRAM4_BASE - SRAM4_ALT_BASE; 557 558 return pa; 559 } 560 #endif 561