1/* 2 * Copyright (c) 2016 Cadence Design Systems, Inc. 3 * SPDX-License-Identifier: Apache-2.0 4 */ 5 6#include <xtensa/coreasm.h> 7#include <xtensa/corebits.h> 8#include <xtensa/cacheasm.h> 9#include <xtensa/cacheattrasm.h> 10#include <xtensa/xtensa-xer.h> 11#include <xtensa/xdm-regs.h> 12#include <xtensa/config/specreg.h> 13#include <xtensa/config/system.h> /* for XSHAL_USE_ABSOLUTE_LITERALS only */ 14#include <xtensa/xtruntime-core-state.h> 15 16/* 17 * The following reset vector avoids initializing certain registers already 18 * initialized by processor reset. But it does initialize some of them 19 * anyway, for minimal support of warm restart (restarting in software by 20 * jumping to the reset vector rather than asserting hardware reset). 21 */ 22 23 .begin literal_prefix .ResetVector 24 .section .ResetVector.text, "ax" 25 26 .align 4 27 .global __start 28__start: 29 30#if (!XCHAL_HAVE_HALT || defined(XTOS_UNPACK)) && XCHAL_HAVE_IMEM_LOADSTORE 31 /* 32 * NOTE: 33 * 34 * IMPORTANT: If you move the _ResetHandler portion to a section 35 * other than .ResetVector.text that is outside the range of 36 * the reset vector's 'j' instruction, the _ResetHandler symbol 37 * and a more elaborate j/movi/jx sequence are needed in 38 * .ResetVector.text to dispatch to the new location. 39 */ 40 j _ResetHandler 41 42 .size __start, . - __start 43 44#if XCHAL_HAVE_HALT 45 /* 46 * Xtensa TX: reset vector segment is only 4 bytes, so must place the 47 * unpacker code elsewhere in the memory that contains the reset 48 * vector. 49 */ 50#if XCHAL_RESET_VECTOR_VADDR == XCHAL_INSTRAM0_VADDR 51 .section .iram0.text, "ax" 52#elif XCHAL_RESET_VECTOR_VADDR == XCHAL_INSTROM0_VADDR 53 .section .irom0.text, "ax" 54#elif XCHAL_RESET_VECTOR_VADDR == XCHAL_URAM0_VADDR 55 .section .uram0.text, "ax" 56#else 57#warning "Xtensa TX reset vector not at start of iram0, irom0, or uram0 -- ROMing LSPs may not work" 58 .text 59#endif 60#endif /* XCHAL_HAVE_HALT */ 61 62 .extern __memctl_default 63 64 .align 4 65 66 /* tells the assembler/linker to place literals here */ 67 .literal_position 68 .align 4 69 .global _ResetHandler 70_ResetHandler: 71#endif 72 73#if !XCHAL_HAVE_HALT 74 75 /* 76 * Even if the processor supports the non-PC-relative L32R option, 77 * it will always start up in PC-relative mode. We take advantage of 78 * this, and use PC-relative mode at least until we're sure the .lit4 79 * section is in place (which is sometimes only after unpacking). 80 */ 81 .begin no-absolute-literals 82 83 /* 84 * If we have dynamic cache way support, init the caches as soon 85 * as we can, which is now. Except, if we are waking up from a 86 * PSO event, then we need to do this slightly later. 87 */ 88#if XCHAL_HAVE_ICACHE_DYN_WAYS || XCHAL_HAVE_DCACHE_DYN_WAYS 89# if XCHAL_HAVE_PSO_CDM && !XCHAL_HAVE_PSO_FULL_RETENTION 90 /* Do this later on in the code -- see below */ 91# else 92 movi a0, __memctl_default 93 wsr a0, MEMCTL 94# endif 95#endif 96 97 /* 98 * If we have PSO support, then we must check for a warm start with 99 * caches left powered on. If the caches had been left powered on, 100 * we must restore the state of MEMCTL to the saved state if any. 101 * Note that MEMCTL may not be present depending on config. 102 */ 103#if XCHAL_HAVE_PSO_CDM && !XCHAL_HAVE_PSO_FULL_RETENTION 104 /* Read PWRSTAT */ 105 movi a2, XDM_MISC_PWRSTAT 106 /* Save area address - retained for later */ 107 movi a3, xthal_pso_savearea 108 /* Signature for compare - retained for later */ 109 movi a5, CORE_STATE_SIGNATURE 110 /* PWRSTAT value - retained for later */ 111 rer a7, a2 112 /* Now bottom 2 bits are core wakeup and cache power lost */ 113 extui a4, a7, 1, 2 114 /* a4==1 means PSO wakeup, caches did not lose power */ 115 bnei a4, 1, .Lcold_start 116 /* Load save area signature field */ 117 l32i a4, a3, CS_SA_signature 118 sub a4, a4, a5 119 /* If signature mismatch then do cold start */ 120 bnez a4, .Lcold_start 121#if XCHAL_USE_MEMCTL 122 /* Load saved MEMCTL value */ 123 l32i a4, a3, CS_SA_memctl 124 movi a0, ~MEMCTL_INV_EN 125 /* Clear invalidate bit */ 126 and a0, a4, a0 127 wsr a0, MEMCTL 128#endif 129 j .Lwarm_start 130 131.Lcold_start: 132 133#if XCHAL_HAVE_ICACHE_DYN_WAYS || XCHAL_HAVE_DCACHE_DYN_WAYS 134 /* 135 * Enable and invalidate all ways of both caches. If there is no 136 * dynamic way support then this write will have no effect. 137 */ 138 movi a0, __memctl_default 139 wsr a0, MEMCTL 140#endif 141 142.Lwarm_start: 143 144#endif 145 /* a0 is always 0 in this code, used to initialize lots of things */ 146 movi a0, 0 147 148/* technically this should be under !FULL_RESET, assuming hard reset */ 149#if XCHAL_HAVE_INTERRUPTS 150 /* make sure that interrupts are shut off (*before* we lower 151 * PS.INTLEVEL and PS.EXCM!) 152 */ 153 wsr.intenable a0 154#if (XCHAL_NUM_INTERRUPTS > 32) 155 wsr.intenable1 a0 156#endif 157#if (XCHAL_NUM_INTERRUPTS > 64) 158 wsr.intenable2 a0 159#endif 160#if (XCHAL_NUM_INTERRUPTS > 96) 161 wsr.intenable3 a0 162#endif 163#endif 164 165#if !XCHAL_HAVE_FULL_RESET 166 167/* pre-LX2 cores only */ 168#if XCHAL_HAVE_CCOUNT && (XCHAL_HW_MIN_VERSION < XTENSA_HWVERSION_RB_2006_0) 169 /* not really necessary, but nice; best done very early */ 170 wsr a0, CCOUNT 171#endif 172 173 /* 174 * For full MMU configs, put page table at an unmapped virtual address. 175 * This ensures that accesses outside the static maps result 176 * in miss exceptions rather than random behaviour. 177 * Assumes XCHAL_SEG_MAPPABLE_VADDR == 0 (true in released MMU). 178 */ 179#if XCHAL_ITLB_ARF_WAYS > 0 || XCHAL_DTLB_ARF_WAYS > 0 180 wsr a0, PTEVADDR 181#endif 182 183 /* 184 * Debug initialization 185 * 186 * NOTE: DBREAKCn must be initialized before the combination of these 187 * two things: any load/store, and a lowering of PS.INTLEVEL below 188 * DEBUG_LEVEL. The processor already resets IBREAKENABLE 189 * appropriately. 190 */ 191#if XCHAL_HAVE_DEBUG 192#if XCHAL_NUM_DBREAK 193#if XCHAL_NUM_DBREAK >= 2 194 wsr a0, DBREAKC1 195#endif 196 wsr a0, DBREAKC0 197 dsync /* wait for WSRs to DBREAKCn to complete */ 198#endif /* XCHAL_NUM_DBREAK */ 199 200/* pre-LX cores only */ 201# if XCHAL_HW_MIN_VERSION < XTENSA_HWVERSION_RA_2004_1 202 /* 203 * Starting in Xtensa LX, ICOUNTLEVEL resets to zero (not 15), so no 204 * need to initialize it. Prior to that we do, otherwise we get an 205 * ICOUNT exception, 2^32 instructions after reset. 206 */ 207 208 /* are we being debugged? (detected by ICOUNTLEVEL not 15, or dropped 209 * below 12) 210 */ 211 rsr a2, ICOUNTLEVEL 212 /* if so, avoid initializing ICOUNTLEVEL which drops single-steps 213 * through here 214 * */ 215 bltui a2, 12, 1f 216 /* avoid ICOUNT exceptions */ 217 wsr a0, ICOUNTLEVEL 218 /* wait for WSR to ICOUNTLEVEL to complete */ 219 isync 2201: 221#endif 222#endif /* XCHAL_HAVE_DEBUG */ 223 224#endif /* !XCHAL_HAVE_FULL_RESET */ 225 226#if XCHAL_HAVE_ABSOLUTE_LITERALS 227 /* Technically, this only needs to be done under !FULL_RESET, 228 * assuming hard reset: 229 */ 230 wsr a0, LITBASE 231 rsync 232#endif 233 234#if XCHAL_HAVE_PSO_CDM && ! XCHAL_HAVE_PSO_FULL_RETENTION 235 /* 236 * If we're powering up from a temporary power shut-off (PSO), 237 * restore state saved just prior to shut-off. Note that the 238 * MEMCTL register was already restored earlier, and as a side 239 * effect, registers a3, a5, a7 are now preloaded with values 240 * that we will use here. 241 * a3 - pointer to save area base address (xthal_pso_savearea) 242 * a5 - saved state signature (CORE_STATE_SIGNATURE) 243 * a7 - contents of PWRSTAT register 244 */ 245 246 /* load save area signature */ 247 l32i a4, a3, CS_SA_signature 248 /* compare signature with expected one */ 249 sub a4, a4, a5 250# if XTOS_PSO_TEST 251 /* pretend PSO warm start with warm caches */ 252 movi a7, PWRSTAT_WAKEUP_RESET 253# endif 254 /* wakeup from PSO? (branch if not) */ 255 bbci.l a7, PWRSTAT_WAKEUP_RESET_SHIFT, 1f 256 /* Yes, wakeup from PSO. Check whether state was properly saved. 257 * speculatively clear PSO-wakeup bit */ 258 addi a5, a7, - PWRSTAT_WAKEUP_RESET 259 /* if state not saved (corrupted?), mark as cold start */ 260 movnez a7, a5, a4 261 /* if state not saved, just continue with reset */ 262 bnez a4, 1f 263 /* Wakeup from PSO with good signature. Now check cache status: 264 * if caches warm, restore now */ 265 bbci.l a7, PWRSTAT_CACHES_LOST_POWER_SHIFT, .Lpso_restore 266 /* Caches got shutoff. Continue reset, we'll end up initializing 267 * caches, and check again later for PSO. 268 */ 269# if XCHAL_HAVE_PRID && XCHAL_HAVE_S32C1I 270 j .Ldonesync /* skip reset sync, only done for cold start */ 271# endif 2721: /* Cold start. (Not PSO wakeup.) Proceed with normal full reset. */ 273#endif 274 275#if XCHAL_HAVE_PRID && XCHAL_HAVE_S32C1I 276 /* Core 0 initializes the XMP synchronization variable, if present. 277 * This operation needs to happen as early as possible in the startup 278 * sequence so that the other cores can be released from reset. 279 */ 280 .weak _ResetSync 281 movi a2, _ResetSync /* address of sync variable */ 282 rsr.prid a3 /* core and multiprocessor ID */ 283 extui a3, a3, 0, 8 /* extract core ID (FIXME: need proper 284 * constants for PRID bits to extract) */ 285 beqz a2, .Ldonesync /* skip if no sync variable */ 286 bnez a3, .Ldonesync /* only do this on core 0 */ 287 s32i a0, a2, 0 /* clear sync variable */ 288.Ldonesync: 289#endif 290#if XCHAL_HAVE_EXTERN_REGS && XCHAL_HAVE_MP_RUNSTALL 291 /* On core 0, this releases other cores. On other cores this has no 292 * effect, because runstall control is unconnected 293 */ 294 movi a2, XER_MPSCORE 295 wer a0, a2 296#endif 297 298 /* 299 * For processors with relocatable vectors, apply any alternate 300 * vector base given to xt-genldscripts, which sets the 301 * _memmap_vecbase_reset symbol accordingly. 302 */ 303#if XCHAL_HAVE_VECBASE 304 /* note: absolute symbol, not a ptr */ 305 movi a2, _memmap_vecbase_reset 306 wsr a2, vecbase 307#endif 308 309/* have ATOMCTL ? */ 310#if XCHAL_HAVE_S32C1I && (XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RC_2009_0) 311#if XCHAL_DCACHE_IS_COHERENT 312 /* MX -- internal for writeback, RCW otherwise */ 313 movi a3, 0x25 314#else 315 /* non-MX -- always RCW */ 316 movi a3, 0x15 317#endif /* XCHAL_DCACHE_IS_COHERENT */ 318 wsr a3, ATOMCTL 319#endif 320 321#if XCHAL_HAVE_INTERRUPTS && XCHAL_HAVE_DEBUG 322 /* lower PS.INTLEVEL here to make reset vector easier to debug */ 323 rsil a2, 1 324#endif 325 326 /* If either of the caches does not have dynamic way support, then 327 * use the old (slow) method to init them. If the cache is absent 328 * the macros will expand to empty. 329 */ 330#if ! XCHAL_HAVE_ICACHE_DYN_WAYS 331 icache_reset a2, a3 332#endif 333#if ! XCHAL_HAVE_DCACHE_DYN_WAYS 334 dcache_reset a2, a3 335#endif 336 337#if XCHAL_HAVE_PSO_CDM && ! XCHAL_HAVE_PSO_FULL_RETENTION 338 /* Here, a7 still contains status from the power status register, 339 * or zero if signature check failed. 340 */ 341 342 /* wakeup from PSO with good signature? */ 343 bbci.l a7, PWRSTAT_WAKEUP_RESET_SHIFT, .Lcoldstart 344 /* Yes, wakeup from PSO. Caches had been powered down, now are 345 * initialized. 346 */ 347.Lpso_restore: 348 /* Assume memory still initialized, so all code still unpacked etc. 349 * So we can just jump/call to relevant state restore code (wherever 350 * located). 351 */ 352 353 /* make shutoff routine return zero */ 354 movi a2, 0 355 movi a3, xthal_pso_savearea 356 /* Here, as below for _start, call0 is used as an unlimited-range 357 * jump. 358 */ 359 call0 xthal_core_restore_nw 360 /* (does not return) */ 361.Lcoldstart: 362#endif 363 364#if XCHAL_HAVE_PREFETCH 365 /* Enable cache prefetch if present. */ 366 movi a2, XCHAL_CACHE_PREFCTL_DEFAULT 367 wsr a2, PREFCTL 368#endif 369 370 /* 371 * Now setup the memory attributes. On some cores this "enables" 372 * caches. We do this ahead of unpacking, so it can proceed more 373 * efficiently. 374 * 375 * The _memmap_cacheattr_reset symbol's value (address) is defined by 376 * the LSP's linker script, as generated by xt-genldscripts. If 377 * defines 4-bit attributes for eight 512MB regions. 378 * 379 * (NOTE: for cores with the older MMU v1 or v2, or without any 380 * memory protection mechanism, the following code has no effect.) 381 */ 382#if XCHAL_HAVE_MPU 383 /* If there's an empty background map, setup foreground maps to mimic 384 * region protection: 385 */ 386# if XCHAL_MPU_ENTRIES >= 8 && XCHAL_MPU_BACKGROUND_ENTRIES <= 2 387 .pushsection .rodata, "a" 388 .global _xtos_mpu_attribs 389 .align 4 390_xtos_mpu_attribs: 391 /* Illegal (---) */ 392 .word 0x00006000+XCHAL_MPU_ENTRIES-8 393 /* Writeback (rwx Cacheable Non-shareable wb rd-alloc wr-alloc) */ 394 .word 0x000F7700+XCHAL_MPU_ENTRIES-8 395 /* WBNA (rwx Cacheable Non-shareable wb rd-alloc) */ 396 .word 0x000D5700+XCHAL_MPU_ENTRIES-8 397 /* Writethru (rwx Cacheable Non-shareable wt rd-alloc) */ 398 .word 0x000C4700+XCHAL_MPU_ENTRIES-8 399 /* Bypass (rwx Device non-interruptible system-shareable) */ 400 .word 0x00006700+XCHAL_MPU_ENTRIES-8 401 .popsection 402 403 /* 404 * We assume reset state: all MPU entries zeroed and disabled. 405 * Otherwise we'd need a loop to zero everything. 406 */ 407 /* note: absolute symbol, not a ptr */ 408 movi a2, _memmap_cacheattr_reset 409 movi a3, _xtos_mpu_attribs 410 movi a4, 0x20000000 /* 512 MB delta */ 411 movi a6, 8 412 movi a7, 1 /* MPU entry vaddr 0, with valid bit set */ 413 movi a9, 0 /* cacheadrdis value */ 414 /* enable everything temporarily while MPU updates */ 415 wsr.cacheadrdis a9 416 417 /* Write eight MPU entries, from the last one going backwards 418 * (entries n-1 thru n-8) 419 */ 4202: extui a8, a2, 28, 4 /* get next attribute nibble (msb first) */ 421 extui a5, a8, 0, 2 /* lower two bit indicate whether cached */ 422 slli a9, a9, 1 /* add a bit to cacheadrdis... */ 423 addi a10, a9, 1 /* set that new bit if... */ 424 moveqz a9, a10, a5 /* ... that region is non-cacheable */ 425 addx4 a5, a8, a3 /* index into _xtos_mpu_attribs table */ 426 addi a8, a8, -5 /* make valid attrib indices negative */ 427 movgez a5, a3, a8 /* if not valid attrib, use Illegal */ 428 l32i a5, a5, 0 /* load access rights, memtype from table 429 * entry 430 */ 431 slli a2, a2, 4 432 sub a7, a7, a4 /* next 512MB region (last to first) */ 433 addi a6, a6, -1 434 add a5, a5, a6 /* add the index */ 435 wptlb a5, a7 /* write the MPU entry */ 436 bnez a6, 2b /* loop until done */ 437# else 438 /* default value of CACHEADRDIS for bgnd map */ 439 movi a9, XCHAL_MPU_BG_CACHEADRDIS 440# endif 441 wsr.cacheadrdis a9 /* update cacheadrdis */ 442#elif XCHAL_HAVE_CACHEATTR || XCHAL_HAVE_MIMIC_CACHEATTR \ 443 || XCHAL_HAVE_XLT_CACHEATTR \ 444 || (XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY) 445 /* note: absolute symbol, not a ptr */ 446 movi a2, _memmap_cacheattr_reset 447 /* set CACHEATTR from a2 (clobbers a3-a8) */ 448 cacheattr_set 449#endif 450 451 /* Now that caches are initialized, cache coherency can be enabled. */ 452#if XCHAL_DCACHE_IS_COHERENT 453# if XCHAL_HAVE_EXTERN_REGS && XCHAL_HAVE_MX && \ 454 (XCHAL_HW_MIN_VERSION < XTENSA_HWVERSION_RE_2012_0) 455 /* Opt into coherence for MX (for backward compatibility / testing). */ 456 movi a3, 1 457 movi a2, XER_CCON 458 wer a3, a2 459# endif 460#endif 461 462 /* Enable zero-overhead loop instr buffer, and snoop responses, if 463 * configured. If HW erratum 453 fix is to be applied, then don't 464 * enable loop instr buffer. 465 */ 466#if XCHAL_USE_MEMCTL && XCHAL_SNOOP_LB_MEMCTL_DEFAULT 467 movi a3, XCHAL_SNOOP_LB_MEMCTL_DEFAULT 468 rsr a2, MEMCTL 469 or a2, a2, a3 470 wsr a2, MEMCTL 471#endif 472 473 /* Caches are all up and running, clear PWRCTL.ShutProcOffOnPWait. */ 474#if XCHAL_HAVE_PSO_CDM 475 movi a2, XDM_MISC_PWRCTL 476 movi a4, ~PWRCTL_CORE_SHUTOFF 477 rer a3, a2 478 and a3, a3, a4 479 wer a3, a2 480#endif 481 482#endif /* !XCHAL_HAVE_HALT */ 483 484 /* 485 * Unpack code and data (eg. copy ROMed segments to RAM, vectors into 486 * their proper location, etc). 487 */ 488 489#if defined(XTOS_UNPACK) 490 movi a2, _rom_store_table 491 beqz a2, unpackdone 492unpack: l32i a3, a2, 0 /* start vaddr */ 493 l32i a4, a2, 4 /* end vaddr */ 494 l32i a5, a2, 8 /* store vaddr */ 495 addi a2, a2, 12 496 bgeu a3, a4, upnext /* skip unless start < end */ 497uploop: l32i a6, a5, 0 498 addi a5, a5, 4 499 s32i a6, a3, 0 500 addi a3, a3, 4 501 bltu a3, a4, uploop 502 j unpack 503upnext: bnez a3, unpack 504 bnez a5, unpack 505#endif /* XTOS_UNPACK */ 506 507unpackdone: 508 509#if defined(XTOS_UNPACK) || defined(XTOS_MP) 510 /* 511 * If writeback caches are configured and enabled, unpacked data must 512 * be written out to memory before trying to execute it: 513 */ 514 dcache_writeback_all a2, a3, a4, 0 515 /* ensure data written back is visible to i-fetch */ 516 icache_sync a2 517 /* 518 * Note: no need to invalidate the i-cache after the above, because 519 * we already invalidated it further above and did not execute 520 * anything within unpacked regions afterwards. [Strictly speaking, 521 * if an unpacked region follows this code very closely, it's possible 522 * for cache-ahead to have cached a bit of that unpacked region, so in 523 * the future we may need to invalidate the entire i-cache here again 524 * anyway.] 525 */ 526#endif 527 528 529#if !XCHAL_HAVE_HALT /* skip for TX */ 530 531 /* 532 * Now that we know the .lit4 section is present (if got unpacked) 533 * (and if absolute literals are used), initialize LITBASE to use it. 534 */ 535#if XCHAL_HAVE_ABSOLUTE_LITERALS && XSHAL_USE_ABSOLUTE_LITERALS 536 /* 537 * Switch from PC-relative to absolute (litbase-relative) L32R mode. 538 * Set LITBASE to 256 kB beyond the start of the literals in .lit4 539 * (aligns to the nearest 4 kB boundary, LITBASE does not have bits 540 * 1..11) and set the enable bit (_lit4_start is assumed 4-byte 541 * aligned). 542 */ 543 movi a2, _lit4_start + 0x40001 544 wsr a2, LITBASE 545 rsync 546#endif /* have and use absolute literals */ 547 /* we can now start using absolute literals */ 548 .end no-absolute-literals 549 550 /* Technically, this only needs to be done pre-LX2, assuming hard 551 * reset: 552 */ 553# if XCHAL_HAVE_WINDOWED && defined(__XTENSA_WINDOWED_ABI__) 554 /* Windowed register init, so we can call windowed code (eg. C code). */ 555 movi a1, 1 556 wsr a1, WINDOWSTART 557 /* 558 * The processor always clears WINDOWBASE at reset, so no need to 559 * clear it here. It resets WINDOWSTART to 1 starting with LX2.0/X7.0 560 * (RB-2006.0). However, assuming hard reset is not yet always 561 * practical, so do this anyway: 562 */ 563 wsr a0, WINDOWBASE 564 rsync 565 movi a0, 0 /* possibly a different a0, clear it */ 566# endif 567 568/* only pre-LX2 needs this */ 569#if XCHAL_HW_MIN_VERSION < XTENSA_HWVERSION_RB_2006_0 570 /* Coprocessor option initialization */ 571# if XCHAL_HAVE_CP 572 /* 573 * To allow creating new coprocessors using TC that are not known 574 * at GUI build time without having to explicitly enable them, 575 * all CPENABLE bits must be set, even though they may not always 576 * correspond to a coprocessor. 577 */ 578#ifdef CONFIG_XTENSA_LAZY_HIFI_SHARING 579 /* 580 * Disable HiFi coprocessor by default. Should a thread try using 581 * the HiFi coprocessor, it will trigger an exception to both enable 582 * it AND save/restore the HiFi state. 583 */ 584 585 movi a2, 0xFF & ~(1 << XCHAL_CP_ID_AUDIOENGINELX) 586#else 587 movi a2, 0xFF /* enable *all* bits, to allow dynamic TIE */ 588#endif 589 wsr a2, CPENABLE 590# endif 591 592 /* 593 * Floating point coprocessor option initialization (at least 594 * rounding mode, so that floating point ops give predictable results) 595 */ 596# if XCHAL_HAVE_FP && !XCHAL_HAVE_VECTORFPU2005 597/* floating-point control register (user register number) */ 598# define FCR 232 599/* floating-point status register (user register number) */ 600# define FSR 233 601 /* wait for WSR to CPENABLE to complete before accessing FP coproc 602 * state 603 */ 604 rsync 605 wur a0, FCR /* clear FCR (default rounding mode, round-nearest) */ 606 wur a0, FSR /* clear FSR */ 607# endif 608#endif /* pre-LX2 */ 609 610 611 /* 612 * Initialize memory error handler address. 613 * Putting this address in a register allows multiple instances of 614 * the same configured core (with separate program images but shared 615 * code memory, thus forcing memory error vector to be shared given 616 * it is not VECBASE relative) to have the same memory error vector, 617 * yet each have their own handler and associated data save area. 618 */ 619#if XCHAL_HAVE_MEM_ECC_PARITY 620 movi a4, _MemErrorHandler 621 wsr a4, MESAVE 622#endif 623 624 625 /* 626 * Initialize medium and high priority interrupt dispatchers: 627 */ 628#if HAVE_XSR 629 630/* For asm macros; works for positive a,b smaller than 1000: */ 631# define GREATERTHAN(a,b) (((b)-(a)) & ~0xFFF) 632 633# ifndef XCHAL_DEBUGLEVEL /* debug option not selected? */ 634# define XCHAL_DEBUGLEVEL 99 /* bogus value outside 2..6 */ 635# endif 636 637 .macro init_vector level 638 .if GREATERTHAN(XCHAL_NUM_INTLEVELS+1,\level) 639 .if XCHAL_DEBUGLEVEL-\level 640 .weak _Level&level&FromVector 641 movi a4, _Level&level&FromVector 642 wsr a4, EXCSAVE+\level 643 .if GREATERTHAN(\level,XCHAL_EXCM_LEVEL) 644 movi a5, _Pri_&level&_HandlerAddress 645 s32i a4, a5, 0 646 /* If user provides their own handler, that handler might 647 * not provide its own _Pri_<n>_HandlerAddress variable for 648 * linking handlers. In that case, the reference below 649 * would pull in the XTOS handler anyway, causing a conflict. 650 * To avoid that, provide a weak version of it here: 651 */ 652 .pushsection .data, "aw" 653 .global _Pri_&level&_HandlerAddress 654 .weak _Pri_&level&_HandlerAddress 655 .align 4 656 _Pri_&level&_HandlerAddress: .space 4 657 .popsection 658 .endif 659 .endif 660 .endif 661 .endm 662 663 init_vector 2 664 init_vector 3 665 init_vector 4 666 init_vector 5 667 init_vector 6 668 669#endif /*HAVE_XSR*/ 670 671 672 /* 673 * Complete reset initialization outside the vector, to avoid 674 * requiring a vector that is larger than necessary. This 2nd-stage 675 * startup code sets up the C Run-Time (CRT) and calls main(). 676 * 677 * Here we use call0 not because we expect any return, but because the 678 * assembler/linker dynamically sizes call0 as needed (with 679 * -mlongcalls) which it doesn't with j or jx. Note: This needs to 680 * be call0 regardless of the selected ABI. 681 */ 682 call0 _start /* jump to _start (in crt1-*.S) */ 683 /* does not return */ 684 685#else /* XCHAL_HAVE_HALT */ 686 687 j _start /* jump to _start (in crt1-*.S) */ 688 /* (TX has max 64kB IRAM, so J always in range) */ 689 690 /* Paranoia -- double-check requirements / assumptions of this Xtensa 691 * TX code: 692 */ 693# if !defined(__XTENSA_CALL0_ABI__) || !XCHAL_HAVE_FULL_RESET \ 694 || XCHAL_HAVE_INTERRUPTS || XCHAL_HAVE_CCOUNT \ 695 || XCHAL_DTLB_ARF_WAYS || XCHAL_HAVE_DEBUG \ 696 || XCHAL_HAVE_S32C1I || XCHAL_HAVE_ABSOLUTE_LITERALS \ 697 || XCHAL_DCACHE_SIZE || XCHAL_ICACHE_SIZE || XCHAL_HAVE_PIF \ 698 || XCHAL_HAVE_WINDOWED 699# error "Halt architecture (Xtensa TX) requires: call0 ABI, all flops reset, no exceptions or interrupts, no TLBs, no debug, no S32C1I, no LITBASE, no cache, no PIF, no windowed regs" 700# endif 701 702#endif /* XCHAL_HAVE_HALT */ 703 704 705#if (!XCHAL_HAVE_HALT || defined(XTOS_UNPACK)) && XCHAL_HAVE_IMEM_LOADSTORE 706 .size _ResetHandler, . - _ResetHandler 707#else 708 .size __start, . - __start 709#endif 710 711 .text 712 .global xthals_hw_configid0, xthals_hw_configid1 713 .global xthals_release_major, xthals_release_minor 714 .end literal_prefix 715