Setting up repository
[linux-libre-firmware.git] / ath9k_htc / sboot / magpie_1_1 / sboot / athos / src / xtos / reset-vector.S
1 // reset-vector.S  --  Xtensa Reset Vector
2 // $Id: //depot/rel/Cottonwood/Xtensa/OS/xtos/reset-vector.S#4 $
3
4 // Copyright (c) 1999-2010 Tensilica Inc.
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining
7 // a copy of this software and associated documentation files (the
8 // "Software"), to deal in the Software without restriction, including
9 // without limitation the rights to use, copy, modify, merge, publish,
10 // distribute, sublicense, and/or sell copies of the Software, and to
11 // permit persons to whom the Software is furnished to do so, subject to
12 // the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included
15 // in all copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25 #include <xtensa/coreasm.h>
26 #include <xtensa/cacheasm.h>
27 #include <xtensa/cacheattrasm.h>
28 #include <xtensa/xtensa-xer.h>
29 #include <xtensa/config/specreg.h>
30 #include <xtensa/config/system.h>       /* for XSHAL_USE_ABSOLUTE_LITERALS only */
31 #include "xtos-internal.h"
32
33 // The following reset vector avoids initializing certain registers already
34 // initialized by processor reset.
35 // Some of the registers reset by the processor include:
36 //   CACHEATTR or relevant TLB state
37 //   IBREAKENABLE               Debug
38 //   LCOUNT                     Loops
39 //   PC                         Core
40 //   PS                         Core
41 //   ICOUNT                     Debug
42 //   ICOUNTLEVEL                Debug
43 //   VECBASE                    Relocatable vectors
44 //   (and various others, depending on hardware version)
45
46
47         .begin  literal_prefix  .ResetVector
48         .section                .ResetVector.text, "ax"
49
50         .align  4
51         .global _ResetVector
52 _ResetVector:
53
54 # if 0  /* if XCHAL_HAVE_HALT */
55         //  In theory, minimal reset vector for Xtensa TX (assuming bootloader to clear BSS).
56         //  In practice we let crt*.S decide whether to do more (e.g. for sim LSP)
57         //  and we might unpack below for ROMing LSPs.
58         movi    sp, __stack     // setup the stack
59         call0   main            // assume declared as "void main(void)" (no args)
60         halt                    // toodaloo
61 # endif
62
63 #if (!XCHAL_HAVE_HALT || defined(XTOS_UNPACK)) && XCHAL_HAVE_IMEM_LOADSTORE
64         //  NOTE:
65         //
66         //  IMPORTANT:  If you move the _ResetHandler portion to a section
67         //  other than .ResetVector.text that is outside the range of
68         //  the reset vector's 'j' instruction, the _ResetHandler symbol
69         //  and a more elaborate j/movi/jx sequence are needed in
70         //  .ResetVector.text to dispatch to the new location.
71
72         j       _ResetHandler
73
74         .size   _ResetVector, . - _ResetVector
75
76 # if XCHAL_HAVE_HALT
77         //  Xtensa TX: reset vector segment is only 4 bytes, so must place the
78         //  unpacker code elsewhere in the memory that contains the reset vector.
79 #  if XCHAL_RESET_VECTOR_VADDR == XCHAL_INSTRAM0_VADDR
80         .section .iram0.text, "ax"
81 #  elif XCHAL_RESET_VECTOR_VADDR == XCHAL_INSTROM0_VADDR
82         .section .irom0.text, "ax"
83 #  elif XCHAL_RESET_VECTOR_VADDR == XCHAL_URAM0_VADDR
84         .section .uram0.text, "ax"
85 #  else
86 #   warning "Xtensa TX reset vector not at start of iram0, irom0, or uram0 -- ROMing LSPs may not work"
87         .text
88 #  endif
89 # endif
90
91         .align  4
92         .literal_position       // tells the assembler/linker to place literals here
93
94         .align  4
95         .global _ResetHandler
96 _ResetHandler:
97 #endif
98
99 #if !XCHAL_HAVE_HALT
100
101         /*
102          *  Even if the processor supports the non-PC-relative L32R option,
103          *  it will always start up in PC-relative mode.  We take advantage of
104          *  this, and use PC-relative mode at least until we're sure the .lit4
105          *  section is in place (which is sometimes only after unpacking).
106          */
107         .begin  no-absolute-literals
108
109
110         movi    a0, 0           // a0 is always 0 in this code, used to initialize lots of things
111
112 #if XCHAL_HAVE_INTERRUPTS       // technically this should be under !FULL_RESET, assuming hard reset
113         wsr     a0, INTENABLE   // make sure that interrupts are shut off (*before* we lower PS.INTLEVEL and PS.EXCM!)
114 #endif
115
116 #if !XCHAL_HAVE_FULL_RESET
117
118 #if XCHAL_HAVE_CCOUNT && (XCHAL_HW_MIN_VERSION < XTENSA_HWVERSION_RB_2006_0)    /* pre-LX2 cores only */
119         wsr     a0, CCOUNT      // not really necessary, but nice; best done very early
120 #endif
121
122         // For full MMU configs, put page table at an unmapped virtual address.
123         // This ensures that accesses outside the static maps result
124         // in miss exceptions rather than random behaviour.
125         // Assumes XCHAL_SEG_MAPPABLE_VADDR == 0 (true in released MMU).
126 #if XCHAL_ITLB_ARF_WAYS > 0 || XCHAL_DTLB_ARF_WAYS > 0
127         wsr     a0, PTEVADDR
128 #endif
129
130         // Debug initialization
131         //
132         // NOTE: DBREAKCn must be initialized before the combination of these two things:
133         //       any load/store, and a lowering of PS.INTLEVEL below DEBUG_LEVEL.
134         //       The processor already resets IBREAKENABLE appropriately.
135         //
136 #if XCHAL_HAVE_DEBUG
137 # if XCHAL_NUM_DBREAK
138 #  if XCHAL_NUM_DBREAK >= 2
139         wsr     a0, DBREAKC1
140 #  endif
141         wsr     a0, DBREAKC0
142         dsync                   // wait for WSRs to DBREAKCn to complete
143 # endif
144
145 # if XCHAL_HW_MIN_VERSION < XTENSA_HWVERSION_RA_2004_1  /* pre-LX cores only */
146         //  Starting in Xtensa LX, ICOUNTLEVEL resets to zero (not 15), so no need to initialize it.
147         //  Prior to that we do, otherwise we get an ICOUNT exception, 2^32 instructions after reset.
148         rsr     a2, ICOUNTLEVEL // are we being debugged? (detected by ICOUNTLEVEL not 15, or dropped below 12)
149         bltui   a2, 12, 1f      // if so, avoid initializing ICOUNTLEVEL which drops single-steps through here
150         wsr     a0, ICOUNTLEVEL // avoid ICOUNT exceptions
151         isync                   // wait for WSR to ICOUNTLEVEL to complete
152 1:
153 # endif
154 #endif
155
156 #endif /* !XCHAL_HAVE_FULL_RESET */
157
158 #if XCHAL_HAVE_ABSOLUTE_LITERALS
159         //  Technically, this only needs to be done under !FULL_RESET, assuming hard reset:
160         wsr     a0, LITBASE
161         rsync
162 #endif
163
164 #if XCHAL_HAVE_PRID && XCHAL_HAVE_S32C1I
165         /* Core 0 initializes the XMP synchronization variable, if present. This operation needs to
166            happen as early as possible in the startup sequence so that the other cores can be released
167            from reset.  */
168         .weak _ResetSync
169         movi    a2, _ResetSync  // address of sync variable
170         rsr.prid a3             // core and multiprocessor ID
171         extui   a3, a3, 0, 8    // extract core ID (FIXME: need proper constants for PRID bits to extract)
172         beqz    a2, 1f          // skip if no sync variable
173         bnez    a3, 1f          // only do this on core 0
174         s32i    a0, a2, 0       // clear sync variable
175 1:
176 #endif
177 #if XCHAL_HAVE_EXTERN_REGS && XCHAL_HAVE_MP_RUNSTALL
178         /* On core 0, this releases other cores.  On other cores this has no effect, because
179            runstall control is unconnected.  */
180         movi    a2, XER_MPSCORE
181         wer     a0, a2
182 #endif
183
184         /*
185          *  For processors with relocatable vectors, apply any alternate
186          *  vector base given to xt-genldscripts, which sets the
187          *  _memmap_vecbase_reset symbol accordingly.
188          */
189 #if XCHAL_HAVE_VECBASE
190         movi    a2, _memmap_vecbase_reset       /* note: absolute symbol, not a ptr */
191         wsr     a2, vecbase
192 #endif
193
194 #if XCHAL_HAVE_S32C1I && (XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RC_2009_0)   /* have ATOMCTL ? */
195 # if XCHAL_DCACHE_IS_COHERENT
196         movi    a3, 0x25                /* MX -- internal for writeback, RCW otherwise */
197 # else
198         movi    a3, 0x15                /* non-MX -- always RCW */
199 # endif
200         wsr     a3, ATOMCTL
201 #endif
202
203 #if XCHAL_HAVE_INTERRUPTS && XCHAL_HAVE_DEBUG
204         rsil    a2, 1           // lower PS.INTLEVEL here to make reset vector easier to debug
205 #endif
206
207         /*
208          *  Initialize the caches.
209          *  We do this very early because performance can increase by
210          *  an order of magnitude when we enable the caches, which
211          *  greatly affects start up time, including the mini-loader below.
212          *  This is also required before we jump into any cacheable region.
213          *  Without caches, these macros expand to nothing (see cacheasm.h).
214          */
215         icache_reset    a2, a3
216         dcache_reset    a2, a3
217
218 #if XCHAL_HAVE_PREFETCH
219         /* Enable cache prefetch if present.  */
220         movi    a2, XCHAL_CACHE_PREFCTL_DEFAULT
221         wsr     a2, PREFCTL
222 #endif
223
224         /*
225          *  Now "enable" the caches, for unpacking to occur a bit more
226          *  efficiently.  Only relevant for region protection and XEA1.
227          *
228          *  The _memmap_cacheattr_reset symbol's value (address) is defined
229          *  by the LSP's linker script, as generated by xt-genldscripts.
230          *
231          *  (NOTE:  for configs that don't have CACHEATTR or region protection,
232          *   ie. for full MMUs, there is no equivalent cache attribute layout,
233          *   and the following code has no effect.  We assume for now that the
234          *   application restricts itself to the static TLB entries, i.e. to
235          *   virtual addresses 0xD0000000 thru 0xFFFFFFFF.)
236          */
237 #if XCHAL_HAVE_CACHEATTR || XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR \
238                 || (XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY)
239         movi    a2, _memmap_cacheattr_reset     /* note: absolute symbol, not a ptr */
240         cacheattr_set                           /* set CACHEATTR from a2 (clobbers a3-a8) */
241 #endif
242
243 #if XCHAL_HAVE_EXTERN_REGS && XCHAL_DCACHE_IS_COHERENT
244         /* Opt into coherence if present.  */
245         movi    a3, 1
246         movi    a2, XER_CCON
247         wer     a3, a2
248 #endif
249
250 #endif /* !XCHAL_HAVE_HALT */
251
252         /*
253          *  Unpack code and data (eg. copy ROMed segments to RAM, vectors into
254          *  their proper location, etc).
255          */
256
257 #if defined(XTOS_UNPACK)
258         movi    a2, _rom_store_table
259         beqz    a2, unpackdone
260 unpack: l32i    a3, a2, 0       // start vaddr
261         l32i    a4, a2, 4       // end vaddr
262         l32i    a5, a2, 8       // store vaddr
263         addi    a2, a2, 12
264         bgeu    a3, a4, upnext  // skip unless start < end
265 uploop: l32i    a6, a5, 0
266         addi    a5, a5, 4
267         s32i    a6, a3, 0
268         addi    a3, a3, 4
269         bltu    a3, a4, uploop
270         j       unpack
271 upnext: bnez    a3, unpack
272         bnez    a5, unpack
273 #endif /* XTOS_UNPACK */
274
275 unpackdone:
276
277 #if defined(XTOS_UNPACK) || defined(XTOS_MP)
278         /*
279          *  If writeback caches are configured and enabled, unpacked data must be
280          *  written out to memory before trying to execute it:
281          */
282         dcache_writeback_all    a2, a3, 0
283         icache_sync             a2      // ensure data written back is visible to i-fetch
284         /*
285          *  Note:  no need to invalidate the i-cache after the above, because we
286          *  already invalidated it further above and did not execute anything within
287          *  unpacked regions afterwards.  [Strictly speaking, if an unpacked region
288          *  follows this code very closely, it's possible for cache-ahead to have
289          *  cached a bit of that unpacked region, so in the future we may need to
290          *  invalidate the entire i-cache here again anyway.]
291          */
292 #endif
293
294
295 #if !XCHAL_HAVE_HALT    /* skip for TX */
296
297         /*
298          *  Now that we know the .lit4 section is present (if got unpacked)
299          *  (and if absolute literals are used), initialize LITBASE to use it.
300          */
301 #if XCHAL_HAVE_ABSOLUTE_LITERALS && XSHAL_USE_ABSOLUTE_LITERALS
302         /*
303          *  Switch from PC-relative to absolute (litbase-relative) L32R mode.
304          *  Set LITBASE to 256 kB beyond the start of the literals in .lit4
305          *  (aligns to the nearest 4 kB boundary, LITBASE does not have bits 1..11)
306          *  and set the enable bit (_lit4_start is assumed 4-byte aligned).
307          */
308         movi    a2, _lit4_start + 0x40001
309         wsr     a2, LITBASE
310         rsync
311 #endif /* have and use absolute literals */
312         .end    no-absolute-literals            // we can now start using absolute literals
313
314
315 //  Technically, this only needs to be done pre-LX2, assuming hard reset:
316 # if XCHAL_HAVE_WINDOWED && defined(__XTENSA_WINDOWED_ABI__)
317         //  Windowed register init, so we can call windowed code (eg. C code).
318         movi    a1, 1
319         wsr     a1, WINDOWSTART
320         //  The processor always clears WINDOWBASE at reset, so no need to clear it here.
321         //  It resets WINDOWSTART to 1 starting with LX2.0/X7.0 (RB-2006.0).
322         //  However, assuming hard reset is not yet always practical, so do this anyway:
323         wsr     a0, WINDOWBASE
324         rsync
325         movi    a0, 0                   // possibly a different a0, clear it
326 # endif
327
328 #if XCHAL_HW_MIN_VERSION < XTENSA_HWVERSION_RB_2006_0   /* only pre-LX2 needs this */
329         // Coprocessor option initialization
330 # if XCHAL_HAVE_CP
331         //movi  a2, XCHAL_CP_MASK       // enable existing CPs
332         //  To allow creating new coprocessors using TC that are not known
333         //  at GUI build time without having to explicitly enable them,
334         //  all CPENABLE bits must be set, even though they may not always
335         //  correspond to a coprocessor.
336         movi    a2, 0xFF        // enable *all* bits, to allow dynamic TIE
337         wsr     a2, CPENABLE
338 # endif
339
340         // Floating point coprocessor option initialization (at least
341         // rounding mode, so that floating point ops give predictable results)
342 # if XCHAL_HAVE_FP && !XCHAL_HAVE_VECTORFPU2005
343 #  define FCR   232     /* floating-point control register (user register number) */
344 #  define FSR   233     /* floating-point status register (user register number) */
345         rsync           /* wait for WSR to CPENABLE to complete before accessing FP coproc state */
346         wur     a0, FCR /* clear FCR (default rounding mode, round-nearest) */
347         wur     a0, FSR /* clear FSR */
348 # endif
349 #endif /* pre-LX2 */
350
351
352         /*
353          *  Initialize medium and high priority interrupt dispatchers:
354          */
355 #if HAVE_XSR
356
357 /*  For asm macros; works for positive a,b smaller than 1000:  */
358 # define GREATERTHAN(a,b)       (((b)-(a)) & ~0xFFF)
359
360 # ifndef XCHAL_DEBUGLEVEL               /* debug option not selected? */
361 #  define XCHAL_DEBUGLEVEL      99      /* bogus value outside 2..6 */
362 # endif
363
364         .macro  init_vector     level
365           .if GREATERTHAN(XCHAL_NUM_INTLEVELS+1,\level)
366             .if XCHAL_DEBUGLEVEL-\level
367               .weak   _Level&level&FromVector
368               movi    a4, _Level&level&FromVector
369               wsr     a4, EXCSAVE+\level
370               .if GREATERTHAN(\level,XCHAL_EXCM_LEVEL)
371                 movi    a5, _Pri_&level&_HandlerAddress
372                 s32i    a4, a5, 0
373                 /*  If user provides their own handler, that handler might
374                  *  not provide its own _Pri_<n>_HandlerAddress variable for
375                  *  linking handlers.  In that case, the reference below
376                  *  would pull in the XTOS handler anyway, causing a conflict.
377                  *  To avoid that, provide a weak version of it here:
378                  */
379                 .pushsection .data, "aw"
380                 .global  _Pri_&level&_HandlerAddress
381                 .weak   _Pri_&level&_HandlerAddress
382                 .align  4
383                 _Pri_&level&_HandlerAddress: .space 4
384                 .popsection
385               .endif
386             .endif
387           .endif
388         .endm
389
390         init_vector     2
391         init_vector     3
392         init_vector     4
393         init_vector     5
394         init_vector     6
395
396 #endif /*HAVE_XSR*/
397
398
399         /*
400          *  Complete reset initialization outside the vector,
401          *  to avoid requiring a vector that is larger than necessary.
402          *  This 2nd-stage startup code sets up the C Run-Time (CRT) and calls main().
403          *  
404          *  Here we use call0 not because we expect any return, but
405          *  because the assembler/linker dynamically sizes call0 as
406          *  needed (with -mlongcalls) which it doesn't with j or jx.
407          *  Note:  This needs to be call0 regardless of the selected ABI.
408          */
409         call0   _start          // jump to _start (in crt1-*.S)
410         /* does not return */
411
412 #else /* XCHAL_HAVE_HALT */
413
414         j       _start          // jump to _start (in crt1-*.S)
415                                 // (TX has max 64kB IRAM, so J always in range)
416
417         //  Paranoia -- double-check requirements / assumptions of this Xtensa TX code:
418 # if !defined(__XTENSA_CALL0_ABI__) || !XCHAL_HAVE_FULL_RESET || XCHAL_HAVE_INTERRUPTS || XCHAL_HAVE_CCOUNT || XCHAL_DTLB_ARF_WAYS || XCHAL_HAVE_DEBUG || XCHAL_HAVE_S32C1I || XCHAL_HAVE_ABSOLUTE_LITERALS || XCHAL_DCACHE_SIZE || XCHAL_ICACHE_SIZE || XCHAL_HAVE_PIF || XCHAL_HAVE_WINDOWED
419 #  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"
420 # endif
421
422 #endif /* XCHAL_HAVE_HALT */
423
424
425 #if (!XCHAL_HAVE_HALT || defined(XTOS_UNPACK)) && XCHAL_HAVE_IMEM_LOADSTORE
426         .size   _ResetHandler, . - _ResetHandler
427 #else
428         .size   _ResetVector, . - _ResetVector
429 #endif
430
431         .text
432         .global xthals_hw_configid0, xthals_hw_configid1
433         .global xthals_release_major, xthals_release_minor
434         .end    literal_prefix