~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/xtensa/kernel/entry.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/xtensa/kernel/entry.S (Architecture m68k) and /arch/alpha/kernel/entry.S (Architecture alpha)


                                                   >>   1 /* SPDX-License-Identifier: GPL-2.0 */
  1 /*                                                  2 /*
  2  * Low-level exception handling                !!   3  * arch/alpha/kernel/entry.S
  3  *                                             << 
  4  * This file is subject to the terms and condi << 
  5  * License.  See the file "COPYING" in the mai << 
  6  * for more details.                           << 
  7  *                                             << 
  8  * Copyright (C) 2004 - 2008 by Tensilica Inc. << 
  9  * Copyright (C) 2015 Cadence Design Systems I << 
 10  *                                             << 
 11  * Chris Zankel <chris@zankel.net>              << 
 12  *                                                  4  *
                                                   >>   5  * Kernel entry-points.
 13  */                                                 6  */
 14                                                     7 
 15 #include <linux/linkage.h>                     << 
 16 #include <linux/pgtable.h>                     << 
 17 #include <asm/asm-offsets.h>                        8 #include <asm/asm-offsets.h>
 18 #include <asm/asmmacro.h>                      << 
 19 #include <asm/processor.h>                     << 
 20 #include <asm/coprocessor.h>                   << 
 21 #include <asm/thread_info.h>                        9 #include <asm/thread_info.h>
 22 #include <asm/asm-uaccess.h>                   !!  10 #include <asm/pal.h>
                                                   >>  11 #include <asm/errno.h>
 23 #include <asm/unistd.h>                            12 #include <asm/unistd.h>
 24 #include <asm/ptrace.h>                        << 
 25 #include <asm/current.h>                       << 
 26 #include <asm/page.h>                          << 
 27 #include <asm/signal.h>                        << 
 28 #include <asm/tlbflush.h>                      << 
 29 #include <variant/tie-asm.h>                   << 
 30                                                << 
 31 /*                                             << 
 32  * Macro to find first bit set in WINDOWBASE f << 
 33  *                                             << 
 34  * 100....0 -> 1                               << 
 35  * 010....0 -> 2                               << 
 36  * 000....1 -> WSBITS                          << 
 37  */                                            << 
 38                                                << 
 39         .macro ffs_ws bit mask                 << 
 40                                                << 
 41 #if XCHAL_HAVE_NSA                             << 
 42         nsau    \bit, \mask                    << 
 43         addi    \bit, \bit, WSBITS - 32 + 1    << 
 44 #else                                          << 
 45         movi    \bit, WSBITS                   << 
 46 #if WSBITS > 16                                << 
 47         _bltui  \mask, 0x10000, 99f            << 
 48         addi    \bit, \bit, -16                << 
 49         extui   \mask, \mask, 16, 16           << 
 50 #endif                                         << 
 51 #if WSBITS > 8                                 << 
 52 99:     _bltui  \mask, 0x100, 99f              << 
 53         addi    \bit, \bit, -8                 << 
 54         srli    \mask, \mask, 8                << 
 55 #endif                                         << 
 56 99:     _bltui  \mask, 0x10, 99f               << 
 57         addi    \bit, \bit, -4                 << 
 58         srli    \mask, \mask, 4                << 
 59 99:     _bltui  \mask, 0x4, 99f                << 
 60         addi    \bit, \bit, -2                 << 
 61         srli    \mask, \mask, 2                << 
 62 99:     _bltui  \mask, 0x2, 99f                << 
 63         addi    \bit, \bit, -1                 << 
 64 99:                                            << 
 65                                                << 
 66 #endif                                         << 
 67         .endm                                  << 
 68                                                << 
 69                                                << 
 70         .macro  irq_save flags tmp             << 
 71 #if XTENSA_FAKE_NMI                            << 
 72 #if defined(CONFIG_DEBUG_KERNEL) && (LOCKLEVEL << 
 73         rsr     \flags, ps                     << 
 74         extui   \tmp, \flags, PS_INTLEVEL_SHIF << 
 75         bgei    \tmp, LOCKLEVEL, 99f           << 
 76         rsil    \tmp, LOCKLEVEL                << 
 77 99:                                            << 
 78 #else                                          << 
 79         movi    \tmp, LOCKLEVEL                << 
 80         rsr     \flags, ps                     << 
 81         or      \flags, \flags, \tmp           << 
 82         xsr     \flags, ps                     << 
 83         rsync                                  << 
 84 #endif                                         << 
 85 #else                                          << 
 86         rsil    \flags, LOCKLEVEL              << 
 87 #endif                                         << 
 88         .endm                                  << 
 89                                                << 
 90 /* ----------------- DEFAULT FIRST LEVEL EXCEP << 
 91                                                << 
 92 /*                                             << 
 93  * First-level exception handler for user exce << 
 94  * Save some special registers, extra states a << 
 95  * register file that were in use in the user  << 
 96  * exception code.                             << 
 97  * We save SAR (used to calculate WMASK), and  << 
 98  * save them for kernel exceptions).           << 
 99  *                                             << 
100  * Entry condition for user_exception:         << 
101  *                                             << 
102  *   a0:        trashed, original value saved  << 
103  *   a1:        a1                             << 
104  *   a2:        new stack pointer, original va << 
105  *   a3:        a3                             << 
106  *   depc:      a2, original value saved on st << 
107  *   excsave1:  dispatch table                 << 
108  *                                             << 
109  *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS << 
110  *           <  VALID_DOUBLE_EXCEPTION_ADDRESS << 
111  *                                             << 
112  * Entry condition for _user_exception:        << 
113  *                                             << 
114  *   a0-a3 and depc have been saved to PT_AREG << 
115  *   excsave has been restored, and            << 
116  *   stack pointer (a1) has been set.          << 
117  *                                             << 
118  * Note: _user_exception might be at an odd ad << 
119  */                                            << 
120         .literal_position                      << 
121                                                << 
122 ENTRY(user_exception)                          << 
123                                                << 
124         /* Save a1, a2, a3, and set SP. */     << 
125                                                << 
126         rsr     a0, depc                       << 
127         s32i    a1, a2, PT_AREG1               << 
128         s32i    a0, a2, PT_AREG2               << 
129         s32i    a3, a2, PT_AREG3               << 
130         mov     a1, a2                         << 
131                                                << 
132         .globl _user_exception                 << 
133 _user_exception:                               << 
134                                                << 
135         /* Save SAR and turn off single steppi << 
136                                                << 
137         movi    a2, 0                          << 
138         wsr     a2, depc                # term << 
139         rsr     a3, sar                        << 
140         xsr     a2, icountlevel                << 
141         s32i    a3, a1, PT_SAR                 << 
142         s32i    a2, a1, PT_ICOUNTLEVEL         << 
143                                                << 
144 #if XCHAL_HAVE_THREADPTR                       << 
145         rur     a2, threadptr                  << 
146         s32i    a2, a1, PT_THREADPTR           << 
147 #endif                                         << 
148                                                << 
149         /* Rotate ws so that the current windo << 
150         /* Assume ws = xxwww1yyyy. Rotate ws r << 
151                                                << 
152 #if defined(USER_SUPPORT_WINDOWED)             << 
153         rsr     a2, windowbase                 << 
154         rsr     a3, windowstart                << 
155         ssr     a2                             << 
156         s32i    a2, a1, PT_WINDOWBASE          << 
157         s32i    a3, a1, PT_WINDOWSTART         << 
158         slli    a2, a3, 32-WSBITS              << 
159         src     a2, a3, a2                     << 
160         srli    a2, a2, 32-WSBITS              << 
161         s32i    a2, a1, PT_WMASK        # need << 
162 #else                                          << 
163         movi    a2, 0                          << 
164         movi    a3, 1                          << 
165         s32i    a2, a1, PT_WINDOWBASE          << 
166         s32i    a3, a1, PT_WINDOWSTART         << 
167         s32i    a3, a1, PT_WMASK               << 
168 #endif                                         << 
169                                                << 
170         /* Save only live registers. */        << 
171                                                << 
172 UABI_W  _bbsi.l a2, 1, .Lsave_window_registers << 
173         s32i    a4, a1, PT_AREG4               << 
174         s32i    a5, a1, PT_AREG5               << 
175         s32i    a6, a1, PT_AREG6               << 
176         s32i    a7, a1, PT_AREG7               << 
177 UABI_W  _bbsi.l a2, 2, .Lsave_window_registers << 
178         s32i    a8, a1, PT_AREG8               << 
179         s32i    a9, a1, PT_AREG9               << 
180         s32i    a10, a1, PT_AREG10             << 
181         s32i    a11, a1, PT_AREG11             << 
182 UABI_W  _bbsi.l a2, 3, .Lsave_window_registers << 
183         s32i    a12, a1, PT_AREG12             << 
184         s32i    a13, a1, PT_AREG13             << 
185         s32i    a14, a1, PT_AREG14             << 
186         s32i    a15, a1, PT_AREG15             << 
187                                                << 
188 #if defined(USER_SUPPORT_WINDOWED)             << 
189         /* If only one valid frame skip saving << 
190                                                << 
191         beqi    a2, 1, common_exception        << 
192                                                << 
193         /* Save the remaining registers.       << 
194          * We have to save all registers up to << 
195          * the right, except the current frame << 
196          * Assume a2 is:  001001000110001      << 
197          * All register frames starting from t << 
198          * must be saved.                      << 
199          */                                    << 
200 .Lsave_window_registers:                       << 
201         addi    a3, a2, -1              # elim << 
202         neg     a3, a3                  # yyyy << 
203         and     a3, a3, a2              # max. << 
204                                                << 
205         /* Find number of frames to save */    << 
206                                                << 
207         ffs_ws  a0, a3                  # numb << 
208                                                << 
209         /* Store information into WMASK:       << 
210          * bits 0..3: xxx1 masked lower 4 bits << 
211          * bits 4...: number of valid 4-regist << 
212          */                                    << 
213                                                << 
214         slli    a3, a0, 4               # numb << 
215         extui   a2, a2, 0, 4            # mask << 
216         or      a2, a3, a2                     << 
217         s32i    a2, a1, PT_WMASK        # need << 
218                                                << 
219         /* Save 4 registers at a time */       << 
220                                                << 
221 1:      rotw    -1                             << 
222         s32i    a0, a5, PT_AREG_END - 16       << 
223         s32i    a1, a5, PT_AREG_END - 12       << 
224         s32i    a2, a5, PT_AREG_END - 8        << 
225         s32i    a3, a5, PT_AREG_END - 4        << 
226         addi    a0, a4, -1                     << 
227         addi    a1, a5, -16                    << 
228         _bnez   a0, 1b                         << 
229                                                << 
230         /* WINDOWBASE still in SAR! */         << 
231                                                << 
232         rsr     a2, sar                 # orig << 
233         movi    a3, 1                          << 
234         ssl     a2                             << 
235         sll     a3, a3                         << 
236         wsr     a3, windowstart         # set  << 
237         wsr     a2, windowbase          # and  << 
238         rsync                                  << 
239                                                << 
240         /* We are back to the original stack p << 
241 #endif                                         << 
242         /* Now, jump to the common exception h << 
243                                                << 
244         j       common_exception               << 
245                                                << 
246 ENDPROC(user_exception)                        << 
247                                                << 
248 /*                                             << 
249  * First-level exit handler for kernel excepti << 
250  * Save special registers and the live window  << 
251  * Note: Even though we changes the stack poin << 
252  *       MOVSP here, as we do that when we ret << 
253  *       (See comment in the kernel exception  << 
254  *                                             << 
255  * Entry condition for kernel_exception:       << 
256  *                                             << 
257  *   a0:        trashed, original value saved  << 
258  *   a1:        a1                             << 
259  *   a2:        new stack pointer, original in << 
260  *   a3:        a3                             << 
261  *   depc:      a2, original value saved on st << 
262  *   excsave_1: dispatch table                 << 
263  *                                             << 
264  *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS << 
265  *           <  VALID_DOUBLE_EXCEPTION_ADDRESS << 
266  *                                             << 
267  * Entry condition for _kernel_exception:      << 
268  *                                             << 
269  *   a0-a3 and depc have been saved to PT_AREG << 
270  *   excsave has been restored, and            << 
271  *   stack pointer (a1) has been set.          << 
272  *                                             << 
273  * Note: _kernel_exception might be at an odd  << 
274  */                                            << 
275                                                << 
276 ENTRY(kernel_exception)                        << 
277                                                << 
278         /* Save a1, a2, a3, and set SP. */     << 
279                                                << 
280         rsr     a0, depc                # get  << 
281         s32i    a1, a2, PT_AREG1               << 
282         s32i    a0, a2, PT_AREG2               << 
283         s32i    a3, a2, PT_AREG3               << 
284         mov     a1, a2                         << 
285                                                << 
286         .globl _kernel_exception               << 
287 _kernel_exception:                             << 
288                                                << 
289         /* Save SAR and turn off single steppi << 
290                                                << 
291         movi    a2, 0                          << 
292         rsr     a3, sar                        << 
293         xsr     a2, icountlevel                << 
294         s32i    a3, a1, PT_SAR                 << 
295         s32i    a2, a1, PT_ICOUNTLEVEL         << 
296                                                << 
297 #if defined(__XTENSA_WINDOWED_ABI__)           << 
298         /* Rotate ws so that the current windo << 
299         /* Assume ws = xxwww1yyyy. Rotate ws r << 
300                                                << 
301         rsr     a2, windowbase          # don' << 
302         rsr     a3, windowstart         # need << 
303         ssr     a2                             << 
304         slli    a2, a3, 32-WSBITS              << 
305         src     a2, a3, a2                     << 
306         srli    a2, a2, 32-WSBITS              << 
307         s32i    a2, a1, PT_WMASK        # need << 
308 #endif                                         << 
309                                                << 
310         /* Save only the live window-frame */  << 
311                                                << 
312 KABI_W  _bbsi.l a2, 1, 1f                      << 
313         s32i    a4, a1, PT_AREG4               << 
314         s32i    a5, a1, PT_AREG5               << 
315         s32i    a6, a1, PT_AREG6               << 
316         s32i    a7, a1, PT_AREG7               << 
317 KABI_W  _bbsi.l a2, 2, 1f                      << 
318         s32i    a8, a1, PT_AREG8               << 
319         s32i    a9, a1, PT_AREG9               << 
320         s32i    a10, a1, PT_AREG10             << 
321         s32i    a11, a1, PT_AREG11             << 
322 KABI_W  _bbsi.l a2, 3, 1f                      << 
323         s32i    a12, a1, PT_AREG12             << 
324         s32i    a13, a1, PT_AREG13             << 
325         s32i    a14, a1, PT_AREG14             << 
326         s32i    a15, a1, PT_AREG15             << 
327                                                << 
328 #ifdef __XTENSA_WINDOWED_ABI__                 << 
329         _bnei   a2, 1, 1f                      << 
330         /* Copy spill slots of a0 and a1 to im << 
331          * in order to keep exception stack co << 
332          */                                    << 
333         l32i    a3, a1, PT_KERNEL_SIZE         << 
334         l32i    a0, a1, PT_KERNEL_SIZE + 4     << 
335         s32e    a3, a1, -16                    << 
336         s32e    a0, a1, -12                    << 
337 #endif                                         << 
338 1:                                             << 
339         l32i    a0, a1, PT_AREG0        # rest << 
340         wsr     a0, depc                       << 
341                                                << 
342 /*                                             << 
343  * This is the common exception handler.       << 
344  * We get here from the user exception handler << 
345  * from the kernel exception handler.          << 
346  * Save the remaining special registers, switc << 
347  * to the second-level exception handler.      << 
348  *                                             << 
349  */                                            << 
350                                                << 
351 common_exception:                              << 
352                                                << 
353         /* Save some registers, disable loops  << 
354                                                << 
355         rsr     a2, debugcause                 << 
356         rsr     a3, epc1                       << 
357         s32i    a2, a1, PT_DEBUGCAUSE          << 
358         s32i    a3, a1, PT_PC                  << 
359                                                << 
360         movi    a2, NO_SYSCALL                 << 
361         rsr     a3, excvaddr                   << 
362         s32i    a2, a1, PT_SYSCALL             << 
363         movi    a2, 0                          << 
364         s32i    a3, a1, PT_EXCVADDR            << 
365 #if XCHAL_HAVE_LOOPS                           << 
366         xsr     a2, lcount                     << 
367         s32i    a2, a1, PT_LCOUNT              << 
368 #endif                                         << 
369                                                << 
370 #if XCHAL_HAVE_EXCLUSIVE                       << 
371         /* Clear exclusive access monitor set  << 
372         clrex                                  << 
373 #endif                                         << 
374                                                << 
375         /* It is now save to restore the EXC_T << 
376                                                << 
377         rsr     a2, exccause                   << 
378         movi    a3, 0                          << 
379         rsr     a0, excsave1                   << 
380         s32i    a2, a1, PT_EXCCAUSE            << 
381         s32i    a3, a0, EXC_TABLE_FIXUP        << 
382                                                << 
383         /* All unrecoverable states are saved  << 
384          * Now we can allow exceptions again.  << 
385          * PS.INTLEVEL is set to LOCKLEVEL dis << 
386          * otherwise it's left unchanged.      << 
387          *                                     << 
388          * Set PS(EXCM = 0, UM = 0, RING = 0,  << 
389          */                                    << 
390                                                << 
391         rsr     a3, ps                         << 
392         s32i    a3, a1, PT_PS           # save << 
393                                                << 
394 #if XTENSA_FAKE_NMI                            << 
395         /* Correct PS needs to be saved in the << 
396          * - in case of exception or level-1 i << 
397          *   and is already saved.             << 
398          * - in case of medium level interrupt << 
399          */                                    << 
400         movi    a0, EXCCAUSE_MAPPED_NMI        << 
401         extui   a3, a3, PS_INTLEVEL_SHIFT, PS_ << 
402         beq     a2, a0, .Lmedium_level_irq     << 
403         bnei    a2, EXCCAUSE_LEVEL1_INTERRUPT, << 
404         beqz    a3, .Llevel1_irq        # leve << 
405                                                << 
406 .Lmedium_level_irq:                            << 
407         rsr     a0, excsave2                   << 
408         s32i    a0, a1, PT_PS           # save << 
409         bgei    a3, LOCKLEVEL, .Lexception     << 
410                                                << 
411 .Llevel1_irq:                                  << 
412         movi    a3, LOCKLEVEL                  << 
413                                                << 
414 .Lexception:                                   << 
415 KABI_W  movi    a0, PS_WOE_MASK                << 
416 KABI_W  or      a3, a3, a0                     << 
417 #else                                          << 
418         addi    a2, a2, -EXCCAUSE_LEVEL1_INTER << 
419         movi    a0, LOCKLEVEL                  << 
420         extui   a3, a3, PS_INTLEVEL_SHIFT, PS_ << 
421                                         # a3 = << 
422         moveqz  a3, a0, a2              # a3 = << 
423 KABI_W  movi    a2, PS_WOE_MASK                << 
424 KABI_W  or      a3, a3, a2                     << 
425 #endif                                         << 
426                                                << 
427         /* restore return address (or 0 if ret << 
428         rsr     a0, depc                       << 
429         wsr     a3, ps                         << 
430         rsync                           # PS.W << 
431                                                << 
432         /* Save lbeg, lend */                  << 
433 #if XCHAL_HAVE_LOOPS                           << 
434         rsr     a4, lbeg                       << 
435         rsr     a3, lend                       << 
436         s32i    a4, a1, PT_LBEG                << 
437         s32i    a3, a1, PT_LEND                << 
438 #endif                                         << 
439                                                << 
440         /* Save SCOMPARE1 */                   << 
441                                                << 
442 #if XCHAL_HAVE_S32C1I                          << 
443         rsr     a3, scompare1                  << 
444         s32i    a3, a1, PT_SCOMPARE1           << 
445 #endif                                         << 
446                                                << 
447         /* Save optional registers. */         << 
448                                                << 
449         save_xtregs_opt a1 a3 a4 a5 a6 a7 PT_X << 
450                                                << 
451 #ifdef CONFIG_TRACE_IRQFLAGS                   << 
452         rsr             abi_tmp0, ps           << 
453         extui           abi_tmp0, abi_tmp0, PS << 
454         beqz            abi_tmp0, 1f           << 
455         abi_call        trace_hardirqs_off     << 
456 1:                                             << 
457 #endif                                         << 
458 #ifdef CONFIG_CONTEXT_TRACKING_USER            << 
459         l32i            abi_tmp0, a1, PT_PS    << 
460         bbci.l          abi_tmp0, PS_UM_BIT, 1 << 
461         abi_call        user_exit_callable     << 
462 1:                                             << 
463 #endif                                         << 
464                                                << 
465         /* Go to second-level dispatcher. Set  << 
466          * exception handler and call the exce << 
467          */                                    << 
468                                                << 
469         l32i            abi_arg1, a1, PT_EXCCA << 
470         rsr             abi_tmp0, excsave1     << 
471         addx4           abi_tmp0, abi_arg1, ab << 
472         l32i            abi_tmp0, abi_tmp0, EX << 
473         mov             abi_arg0, a1           << 
474                                                << 
475         /* Call the second-level handler */    << 
476                                                << 
477         abi_callx       abi_tmp0               << 
478                                                << 
479         /* Jump here for exception exit */     << 
480         .global common_exception_return        << 
481 common_exception_return:                       << 
482                                                << 
483 #if XTENSA_FAKE_NMI                            << 
484         l32i            abi_tmp0, a1, PT_EXCCA << 
485         movi            abi_tmp1, EXCCAUSE_MAP << 
486         l32i            abi_saved1, a1, PT_PS  << 
487         beq             abi_tmp0, abi_tmp1, .L << 
488 #endif                                         << 
489 .Ltif_loop:                                    << 
490         irq_save        abi_tmp0, abi_tmp1     << 
491 #ifdef CONFIG_TRACE_IRQFLAGS                   << 
492         abi_call        trace_hardirqs_off     << 
493 #endif                                         << 
494                                                << 
495         /* Jump if we are returning from kerne << 
496                                                << 
497         l32i            abi_saved1, a1, PT_PS  << 
498         GET_THREAD_INFO(abi_tmp0, a1)          << 
499         l32i            abi_saved0, abi_tmp0,  << 
500         _bbci.l         abi_saved1, PS_UM_BIT, << 
501                                                << 
502         /* Specific to a user exception exit:  << 
503          * We need to check some flags for sig << 
504          * and have to restore WB and WS, extr << 
505          * in the register file that were in u << 
506          * Note that we don't disable interrup << 
507          */                                    << 
508                                                << 
509         _bbsi.l         abi_saved0, TIF_NEED_R << 
510         movi            abi_tmp0, _TIF_SIGPEND << 
511         bnone           abi_saved0, abi_tmp0,  << 
512                                                << 
513         l32i            abi_tmp0, a1, PT_DEPC  << 
514         bgeui           abi_tmp0, VALID_DOUBLE << 
515                                                << 
516         /* Call do_signal() */                 << 
517                                                << 
518 #ifdef CONFIG_TRACE_IRQFLAGS                   << 
519         abi_call        trace_hardirqs_on      << 
520 #endif                                         << 
521         rsil            abi_tmp0, 0            << 
522         mov             abi_arg0, a1           << 
523         abi_call        do_notify_resume       << 
524         j               .Ltif_loop             << 
525                                                << 
526 .Lresched:                                     << 
527 #ifdef CONFIG_TRACE_IRQFLAGS                   << 
528         abi_call        trace_hardirqs_on      << 
529 #endif                                         << 
530         rsil            abi_tmp0, 0            << 
531         abi_call        schedule        # void << 
532         j               .Ltif_loop             << 
533                                                << 
534 .Lexit_tif_loop_kernel:                        << 
535 #ifdef CONFIG_PREEMPTION                       << 
536         _bbci.l         abi_saved0, TIF_NEED_R << 
537                                                << 
538         /* Check current_thread_info->preempt_ << 
539                                                << 
540         l32i            abi_tmp1, abi_tmp0, TI << 
541         bnez            abi_tmp1, .Lrestore_st << 
542         abi_call        preempt_schedule_irq   << 
543 #endif                                         << 
544         j               .Lrestore_state        << 
545                                                << 
546 .Lexit_tif_loop_user:                          << 
547 #ifdef CONFIG_CONTEXT_TRACKING_USER            << 
548         abi_call        user_enter_callable    << 
549 #endif                                         << 
550 #ifdef CONFIG_HAVE_HW_BREAKPOINT               << 
551         _bbci.l         abi_saved0, TIF_DB_DIS << 
552         abi_call        restore_dbreak         << 
553 1:                                             << 
554 #endif                                         << 
555 #ifdef CONFIG_DEBUG_TLB_SANITY                 << 
556         l32i            abi_tmp0, a1, PT_DEPC  << 
557         bgeui           abi_tmp0, VALID_DOUBLE << 
558         abi_call        check_tlb_sanity       << 
559 #endif                                         << 
560                                                << 
561 .Lrestore_state:                               << 
562 #ifdef CONFIG_TRACE_IRQFLAGS                   << 
563         extui           abi_tmp0, abi_saved1,  << 
564         bgei            abi_tmp0, LOCKLEVEL, 1 << 
565         abi_call        trace_hardirqs_on      << 
566 1:                                             << 
567 #endif                                         << 
568         /*                                     << 
569          * Restore optional registers.         << 
570          * abi_arg* are used as temporary regi << 
571          */                                    << 
572                                                << 
573         load_xtregs_opt a1 abi_tmp0 abi_arg0 a << 
574                                                << 
575         /* Restore SCOMPARE1 */                << 
576                                                << 
577 #if XCHAL_HAVE_S32C1I                          << 
578         l32i            abi_tmp0, a1, PT_SCOMP << 
579         wsr             abi_tmp0, scompare1    << 
580 #endif                                         << 
581         wsr             abi_saved1, ps         << 
582         _bbci.l         abi_saved1, PS_UM_BIT, << 
583                                                << 
584 user_exception_exit:                           << 
585                                                << 
586         /* Restore the state of the task and r << 
587                                                    13 
588 #if defined(USER_SUPPORT_WINDOWED)             !!  14         .text
589         /* Switch to the user thread WINDOWBAS !!  15         .set noat
590                                                !!  16         .cfi_sections   .debug_frame
591         l32i    a2, a1, PT_WINDOWBASE          << 
592         l32i    a3, a1, PT_WINDOWSTART         << 
593         wsr     a1, depc                # use  << 
594         wsr     a3, windowstart         # rest << 
595         ssr     a2                      # pres << 
596         wsr     a2, windowbase          # swit << 
597         rsync                                  << 
598         rsr     a1, depc                # rest << 
599         l32i    a2, a1, PT_WMASK        # regi << 
600         rotw    -1                      # we r << 
601         _bltui  a6, 16, .Lclear_regs    # only << 
602                                                << 
603         /* The working registers are a0 and a3 << 
604          * a4..a7.  Be careful not to destroy  << 
605          * Note: wmask has the format YYYYM:   << 
606          *       Y: number of registers saved  << 
607          *       M: 4 bit mask of first 16 reg << 
608          */                                    << 
609                                                << 
610         mov     a2, a6                         << 
611         mov     a3, a5                         << 
612                                                << 
613 1:      rotw    -1                      # a0.. << 
614         addi    a3, a7, -4*4            # next << 
615         addi    a2, a6, -16             # decr << 
616         l32i    a4, a3, PT_AREG_END + 0        << 
617         l32i    a5, a3, PT_AREG_END + 4        << 
618         l32i    a6, a3, PT_AREG_END + 8        << 
619         l32i    a7, a3, PT_AREG_END + 12       << 
620         _bgeui  a2, 16, 1b                     << 
621                                                << 
622         /* Clear unrestored registers (don't l << 
623                                                << 
624 .Lclear_regs:                                  << 
625         rsr     a0, windowbase                 << 
626         rsr     a3, sar                        << 
627         sub     a3, a0, a3                     << 
628         beqz    a3, 2f                         << 
629         extui   a3, a3, 0, WBBITS              << 
630                                                << 
631 1:      rotw    -1                             << 
632         addi    a3, a7, -1                     << 
633         movi    a4, 0                          << 
634         movi    a5, 0                          << 
635         movi    a6, 0                          << 
636         movi    a7, 0                          << 
637         bgei    a3, 1, 1b                      << 
638                                                << 
639         /* We are back were we were when we st << 
640          * Note: a2 still contains WMASK (if w << 
641          *       frame where we had loaded a2) << 
642          *       (if we have restored WSBITS-1 << 
643          */                                    << 
644 2:                                             << 
645 #else                                          << 
646         movi    a2, 1                          << 
647 #endif                                         << 
648 #if XCHAL_HAVE_THREADPTR                       << 
649         l32i    a3, a1, PT_THREADPTR           << 
650         wur     a3, threadptr                  << 
651 #endif                                         << 
652                                                << 
653         j       common_exception_exit          << 
654                                                << 
655         /* This is the kernel exception exit.  << 
656          * We avoided to do a MOVSP when we en << 
657          * have to do it here.                 << 
658          */                                    << 
659                                                << 
660 kernel_exception_exit:                         << 
661                                                << 
662 #if defined(__XTENSA_WINDOWED_ABI__)           << 
663         /* Check if we have to do a movsp.     << 
664          *                                     << 
665          * We only have to do a movsp if the p << 
666          * been spilled to the *temporary* exc << 
667          * task's stack. This is the case if t << 
668          * WINDOWSTART for the previous window << 
669          * (not spilled) but is zero now (spil << 
670          * If this bit is zero, all other bits << 
671          * current window frame are also zero. << 
672          * 'and' WINDOWSTART and WINDOWSTART-1 << 
673          *                                     << 
674          *  (XXXXXX1[0]* - 1) AND XXXXXX1[0]*  << 
675          *                                     << 
676          * The result is zero only if one bit  << 
677          *                                     << 
678          * (Note: We might have gone through s << 
679          *        we come back to the current  << 
680          *        different from the time the  << 
681          */                                    << 
682                                                << 
683         /* Test WINDOWSTART before and after t << 
684          * We actually have WMASK, so we only  << 
685          */                                    << 
686                                                << 
687         l32i    a2, a1, PT_WMASK               << 
688         _beqi   a2, 1, common_exception_exit   << 
689                                                << 
690         /* Test WINDOWSTART now. If spilled, d << 
691                                                << 
692         rsr     a3, windowstart                << 
693         addi    a0, a3, -1                     << 
694         and     a3, a3, a0                     << 
695         _bnez   a3, common_exception_exit      << 
696                                                << 
697         /* Do a movsp (we returned from a call << 
698                                                << 
699         addi    a0, a1, -16                    << 
700         l32i    a3, a0, 0                      << 
701         l32i    a4, a0, 4                      << 
702         s32i    a3, a1, PT_KERNEL_SIZE + 0     << 
703         s32i    a4, a1, PT_KERNEL_SIZE + 4     << 
704         l32i    a3, a0, 8                      << 
705         l32i    a4, a0, 12                     << 
706         s32i    a3, a1, PT_KERNEL_SIZE + 8     << 
707         s32i    a4, a1, PT_KERNEL_SIZE + 12    << 
708                                                << 
709         /* Common exception exit.              << 
710          * We restore the special register and << 
711          * return from the exception.          << 
712          *                                     << 
713          * Note: We expect a2 to hold PT_WMASK << 
714          */                                    << 
715 #else                                          << 
716         movi    a2, 1                          << 
717 #endif                                         << 
718                                                << 
719 common_exception_exit:                         << 
720                                                << 
721         /* Restore address registers. */       << 
722                                                << 
723         _bbsi.l a2, 1, 1f                      << 
724         l32i    a4,  a1, PT_AREG4              << 
725         l32i    a5,  a1, PT_AREG5              << 
726         l32i    a6,  a1, PT_AREG6              << 
727         l32i    a7,  a1, PT_AREG7              << 
728         _bbsi.l a2, 2, 1f                      << 
729         l32i    a8,  a1, PT_AREG8              << 
730         l32i    a9,  a1, PT_AREG9              << 
731         l32i    a10, a1, PT_AREG10             << 
732         l32i    a11, a1, PT_AREG11             << 
733         _bbsi.l a2, 3, 1f                      << 
734         l32i    a12, a1, PT_AREG12             << 
735         l32i    a13, a1, PT_AREG13             << 
736         l32i    a14, a1, PT_AREG14             << 
737         l32i    a15, a1, PT_AREG15             << 
738                                                << 
739         /* Restore PC, SAR */                  << 
740                                                << 
741 1:      l32i    a2, a1, PT_PC                  << 
742         l32i    a3, a1, PT_SAR                 << 
743         wsr     a2, epc1                       << 
744         wsr     a3, sar                        << 
745                                                << 
746         /* Restore LBEG, LEND, LCOUNT */       << 
747 #if XCHAL_HAVE_LOOPS                           << 
748         l32i    a2, a1, PT_LBEG                << 
749         l32i    a3, a1, PT_LEND                << 
750         wsr     a2, lbeg                       << 
751         l32i    a2, a1, PT_LCOUNT              << 
752         wsr     a3, lend                       << 
753         wsr     a2, lcount                     << 
754 #endif                                         << 
755                                                << 
756         /* We control single stepping through  << 
757                                                << 
758         l32i    a2, a1, PT_ICOUNTLEVEL         << 
759         movi    a3, -2                         << 
760         wsr     a2, icountlevel                << 
761         wsr     a3, icount                     << 
762                                                << 
763         /* Check if it was double exception. * << 
764                                                << 
765         l32i    a0, a1, PT_DEPC                << 
766         l32i    a3, a1, PT_AREG3               << 
767         l32i    a2, a1, PT_AREG2               << 
768         _bgeui  a0, VALID_DOUBLE_EXCEPTION_ADD << 
769                                                << 
770         /* Restore a0...a3 and return */       << 
771                                                << 
772         l32i    a0, a1, PT_AREG0               << 
773         l32i    a1, a1, PT_AREG1               << 
774         rfe                                    << 
775                                                << 
776 1:      wsr     a0, depc                       << 
777         l32i    a0, a1, PT_AREG0               << 
778         l32i    a1, a1, PT_AREG1               << 
779         rfde                                   << 
780                                                << 
781 ENDPROC(kernel_exception)                      << 
782                                                << 
783 /*                                             << 
784  * Debug exception handler.                    << 
785  *                                             << 
786  * Currently, we don't support KGDB, so only u << 
787  *                                             << 
788  * When we get here,  a0 is trashed and saved  << 
789  */                                            << 
790                                                << 
791         .literal_position                      << 
792                                                << 
793 ENTRY(debug_exception)                         << 
794                                                << 
795         rsr     a0, SREG_EPS + XCHAL_DEBUGLEVE << 
796         bbsi.l  a0, PS_EXCM_BIT, .Ldebug_excep << 
797                                                << 
798         /* Set EPC1 and EXCCAUSE */            << 
799                                                << 
800         wsr     a2, depc                # save << 
801         rsr     a2, SREG_EPC + XCHAL_DEBUGLEVE << 
802         wsr     a2, epc1                       << 
803                                                << 
804         movi    a2, EXCCAUSE_MAPPED_DEBUG      << 
805         wsr     a2, exccause                   << 
806                                                << 
807         /* Restore PS to the value before the  << 
808                                                << 
809         movi    a2, 1 << PS_EXCM_BIT           << 
810         or      a2, a0, a2                     << 
811         wsr     a2, ps                         << 
812                                                << 
813         /* Switch to kernel/user stack, restor << 
814                                                << 
815         bbsi.l  a2, PS_UM_BIT, .Ldebug_excepti << 
816         addi    a2, a1, -16 - PT_KERNEL_SIZE   << 
817                                                << 
818 .Ldebug_exception_continue:                    << 
819         l32i    a0, a3, DT_DEBUG_SAVE          << 
820         s32i    a1, a2, PT_AREG1               << 
821         s32i    a0, a2, PT_AREG0               << 
822         movi    a0, 0                          << 
823         s32i    a0, a2, PT_DEPC         # mark << 
824         xsr     a3, SREG_EXCSAVE + XCHAL_DEBUG << 
825         xsr     a0, depc                       << 
826         s32i    a3, a2, PT_AREG3               << 
827         s32i    a0, a2, PT_AREG2               << 
828         mov     a1, a2                         << 
829                                                << 
830         /* Debug exception is handled as an ex << 
831          * likely be enabled in the common exc << 
832          * preemption if we have HW breakpoint << 
833          * meaning.                            << 
834          */                                    << 
835 #if defined(CONFIG_PREEMPT_COUNT) && defined(C << 
836         GET_THREAD_INFO(a2, a1)                << 
837         l32i    a3, a2, TI_PRE_COUNT           << 
838         addi    a3, a3, 1                      << 
839         s32i    a3, a2, TI_PRE_COUNT           << 
840 #endif                                         << 
841                                                << 
842         rsr     a2, ps                         << 
843         bbsi.l  a2, PS_UM_BIT, _user_exception << 
844         j       _kernel_exception              << 
845                                                << 
846 .Ldebug_exception_user:                        << 
847         rsr     a2, excsave1                   << 
848         l32i    a2, a2, EXC_TABLE_KSTK  # load << 
849         j       .Ldebug_exception_continue     << 
850                                                << 
851 .Ldebug_exception_in_exception:                << 
852 #ifdef CONFIG_HAVE_HW_BREAKPOINT               << 
853         /* Debug exception while in exception  << 
854          * window overflow/underflow handler o << 
855          * data breakpoint, in which case save << 
856          * breakpoints, single-step faulting i << 
857          * breakpoints.                        << 
858          */                                    << 
859                                                << 
860         bbci.l  a0, PS_UM_BIT, .Ldebug_excepti << 
861                                                << 
862         rsr     a0, debugcause                 << 
863         bbsi.l  a0, DEBUGCAUSE_DBREAK_BIT, .Ld << 
864                                                << 
865         .set    _index, 0                      << 
866         .rept   XCHAL_NUM_DBREAK               << 
867         l32i    a0, a3, DT_DBREAKC_SAVE + _ind << 
868         wsr     a0, SREG_DBREAKC + _index      << 
869         .set    _index, _index + 1             << 
870         .endr                                  << 
871                                                << 
872         l32i    a0, a3, DT_ICOUNT_LEVEL_SAVE   << 
873         wsr     a0, icountlevel                << 
874                                                << 
875         l32i    a0, a3, DT_ICOUNT_SAVE         << 
876         xsr     a0, icount                     << 
877                                                << 
878         l32i    a0, a3, DT_DEBUG_SAVE          << 
879         xsr     a3, SREG_EXCSAVE + XCHAL_DEBUG << 
880         rfi     XCHAL_DEBUGLEVEL               << 
881                                                << 
882 .Ldebug_save_dbreak:                           << 
883         .set    _index, 0                      << 
884         .rept   XCHAL_NUM_DBREAK               << 
885         movi    a0, 0                          << 
886         xsr     a0, SREG_DBREAKC + _index      << 
887         s32i    a0, a3, DT_DBREAKC_SAVE + _ind << 
888         .set    _index, _index + 1             << 
889         .endr                                  << 
890                                                << 
891         movi    a0, XCHAL_EXCM_LEVEL + 1       << 
892         xsr     a0, icountlevel                << 
893         s32i    a0, a3, DT_ICOUNT_LEVEL_SAVE   << 
894                                                << 
895         movi    a0, 0xfffffffe                 << 
896         xsr     a0, icount                     << 
897         s32i    a0, a3, DT_ICOUNT_SAVE         << 
898                                                << 
899         l32i    a0, a3, DT_DEBUG_SAVE          << 
900         xsr     a3, SREG_EXCSAVE + XCHAL_DEBUG << 
901         rfi     XCHAL_DEBUGLEVEL               << 
902 #else                                          << 
903         /* Debug exception while in exception  << 
904         j       .Ldebug_exception_in_exception << 
905 #endif                                         << 
906                                                << 
907 ENDPROC(debug_exception)                       << 
908                                                << 
909 /*                                             << 
910  * We get here in case of an unrecoverable exc << 
911  * The only thing we can do is to be nice and  << 
912  * We only produce a single stack frame for pa << 
913  *                                             << 
914  *                                             << 
915  * Entry conditions:                           << 
916  *                                             << 
917  *   - a0 contains the caller address; origina << 
918  *   - the original a0 contains a valid return << 
919  *   - a2 contains a valid stackpointer        << 
920  *                                             << 
921  * Notes:                                      << 
922  *                                             << 
923  *   - If the stack pointer could be invalid,  << 
924  *     dummy stack pointer (e.g. the stack of  << 
925  *                                             << 
926  *   - If the return address could be invalid, << 
927  *     to 0, so the backtrace would stop.      << 
928  *                                             << 
929  */                                            << 
930         .align 4                               << 
931 unrecoverable_text:                            << 
932         .ascii "Unrecoverable error in excepti << 
933                                                << 
934         .literal_position                      << 
935                                                << 
936 ENTRY(unrecoverable_exception)                 << 
937                                                << 
938 #if XCHAL_HAVE_WINDOWED                        << 
939         movi    a0, 1                          << 
940         movi    a1, 0                          << 
941                                                << 
942         wsr     a0, windowstart                << 
943         wsr     a1, windowbase                 << 
944         rsync                                  << 
945 #endif                                         << 
946                                                << 
947         movi    a1, KERNEL_PS_WOE_MASK | LOCKL << 
948         wsr     a1, ps                         << 
949         rsync                                  << 
950                                                << 
951         movi    a1, init_task                  << 
952         movi    a0, 0                          << 
953         addi    a1, a1, PT_REGS_OFFSET         << 
954                                                << 
955         movi    abi_arg0, unrecoverable_text   << 
956         abi_call        panic                  << 
957                                                << 
958 1:      j       1b                             << 
959                                                << 
960 ENDPROC(unrecoverable_exception)               << 
961                                                << 
962 /* -------------------------- FAST EXCEPTION H << 
963                                                << 
964         __XTENSA_HANDLER                       << 
965         .literal_position                      << 
966                                                    17 
967 #ifdef SUPPORT_WINDOWED                        !!  18 /* Stack offsets.  */
968 /*                                             !!  19 #define SP_OFF                  184
969  * Fast-handler for alloca exceptions          !!  20 #define SWITCH_STACK_SIZE       64
970  *                                             << 
971  *  The ALLOCA handler is entered when user co << 
972  *  instruction and the caller's frame is not  << 
973  *                                             << 
974  * This algorithm was taken from the Ross Morl << 
975  *                                             << 
976  *    /home/ross/rtos/porting/XtensaRTOS-Porti << 
977  *                                             << 
978  * It leverages the existing window spill/fill << 
979  * double exceptions. The 'movsp' instruction  << 
980  * the next window needs to be loaded. In fact << 
981  * replaced at some point by changing the hard << 
982  * of the proper size instead.                 << 
983  *                                             << 
984  * This algorithm simply backs out the registe << 
985  * exception handler, makes it appear that we  << 
986  * by rotating the window back and then settin << 
987  * the 'ps' register with the rolled back wind << 
988  * will be re-executed and this time since the << 
989  * active AR registers it won't cause an excep << 
990  *                                             << 
991  * If the WindowUnderflow code gets a TLB miss << 
992  * the partial WindowUnderflow will be handled << 
993  * handler.                                    << 
994  *                                             << 
995  * Entry condition:                            << 
996  *                                             << 
997  *   a0:        trashed, original value saved  << 
998  *   a1:        a1                             << 
999  *   a2:        new stack pointer, original in << 
1000  *   a3:        a3                            << 
1001  *   depc:      a2, original value saved on s << 
1002  *   excsave_1: dispatch table                << 
1003  *                                            << 
1004  *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRES << 
1005  *           <  VALID_DOUBLE_EXCEPTION_ADDRES << 
1006  */                                           << 
1007                                                   21 
1008 ENTRY(fast_alloca)                            !!  22 .macro  CFI_START_OSF_FRAME     func
1009         rsr     a0, windowbase                !!  23         .align  4
1010         rotw    -1                            !!  24         .globl  \func
1011         rsr     a2, ps                        !!  25         .type   \func,@function
1012         extui   a3, a2, PS_OWB_SHIFT, PS_OWB_ !!  26 \func:
1013         xor     a3, a3, a4                    !!  27         .cfi_startproc simple
1014         l32i    a4, a6, PT_AREG0              !!  28         .cfi_return_column 64
1015         l32i    a1, a6, PT_DEPC               !!  29         .cfi_def_cfa    $sp, 48
1016         rsr     a6, depc                      !!  30         .cfi_rel_offset 64, 8
1017         wsr     a1, depc                      !!  31         .cfi_rel_offset $gp, 16
1018         slli    a3, a3, PS_OWB_SHIFT          !!  32         .cfi_rel_offset $16, 24
1019         xor     a2, a2, a3                    !!  33         .cfi_rel_offset $17, 32
1020         wsr     a2, ps                        !!  34         .cfi_rel_offset $18, 40
1021         rsync                                 !!  35 .endm
1022                                               !!  36 
1023         _bbci.l a4, 31, 4f                    !!  37 .macro  CFI_END_OSF_FRAME       func
1024         rotw    -1                            !!  38         .cfi_endproc
1025         _bbci.l a8, 30, 8f                    !!  39         .size   \func, . - \func
1026         rotw    -1                            !!  40 .endm
1027         j       _WindowUnderflow12            !!  41 
1028 8:      j       _WindowUnderflow8             !!  42 /*
1029 4:      j       _WindowUnderflow4             !!  43  * This defines the normal kernel pt-regs layout.
1030 ENDPROC(fast_alloca)                          !!  44  *
1031 #endif                                        !!  45  * regs 9-15 preserved by C code
                                                   >>  46  * regs 16-18 saved by PAL-code
                                                   >>  47  * regs 29-30 saved and set up by PAL-code
                                                   >>  48  * JRP - Save regs 16-18 in a special area of the stack, so that
                                                   >>  49  * the palcode-provided values are available to the signal handler.
                                                   >>  50  */
                                                   >>  51 
                                                   >>  52 .macro  SAVE_ALL
                                                   >>  53         subq    $sp, SP_OFF, $sp
                                                   >>  54         .cfi_adjust_cfa_offset  SP_OFF
                                                   >>  55         stq     $0, 0($sp)
                                                   >>  56         stq     $1, 8($sp)
                                                   >>  57         stq     $2, 16($sp)
                                                   >>  58         stq     $3, 24($sp)
                                                   >>  59         stq     $4, 32($sp)
                                                   >>  60         stq     $28, 144($sp)
                                                   >>  61         .cfi_rel_offset $0, 0
                                                   >>  62         .cfi_rel_offset $1, 8
                                                   >>  63         .cfi_rel_offset $2, 16
                                                   >>  64         .cfi_rel_offset $3, 24
                                                   >>  65         .cfi_rel_offset $4, 32
                                                   >>  66         .cfi_rel_offset $28, 144
                                                   >>  67         lda     $2, alpha_mv
                                                   >>  68         stq     $5, 40($sp)
                                                   >>  69         stq     $6, 48($sp)
                                                   >>  70         stq     $7, 56($sp)
                                                   >>  71         stq     $8, 64($sp)
                                                   >>  72         stq     $19, 72($sp)
                                                   >>  73         stq     $20, 80($sp)
                                                   >>  74         stq     $21, 88($sp)
                                                   >>  75         ldq     $2, HAE_CACHE($2)
                                                   >>  76         stq     $22, 96($sp)
                                                   >>  77         stq     $23, 104($sp)
                                                   >>  78         stq     $24, 112($sp)
                                                   >>  79         stq     $25, 120($sp)
                                                   >>  80         stq     $26, 128($sp)
                                                   >>  81         stq     $27, 136($sp)
                                                   >>  82         stq     $2, 152($sp)
                                                   >>  83         stq     $16, 160($sp)
                                                   >>  84         stq     $17, 168($sp)
                                                   >>  85         stq     $18, 176($sp)
                                                   >>  86         .cfi_rel_offset $5, 40
                                                   >>  87         .cfi_rel_offset $6, 48
                                                   >>  88         .cfi_rel_offset $7, 56
                                                   >>  89         .cfi_rel_offset $8, 64
                                                   >>  90         .cfi_rel_offset $19, 72
                                                   >>  91         .cfi_rel_offset $20, 80
                                                   >>  92         .cfi_rel_offset $21, 88
                                                   >>  93         .cfi_rel_offset $22, 96
                                                   >>  94         .cfi_rel_offset $23, 104
                                                   >>  95         .cfi_rel_offset $24, 112
                                                   >>  96         .cfi_rel_offset $25, 120
                                                   >>  97         .cfi_rel_offset $26, 128
                                                   >>  98         .cfi_rel_offset $27, 136
                                                   >>  99 .endm
                                                   >> 100 
                                                   >> 101 .macro  RESTORE_ALL
                                                   >> 102         lda     $19, alpha_mv
                                                   >> 103         ldq     $0, 0($sp)
                                                   >> 104         ldq     $1, 8($sp)
                                                   >> 105         ldq     $2, 16($sp)
                                                   >> 106         ldq     $3, 24($sp)
                                                   >> 107         ldq     $21, 152($sp)
                                                   >> 108         ldq     $20, HAE_CACHE($19)
                                                   >> 109         ldq     $4, 32($sp)
                                                   >> 110         ldq     $5, 40($sp)
                                                   >> 111         ldq     $6, 48($sp)
                                                   >> 112         ldq     $7, 56($sp)
                                                   >> 113         subq    $20, $21, $20
                                                   >> 114         ldq     $8, 64($sp)
                                                   >> 115         beq     $20, 99f
                                                   >> 116         ldq     $20, HAE_REG($19)
                                                   >> 117         stq     $21, HAE_CACHE($19)
                                                   >> 118         stq     $21, 0($20)
                                                   >> 119 99:     ldq     $19, 72($sp)
                                                   >> 120         ldq     $20, 80($sp)
                                                   >> 121         ldq     $21, 88($sp)
                                                   >> 122         ldq     $22, 96($sp)
                                                   >> 123         ldq     $23, 104($sp)
                                                   >> 124         ldq     $24, 112($sp)
                                                   >> 125         ldq     $25, 120($sp)
                                                   >> 126         ldq     $26, 128($sp)
                                                   >> 127         ldq     $27, 136($sp)
                                                   >> 128         ldq     $28, 144($sp)
                                                   >> 129         addq    $sp, SP_OFF, $sp
                                                   >> 130         .cfi_restore    $0
                                                   >> 131         .cfi_restore    $1
                                                   >> 132         .cfi_restore    $2
                                                   >> 133         .cfi_restore    $3
                                                   >> 134         .cfi_restore    $4
                                                   >> 135         .cfi_restore    $5
                                                   >> 136         .cfi_restore    $6
                                                   >> 137         .cfi_restore    $7
                                                   >> 138         .cfi_restore    $8
                                                   >> 139         .cfi_restore    $19
                                                   >> 140         .cfi_restore    $20
                                                   >> 141         .cfi_restore    $21
                                                   >> 142         .cfi_restore    $22
                                                   >> 143         .cfi_restore    $23
                                                   >> 144         .cfi_restore    $24
                                                   >> 145         .cfi_restore    $25
                                                   >> 146         .cfi_restore    $26
                                                   >> 147         .cfi_restore    $27
                                                   >> 148         .cfi_restore    $28
                                                   >> 149         .cfi_adjust_cfa_offset  -SP_OFF
                                                   >> 150 .endm
                                                   >> 151 
                                                   >> 152 .macro  DO_SWITCH_STACK
                                                   >> 153         bsr     $1, do_switch_stack
                                                   >> 154         .cfi_adjust_cfa_offset  SWITCH_STACK_SIZE
                                                   >> 155         .cfi_rel_offset $9, 0
                                                   >> 156         .cfi_rel_offset $10, 8
                                                   >> 157         .cfi_rel_offset $11, 16
                                                   >> 158         .cfi_rel_offset $12, 24
                                                   >> 159         .cfi_rel_offset $13, 32
                                                   >> 160         .cfi_rel_offset $14, 40
                                                   >> 161         .cfi_rel_offset $15, 48
                                                   >> 162 .endm
                                                   >> 163 
                                                   >> 164 .macro  UNDO_SWITCH_STACK
                                                   >> 165         bsr     $1, undo_switch_stack
                                                   >> 166         .cfi_restore    $9
                                                   >> 167         .cfi_restore    $10
                                                   >> 168         .cfi_restore    $11
                                                   >> 169         .cfi_restore    $12
                                                   >> 170         .cfi_restore    $13
                                                   >> 171         .cfi_restore    $14
                                                   >> 172         .cfi_restore    $15
                                                   >> 173         .cfi_adjust_cfa_offset  -SWITCH_STACK_SIZE
                                                   >> 174 .endm
                                                   >> 175 
                                                   >> 176 /*
                                                   >> 177  * Non-syscall kernel entry points.
                                                   >> 178  */
                                                   >> 179 
                                                   >> 180 CFI_START_OSF_FRAME entInt
                                                   >> 181         SAVE_ALL
                                                   >> 182         lda     $8, 0x3fff
                                                   >> 183         lda     $26, ret_from_sys_call
                                                   >> 184         bic     $sp, $8, $8
                                                   >> 185         mov     $sp, $19
                                                   >> 186         jsr     $31, do_entInt
                                                   >> 187 CFI_END_OSF_FRAME entInt
                                                   >> 188 
                                                   >> 189 CFI_START_OSF_FRAME entArith
                                                   >> 190         SAVE_ALL
                                                   >> 191         lda     $8, 0x3fff
                                                   >> 192         lda     $26, ret_from_sys_call
                                                   >> 193         bic     $sp, $8, $8
                                                   >> 194         mov     $sp, $18
                                                   >> 195         jsr     $31, do_entArith
                                                   >> 196 CFI_END_OSF_FRAME entArith
                                                   >> 197 
                                                   >> 198 CFI_START_OSF_FRAME entMM
                                                   >> 199         SAVE_ALL
                                                   >> 200 /* save $9 - $15 so the inline exception code can manipulate them.  */
                                                   >> 201         subq    $sp, 56, $sp
                                                   >> 202         .cfi_adjust_cfa_offset  56
                                                   >> 203         stq     $9, 0($sp)
                                                   >> 204         stq     $10, 8($sp)
                                                   >> 205         stq     $11, 16($sp)
                                                   >> 206         stq     $12, 24($sp)
                                                   >> 207         stq     $13, 32($sp)
                                                   >> 208         stq     $14, 40($sp)
                                                   >> 209         stq     $15, 48($sp)
                                                   >> 210         .cfi_rel_offset $9, 0
                                                   >> 211         .cfi_rel_offset $10, 8
                                                   >> 212         .cfi_rel_offset $11, 16
                                                   >> 213         .cfi_rel_offset $12, 24
                                                   >> 214         .cfi_rel_offset $13, 32
                                                   >> 215         .cfi_rel_offset $14, 40
                                                   >> 216         .cfi_rel_offset $15, 48
                                                   >> 217         addq    $sp, 56, $19
                                                   >> 218 /* handle the fault */
                                                   >> 219         lda     $8, 0x3fff
                                                   >> 220         bic     $sp, $8, $8
                                                   >> 221         jsr     $26, do_page_fault
                                                   >> 222 /* reload the registers after the exception code played.  */
                                                   >> 223         ldq     $9, 0($sp)
                                                   >> 224         ldq     $10, 8($sp)
                                                   >> 225         ldq     $11, 16($sp)
                                                   >> 226         ldq     $12, 24($sp)
                                                   >> 227         ldq     $13, 32($sp)
                                                   >> 228         ldq     $14, 40($sp)
                                                   >> 229         ldq     $15, 48($sp)
                                                   >> 230         addq    $sp, 56, $sp
                                                   >> 231         .cfi_restore    $9
                                                   >> 232         .cfi_restore    $10
                                                   >> 233         .cfi_restore    $11
                                                   >> 234         .cfi_restore    $12
                                                   >> 235         .cfi_restore    $13
                                                   >> 236         .cfi_restore    $14
                                                   >> 237         .cfi_restore    $15
                                                   >> 238         .cfi_adjust_cfa_offset  -56
                                                   >> 239 /* finish up the syscall as normal.  */
                                                   >> 240         br      ret_from_sys_call
                                                   >> 241 CFI_END_OSF_FRAME entMM
                                                   >> 242 
                                                   >> 243 CFI_START_OSF_FRAME entIF
                                                   >> 244         SAVE_ALL
                                                   >> 245         lda     $8, 0x3fff
                                                   >> 246         lda     $26, ret_from_sys_call
                                                   >> 247         bic     $sp, $8, $8
                                                   >> 248         mov     $sp, $17
                                                   >> 249         jsr     $31, do_entIF
                                                   >> 250 CFI_END_OSF_FRAME entIF
                                                   >> 251 
                                                   >> 252 CFI_START_OSF_FRAME entUna
                                                   >> 253         lda     $sp, -256($sp)
                                                   >> 254         .cfi_adjust_cfa_offset  256
                                                   >> 255         stq     $0, 0($sp)
                                                   >> 256         .cfi_rel_offset $0, 0
                                                   >> 257         .cfi_remember_state
                                                   >> 258         ldq     $0, 256($sp)    /* get PS */
                                                   >> 259         stq     $1, 8($sp)
                                                   >> 260         stq     $2, 16($sp)
                                                   >> 261         stq     $3, 24($sp)
                                                   >> 262         and     $0, 8, $0               /* user mode? */
                                                   >> 263         stq     $4, 32($sp)
                                                   >> 264         bne     $0, entUnaUser  /* yup -> do user-level unaligned fault */
                                                   >> 265         stq     $5, 40($sp)
                                                   >> 266         stq     $6, 48($sp)
                                                   >> 267         stq     $7, 56($sp)
                                                   >> 268         stq     $8, 64($sp)
                                                   >> 269         stq     $9, 72($sp)
                                                   >> 270         stq     $10, 80($sp)
                                                   >> 271         stq     $11, 88($sp)
                                                   >> 272         stq     $12, 96($sp)
                                                   >> 273         stq     $13, 104($sp)
                                                   >> 274         stq     $14, 112($sp)
                                                   >> 275         stq     $15, 120($sp)
                                                   >> 276         /* 16-18 PAL-saved */
                                                   >> 277         stq     $19, 152($sp)
                                                   >> 278         stq     $20, 160($sp)
                                                   >> 279         stq     $21, 168($sp)
                                                   >> 280         stq     $22, 176($sp)
                                                   >> 281         stq     $23, 184($sp)
                                                   >> 282         stq     $24, 192($sp)
                                                   >> 283         stq     $25, 200($sp)
                                                   >> 284         stq     $26, 208($sp)
                                                   >> 285         stq     $27, 216($sp)
                                                   >> 286         stq     $28, 224($sp)
                                                   >> 287         mov     $sp, $19
                                                   >> 288         stq     $gp, 232($sp)
                                                   >> 289         .cfi_rel_offset $1, 1*8
                                                   >> 290         .cfi_rel_offset $2, 2*8
                                                   >> 291         .cfi_rel_offset $3, 3*8
                                                   >> 292         .cfi_rel_offset $4, 4*8
                                                   >> 293         .cfi_rel_offset $5, 5*8
                                                   >> 294         .cfi_rel_offset $6, 6*8
                                                   >> 295         .cfi_rel_offset $7, 7*8
                                                   >> 296         .cfi_rel_offset $8, 8*8
                                                   >> 297         .cfi_rel_offset $9, 9*8
                                                   >> 298         .cfi_rel_offset $10, 10*8
                                                   >> 299         .cfi_rel_offset $11, 11*8
                                                   >> 300         .cfi_rel_offset $12, 12*8
                                                   >> 301         .cfi_rel_offset $13, 13*8
                                                   >> 302         .cfi_rel_offset $14, 14*8
                                                   >> 303         .cfi_rel_offset $15, 15*8
                                                   >> 304         .cfi_rel_offset $19, 19*8
                                                   >> 305         .cfi_rel_offset $20, 20*8
                                                   >> 306         .cfi_rel_offset $21, 21*8
                                                   >> 307         .cfi_rel_offset $22, 22*8
                                                   >> 308         .cfi_rel_offset $23, 23*8
                                                   >> 309         .cfi_rel_offset $24, 24*8
                                                   >> 310         .cfi_rel_offset $25, 25*8
                                                   >> 311         .cfi_rel_offset $26, 26*8
                                                   >> 312         .cfi_rel_offset $27, 27*8
                                                   >> 313         .cfi_rel_offset $28, 28*8
                                                   >> 314         .cfi_rel_offset $29, 29*8
                                                   >> 315         lda     $8, 0x3fff
                                                   >> 316         stq     $31, 248($sp)
                                                   >> 317         bic     $sp, $8, $8
                                                   >> 318         jsr     $26, do_entUna
                                                   >> 319         ldq     $0, 0($sp)
                                                   >> 320         ldq     $1, 8($sp)
                                                   >> 321         ldq     $2, 16($sp)
                                                   >> 322         ldq     $3, 24($sp)
                                                   >> 323         ldq     $4, 32($sp)
                                                   >> 324         ldq     $5, 40($sp)
                                                   >> 325         ldq     $6, 48($sp)
                                                   >> 326         ldq     $7, 56($sp)
                                                   >> 327         ldq     $8, 64($sp)
                                                   >> 328         ldq     $9, 72($sp)
                                                   >> 329         ldq     $10, 80($sp)
                                                   >> 330         ldq     $11, 88($sp)
                                                   >> 331         ldq     $12, 96($sp)
                                                   >> 332         ldq     $13, 104($sp)
                                                   >> 333         ldq     $14, 112($sp)
                                                   >> 334         ldq     $15, 120($sp)
                                                   >> 335         /* 16-18 PAL-saved */
                                                   >> 336         ldq     $19, 152($sp)
                                                   >> 337         ldq     $20, 160($sp)
                                                   >> 338         ldq     $21, 168($sp)
                                                   >> 339         ldq     $22, 176($sp)
                                                   >> 340         ldq     $23, 184($sp)
                                                   >> 341         ldq     $24, 192($sp)
                                                   >> 342         ldq     $25, 200($sp)
                                                   >> 343         ldq     $26, 208($sp)
                                                   >> 344         ldq     $27, 216($sp)
                                                   >> 345         ldq     $28, 224($sp)
                                                   >> 346         ldq     $gp, 232($sp)
                                                   >> 347         lda     $sp, 256($sp)
                                                   >> 348         .cfi_restore    $1
                                                   >> 349         .cfi_restore    $2
                                                   >> 350         .cfi_restore    $3
                                                   >> 351         .cfi_restore    $4
                                                   >> 352         .cfi_restore    $5
                                                   >> 353         .cfi_restore    $6
                                                   >> 354         .cfi_restore    $7
                                                   >> 355         .cfi_restore    $8
                                                   >> 356         .cfi_restore    $9
                                                   >> 357         .cfi_restore    $10
                                                   >> 358         .cfi_restore    $11
                                                   >> 359         .cfi_restore    $12
                                                   >> 360         .cfi_restore    $13
                                                   >> 361         .cfi_restore    $14
                                                   >> 362         .cfi_restore    $15
                                                   >> 363         .cfi_restore    $19
                                                   >> 364         .cfi_restore    $20
                                                   >> 365         .cfi_restore    $21
                                                   >> 366         .cfi_restore    $22
                                                   >> 367         .cfi_restore    $23
                                                   >> 368         .cfi_restore    $24
                                                   >> 369         .cfi_restore    $25
                                                   >> 370         .cfi_restore    $26
                                                   >> 371         .cfi_restore    $27
                                                   >> 372         .cfi_restore    $28
                                                   >> 373         .cfi_restore    $29
                                                   >> 374         .cfi_adjust_cfa_offset  -256
                                                   >> 375         call_pal PAL_rti
1032                                                  376 
1033 #ifdef CONFIG_USER_ABI_CALL0_PROBE            !! 377         .align  4
1034 /*                                            !! 378 entUnaUser:
1035  * fast illegal instruction handler.          !! 379         .cfi_restore_state
1036  *                                            !! 380         ldq     $0, 0($sp)      /* restore original $0 */
1037  * This is used to fix up user PS.WOE on the  !! 381         lda     $sp, 256($sp)   /* pop entUna's stack frame */
1038  * by the first opcode related to register wi !! 382         .cfi_restore    $0
1039  * already set it goes directly to the common !! 383         .cfi_adjust_cfa_offset  -256
                                                   >> 384         SAVE_ALL                /* setup normal kernel stack */
                                                   >> 385         lda     $sp, -56($sp)
                                                   >> 386         .cfi_adjust_cfa_offset  56
                                                   >> 387         stq     $9, 0($sp)
                                                   >> 388         stq     $10, 8($sp)
                                                   >> 389         stq     $11, 16($sp)
                                                   >> 390         stq     $12, 24($sp)
                                                   >> 391         stq     $13, 32($sp)
                                                   >> 392         stq     $14, 40($sp)
                                                   >> 393         stq     $15, 48($sp)
                                                   >> 394         .cfi_rel_offset $9, 0
                                                   >> 395         .cfi_rel_offset $10, 8
                                                   >> 396         .cfi_rel_offset $11, 16
                                                   >> 397         .cfi_rel_offset $12, 24
                                                   >> 398         .cfi_rel_offset $13, 32
                                                   >> 399         .cfi_rel_offset $14, 40
                                                   >> 400         .cfi_rel_offset $15, 48
                                                   >> 401         lda     $8, 0x3fff
                                                   >> 402         addq    $sp, 56, $19
                                                   >> 403         bic     $sp, $8, $8
                                                   >> 404         jsr     $26, do_entUnaUser
                                                   >> 405         ldq     $9, 0($sp)
                                                   >> 406         ldq     $10, 8($sp)
                                                   >> 407         ldq     $11, 16($sp)
                                                   >> 408         ldq     $12, 24($sp)
                                                   >> 409         ldq     $13, 32($sp)
                                                   >> 410         ldq     $14, 40($sp)
                                                   >> 411         ldq     $15, 48($sp)
                                                   >> 412         lda     $sp, 56($sp)
                                                   >> 413         .cfi_restore    $9
                                                   >> 414         .cfi_restore    $10
                                                   >> 415         .cfi_restore    $11
                                                   >> 416         .cfi_restore    $12
                                                   >> 417         .cfi_restore    $13
                                                   >> 418         .cfi_restore    $14
                                                   >> 419         .cfi_restore    $15
                                                   >> 420         .cfi_adjust_cfa_offset  -56
                                                   >> 421         br      ret_from_sys_call
                                                   >> 422 CFI_END_OSF_FRAME entUna
                                                   >> 423 
                                                   >> 424 CFI_START_OSF_FRAME entDbg
                                                   >> 425         SAVE_ALL
                                                   >> 426         lda     $8, 0x3fff
                                                   >> 427         lda     $26, ret_from_sys_call
                                                   >> 428         bic     $sp, $8, $8
                                                   >> 429         mov     $sp, $16
                                                   >> 430         jsr     $31, do_entDbg
                                                   >> 431 CFI_END_OSF_FRAME entDbg
                                                   >> 432 
                                                   >> 433 /*
                                                   >> 434  * The system call entry point is special.  Most importantly, it looks
                                                   >> 435  * like a function call to userspace as far as clobbered registers.  We
                                                   >> 436  * do preserve the argument registers (for syscall restarts) and $26
                                                   >> 437  * (for leaf syscall functions).
1040  *                                               438  *
1041  * Entry condition:                           !! 439  * So much for theory.  We don't take advantage of this yet.
1042  *                                               440  *
1043  *   a0:        trashed, original value saved !! 441  * Note that a0-a2 are not saved by PALcode as with the other entry points.
1044  *   a1:        a1                            << 
1045  *   a2:        new stack pointer, original i << 
1046  *   a3:        a3                            << 
1047  *   depc:      a2, original value saved on s << 
1048  *   excsave_1: dispatch table                << 
1049  */                                              442  */
1050                                                  443 
1051 ENTRY(fast_illegal_instruction_user)          !! 444         .align  4
1052                                               !! 445         .globl  entSys
1053         rsr     a0, ps                        !! 446         .type   entSys, @function
1054         bbsi.l  a0, PS_WOE_BIT, 1f            !! 447         .cfi_startproc simple
1055         s32i    a3, a2, PT_AREG3              !! 448         .cfi_return_column 64
1056         movi    a3, PS_WOE_MASK               !! 449         .cfi_def_cfa    $sp, 48
1057         or      a0, a0, a3                    !! 450         .cfi_rel_offset 64, 8
1058         wsr     a0, ps                        !! 451         .cfi_rel_offset $gp, 16
1059 #ifdef CONFIG_USER_ABI_CALL0_PROBE            !! 452 entSys:
1060         GET_THREAD_INFO(a3, a2)               !! 453         SAVE_ALL
1061         rsr     a0, epc1                      !! 454         lda     $8, 0x3fff
1062         s32i    a0, a3, TI_PS_WOE_FIX_ADDR    !! 455         bic     $sp, $8, $8
1063 #endif                                        !! 456         lda     $4, NR_syscalls($31)
1064         l32i    a3, a2, PT_AREG3              !! 457         stq     $16, SP_OFF+24($sp)
1065         l32i    a0, a2, PT_AREG0              !! 458         lda     $5, sys_call_table
1066         rsr     a2, depc                      !! 459         lda     $27, sys_ni_syscall
1067         rfe                                   !! 460         cmpult  $0, $4, $4
1068 1:                                            !! 461         ldl     $3, TI_FLAGS($8)
1069         call0   user_exception                !! 462         stq     $17, SP_OFF+32($sp)
                                                   >> 463         s8addq  $0, $5, $5
                                                   >> 464         stq     $18, SP_OFF+40($sp)
                                                   >> 465         .cfi_rel_offset $16, SP_OFF+24
                                                   >> 466         .cfi_rel_offset $17, SP_OFF+32
                                                   >> 467         .cfi_rel_offset $18, SP_OFF+40
                                                   >> 468 #ifdef CONFIG_AUDITSYSCALL
                                                   >> 469         lda     $6, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
                                                   >> 470         and     $3, $6, $3
                                                   >> 471         bne     $3, strace
                                                   >> 472 #else
                                                   >> 473         blbs    $3, strace              /* check for SYSCALL_TRACE in disguise */
                                                   >> 474 #endif
                                                   >> 475         beq     $4, 1f
                                                   >> 476         ldq     $27, 0($5)
                                                   >> 477 1:      jsr     $26, ($27), sys_ni_syscall
                                                   >> 478         ldgp    $gp, 0($26)
                                                   >> 479         blt     $0, $syscall_error      /* the call failed */
                                                   >> 480 $ret_success:
                                                   >> 481         stq     $0, 0($sp)
                                                   >> 482         stq     $31, 72($sp)            /* a3=0 => no error */
1070                                                  483 
1071 ENDPROC(fast_illegal_instruction_user)        !! 484         .align  4
1072 #endif                                        !! 485         .globl  ret_from_sys_call
                                                   >> 486 ret_from_sys_call:
                                                   >> 487         cmovne  $26, 0, $18             /* $18 = 0 => non-restartable */
                                                   >> 488         ldq     $0, SP_OFF($sp)
                                                   >> 489         and     $0, 8, $0
                                                   >> 490         beq     $0, ret_to_kernel
                                                   >> 491 ret_to_user:
                                                   >> 492         /* Make sure need_resched and sigpending don't change between
                                                   >> 493                 sampling and the rti.  */
                                                   >> 494         lda     $16, 7
                                                   >> 495         call_pal PAL_swpipl
                                                   >> 496         ldl     $17, TI_FLAGS($8)
                                                   >> 497         and     $17, _TIF_WORK_MASK, $2
                                                   >> 498         bne     $2, work_pending
                                                   >> 499 restore_all:
                                                   >> 500         ldl     $2, TI_STATUS($8)
                                                   >> 501         and     $2, TS_SAVED_FP | TS_RESTORE_FP, $3
                                                   >> 502         bne     $3, restore_fpu
                                                   >> 503 restore_other:
                                                   >> 504         .cfi_remember_state
                                                   >> 505         RESTORE_ALL
                                                   >> 506         call_pal PAL_rti
                                                   >> 507 
                                                   >> 508 ret_to_kernel:
                                                   >> 509         .cfi_restore_state
                                                   >> 510         lda     $16, 7
                                                   >> 511         call_pal PAL_swpipl
                                                   >> 512         br restore_other
1073                                                  513 
                                                   >> 514         .align 3
                                                   >> 515 $syscall_error:
1074         /*                                       516         /*
1075  * fast system calls.                         !! 517          * Some system calls (e.g., ptrace) can return arbitrary
1076  *                                            !! 518          * values which might normally be mistaken as error numbers.
1077  * WARNING:  The kernel doesn't save the enti !! 519          * Those functions must zero $0 (v0) directly in the stack
1078  * handling a fast system call.  These functi !! 520          * frame to indicate that a negative return value wasn't an
1079  * usually offering some functionality not av !! 521          * error number..
1080  *                                            !! 522          */
1081  * BE CAREFUL TO PRESERVE THE USER'S CONTEXT. !! 523         ldq     $18, 0($sp)     /* old syscall nr (zero if success) */
1082  *                                            !! 524         beq     $18, $ret_success
1083  * Entry condition:                           !! 525 
1084  *                                            !! 526         ldq     $19, 72($sp)    /* .. and this a3 */
1085  *   a0:        trashed, original value saved !! 527         subq    $31, $0, $0     /* with error in v0 */
1086  *   a1:        a1                            !! 528         addq    $31, 1, $1      /* set a3 for errno return */
1087  *   a2:        new stack pointer, original i !! 529         stq     $0, 0($sp)
1088  *   a3:        a3                            !! 530         mov     $31, $26        /* tell "ret_from_sys_call" we can restart */
1089  *   depc:      a2, original value saved on s !! 531         stq     $1, 72($sp)     /* a3 for return */
1090  *   excsave_1: dispatch table                !! 532         br      ret_from_sys_call
                                                   >> 533 
                                                   >> 534 /*
                                                   >> 535  * Do all cleanup when returning from all interrupts and system calls.
                                                   >> 536  *
                                                   >> 537  * Arguments:
                                                   >> 538  *       $8: current.
                                                   >> 539  *      $17: TI_FLAGS.
                                                   >> 540  *      $18: The old syscall number, or zero if this is not a return
                                                   >> 541  *           from a syscall that errored and is possibly restartable.
                                                   >> 542  *      $19: The old a3 value
1091  */                                              543  */
1092                                                  544 
1093 ENTRY(fast_syscall_user)                      !! 545         .align  4
1094                                               !! 546         .type   work_pending, @function
1095         /* Skip syscall. */                   !! 547 work_pending:
1096                                               !! 548         and     $17, _TIF_NOTIFY_RESUME | _TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL, $2
1097         rsr     a0, epc1                      !! 549         bne     $2, $work_notifysig
1098         addi    a0, a0, 3                     << 
1099         wsr     a0, epc1                      << 
1100                                               << 
1101         l32i    a0, a2, PT_DEPC               << 
1102         bgeui   a0, VALID_DOUBLE_EXCEPTION_AD << 
1103                                               << 
1104         rsr     a0, depc                      << 
1105         _beqz   a0, fast_syscall_spill_regist << 
1106         _beqi   a0, __NR_xtensa, fast_syscall << 
1107                                               << 
1108         call0   user_exception                << 
1109                                               << 
1110 ENDPROC(fast_syscall_user)                    << 
1111                                               << 
1112 ENTRY(fast_syscall_unrecoverable)             << 
1113                                               << 
1114         /* Restore all states. */             << 
1115                                               << 
1116         l32i    a0, a2, PT_AREG0        # res << 
1117         xsr     a2, depc                # res << 
1118                                               << 
1119         wsr     a0, excsave1                  << 
1120         call0   unrecoverable_exception       << 
1121                                               << 
1122 ENDPROC(fast_syscall_unrecoverable)           << 
1123                                               << 
1124 /*                                            << 
1125  * sysxtensa syscall handler                  << 
1126  *                                            << 
1127  * int sysxtensa (SYS_XTENSA_ATOMIC_SET,      << 
1128  * int sysxtensa (SYS_XTENSA_ATOMIC_ADD,      << 
1129  * int sysxtensa (SYS_XTENSA_ATOMIC_EXG_ADD,  << 
1130  * int sysxtensa (SYS_XTENSA_ATOMIC_CMP_SWP,  << 
1131  *        a2            a6                    << 
1132  *                                            << 
1133  * Entry condition:                           << 
1134  *                                            << 
1135  *   a0:        a2 (syscall-nr), original val << 
1136  *   a1:        a1                            << 
1137  *   a2:        new stack pointer, original i << 
1138  *   a3:        a3                            << 
1139  *   a4..a15:   unchanged                     << 
1140  *   depc:      a2, original value saved on s << 
1141  *   excsave_1: dispatch table                << 
1142  *                                            << 
1143  *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRES << 
1144  *           <  VALID_DOUBLE_EXCEPTION_ADDRES << 
1145  *                                            << 
1146  * Note: we don't have to save a2; a2 holds t << 
1147  */                                           << 
1148                                               << 
1149         .literal_position                     << 
1150                                               << 
1151 #ifdef CONFIG_FAST_SYSCALL_XTENSA             << 
1152                                               << 
1153 ENTRY(fast_syscall_xtensa)                    << 
1154                                               << 
1155         s32i    a7, a2, PT_AREG7        # we  << 
1156         movi    a7, 4                   # siz << 
1157         access_ok a3, a7, a0, a2, .Leac # a0: << 
1158                                               << 
1159         _bgeui  a6, SYS_XTENSA_COUNT, .Lill   << 
1160         _bnei   a6, SYS_XTENSA_ATOMIC_CMP_SWP << 
1161                                               << 
1162         /* Fall through for ATOMIC_CMP_SWP. * << 
1163                                               << 
1164 .Lswp:  /* Atomic compare and swap */         << 
1165                                               << 
1166 EX(.Leac) l32i  a0, a3, 0               # rea << 
1167         bne     a0, a4, 1f              # sam << 
1168 EX(.Leac) s32i  a5, a3, 0               # dif << 
1169         l32i    a7, a2, PT_AREG7        # res << 
1170         l32i    a0, a2, PT_AREG0        # res << 
1171         movi    a2, 1                   # and << 
1172         rfe                                   << 
1173                                               << 
1174 1:      l32i    a7, a2, PT_AREG7        # res << 
1175         l32i    a0, a2, PT_AREG0        # res << 
1176         movi    a2, 0                   # ret << 
1177         rfe                                   << 
1178                                               << 
1179 .Lnswp: /* Atomic set, add, and exg_add. */   << 
1180                                               << 
1181 EX(.Leac) l32i  a7, a3, 0               # ori << 
1182         addi    a6, a6, -SYS_XTENSA_ATOMIC_SE << 
1183         add     a0, a4, a7              # + a << 
1184         moveqz  a0, a4, a6              # set << 
1185         addi    a6, a6, SYS_XTENSA_ATOMIC_SET << 
1186 EX(.Leac) s32i  a0, a3, 0               # wri << 
1187                                               << 
1188         mov     a0, a2                        << 
1189         mov     a2, a7                        << 
1190         l32i    a7, a0, PT_AREG7        # res << 
1191         l32i    a0, a0, PT_AREG0        # res << 
1192         rfe                                   << 
1193                                               << 
1194 .Leac:  l32i    a7, a2, PT_AREG7        # res << 
1195         l32i    a0, a2, PT_AREG0        # res << 
1196         movi    a2, -EFAULT                   << 
1197         rfe                                   << 
1198                                               << 
1199 .Lill:  l32i    a7, a2, PT_AREG7        # res << 
1200         l32i    a0, a2, PT_AREG0        # res << 
1201         movi    a2, -EINVAL                   << 
1202         rfe                                   << 
1203                                               << 
1204 ENDPROC(fast_syscall_xtensa)                  << 
1205                                               << 
1206 #else /* CONFIG_FAST_SYSCALL_XTENSA */        << 
1207                                               << 
1208 ENTRY(fast_syscall_xtensa)                    << 
1209                                               << 
1210         l32i    a0, a2, PT_AREG0        # res << 
1211         movi    a2, -ENOSYS                   << 
1212         rfe                                   << 
1213                                               << 
1214 ENDPROC(fast_syscall_xtensa)                  << 
1215                                               << 
1216 #endif /* CONFIG_FAST_SYSCALL_XTENSA */       << 
1217                                               << 
1218                                               << 
1219 /* fast_syscall_spill_registers.              << 
1220  *                                            << 
1221  * Entry condition:                           << 
1222  *                                            << 
1223  *   a0:        trashed, original value saved << 
1224  *   a1:        a1                            << 
1225  *   a2:        new stack pointer, original i << 
1226  *   a3:        a3                            << 
1227  *   depc:      a2, original value saved on s << 
1228  *   excsave_1: dispatch table                << 
1229  *                                            << 
1230  * Note: We assume the stack pointer is EXC_T << 
1231  */                                           << 
1232                                               << 
1233 #if defined(CONFIG_FAST_SYSCALL_SPILL_REGISTE << 
1234                 defined(USER_SUPPORT_WINDOWED << 
1235                                               << 
1236 ENTRY(fast_syscall_spill_registers)           << 
1237                                               << 
1238         /* Register a FIXUP handler (pass cur << 
1239                                               << 
1240         xsr     a3, excsave1                  << 
1241         movi    a0, fast_syscall_spill_regist << 
1242         s32i    a0, a3, EXC_TABLE_FIXUP       << 
1243         rsr     a0, windowbase                << 
1244         s32i    a0, a3, EXC_TABLE_PARAM       << 
1245         xsr     a3, excsave1            # res << 
1246                                               << 
1247         /* Save a3, a4 and SAR on stack. */   << 
1248                                               << 
1249         rsr     a0, sar                       << 
1250         s32i    a3, a2, PT_AREG3              << 
1251         s32i    a0, a2, PT_SAR                << 
1252                                               << 
1253         /* The spill routine might clobber a4 << 
1254                                               << 
1255         s32i    a4, a2, PT_AREG4              << 
1256         s32i    a7, a2, PT_AREG7              << 
1257         s32i    a8, a2, PT_AREG8              << 
1258         s32i    a11, a2, PT_AREG11            << 
1259         s32i    a12, a2, PT_AREG12            << 
1260         s32i    a15, a2, PT_AREG15            << 
1261                                                  550 
                                                   >> 551 $work_resched:
1262         /*                                       552         /*
1263          * Rotate ws so that the current wind !! 553          * We can get here only if we returned from syscall without SIGPENDING
1264          * Assume ws = xxxwww1yy (www1 curren !! 554          * or got through work_notifysig already.  Either case means no syscall
1265          * Rotate ws right so that a4 = yyxxx !! 555          * restarts for us, so let $18 and $19 burn.
1266          */                                   !! 556          */
1267                                               !! 557         jsr     $26, schedule
1268         rsr     a0, windowbase                !! 558         mov     0, $18
1269         rsr     a3, windowstart         # a3  !! 559         br      ret_to_user
1270         ssr     a0                      # hol !! 560 
1271         slli    a0, a3, WSBITS                !! 561 $work_notifysig:
1272         or      a3, a3, a0              # a3  !! 562         mov     $sp, $16
1273         srl     a3, a3                  # a3  !! 563         DO_SWITCH_STACK
1274                                               !! 564         jsr     $26, do_work_pending
1275         /* We are done if there are no more t !! 565         UNDO_SWITCH_STACK
1276                                               !! 566         br      restore_all
1277         extui   a3, a3, 1, WSBITS-1     # a3  << 
1278         movi    a0, (1 << (WSBITS-1))         << 
1279         _beqz   a3, .Lnospill           # onl << 
1280                                               << 
1281         /* We want 1 at the top, so that we r << 
1282                                               << 
1283         or      a3, a3, a0              # 1yy << 
1284                                               << 
1285         /* Skip empty frames - get 'oldest' W << 
1286                                               << 
1287         wsr     a3, windowstart         # sav << 
1288         neg     a0, a3                        << 
1289         and     a3, a0, a3              # fir << 
1290                                               << 
1291         ffs_ws  a0, a3                  # a0: << 
1292         movi    a3, WSBITS                    << 
1293         sub     a0, a3, a0              # WSB << 
1294         ssr     a0                      # sav << 
1295                                               << 
1296         rsr     a3, windowbase                << 
1297         add     a3, a3, a0                    << 
1298         wsr     a3, windowbase                << 
1299         rsync                                 << 
1300                                               << 
1301         rsr     a3, windowstart               << 
1302         srl     a3, a3                  # shi << 
1303                                               << 
1304         /* WB is now just one frame below the << 
1305            window. WS is shifted so the oldes << 
1306            and WS differ by one 4-register fr << 
1307                                               << 
1308         /* Save frames. Depending what call w << 
1309          * we have to save 4,8. or 12 registe << 
1310          */                                   << 
1311                                               << 
1312                                               << 
1313 .Lloop: _bbsi.l a3, 1, .Lc4                   << 
1314         _bbci.l a3, 2, .Lc12                  << 
1315                                               << 
1316 .Lc8:   s32e    a4, a13, -16                  << 
1317         l32e    a4, a5, -12                   << 
1318         s32e    a8, a4, -32                   << 
1319         s32e    a5, a13, -12                  << 
1320         s32e    a6, a13, -8                   << 
1321         s32e    a7, a13, -4                   << 
1322         s32e    a9, a4, -28                   << 
1323         s32e    a10, a4, -24                  << 
1324         s32e    a11, a4, -20                  << 
1325         srli    a11, a3, 2              # shi << 
1326         rotw    2                             << 
1327         _bnei   a3, 1, .Lloop                 << 
1328         j       .Lexit                        << 
1329                                               << 
1330 .Lc4:   s32e    a4, a9, -16                   << 
1331         s32e    a5, a9, -12                   << 
1332         s32e    a6, a9, -8                    << 
1333         s32e    a7, a9, -4                    << 
1334                                               << 
1335         srli    a7, a3, 1                     << 
1336         rotw    1                             << 
1337         _bnei   a3, 1, .Lloop                 << 
1338         j       .Lexit                        << 
1339                                               << 
1340 .Lc12:  _bbci.l a3, 3, .Linvalid_mask   # bit << 
1341                                               << 
1342         /* 12-register frame (call12) */      << 
1343                                               << 
1344         l32e    a0, a5, -12                   << 
1345         s32e    a8, a0, -48                   << 
1346         mov     a8, a0                        << 
1347                                               << 
1348         s32e    a9, a8, -44                   << 
1349         s32e    a10, a8, -40                  << 
1350         s32e    a11, a8, -36                  << 
1351         s32e    a12, a8, -32                  << 
1352         s32e    a13, a8, -28                  << 
1353         s32e    a14, a8, -24                  << 
1354         s32e    a15, a8, -20                  << 
1355         srli    a15, a3, 3                    << 
1356                                               << 
1357         /* The stack pointer for a4..a7 is ou << 
1358          * window, grab the stackpointer, and << 
1359          * Alternatively, we could also use t << 
1360          * makes the fixup routine much more  << 
1361          * rotw 1                             << 
1362          * s32e a0, a13, -16                  << 
1363          * ...                                << 
1364          * rotw 2                             << 
1365          */                                   << 
1366                                               << 
1367         rotw    1                             << 
1368         mov     a4, a13                       << 
1369         rotw    -1                            << 
1370                                               << 
1371         s32e    a4, a8, -16                   << 
1372         s32e    a5, a8, -12                   << 
1373         s32e    a6, a8, -8                    << 
1374         s32e    a7, a8, -4                    << 
1375                                               << 
1376         rotw    3                             << 
1377                                               << 
1378         _beqi   a3, 1, .Lexit                 << 
1379         j       .Lloop                        << 
1380                                               << 
1381 .Lexit:                                       << 
1382                                               << 
1383         /* Done. Do the final rotation and se << 
1384                                               << 
1385         rotw    1                             << 
1386         rsr     a3, windowbase                << 
1387         ssl     a3                            << 
1388         movi    a3, 1                         << 
1389         sll     a3, a3                        << 
1390         wsr     a3, windowstart               << 
1391 .Lnospill:                                    << 
1392                                               << 
1393         /* Advance PC, restore registers and  << 
1394                                               << 
1395         l32i    a3, a2, PT_SAR                << 
1396         l32i    a0, a2, PT_AREG0              << 
1397         wsr     a3, sar                       << 
1398         l32i    a3, a2, PT_AREG3              << 
1399                                               << 
1400         /* Restore clobbered registers. */    << 
1401                                               << 
1402         l32i    a4, a2, PT_AREG4              << 
1403         l32i    a7, a2, PT_AREG7              << 
1404         l32i    a8, a2, PT_AREG8              << 
1405         l32i    a11, a2, PT_AREG11            << 
1406         l32i    a12, a2, PT_AREG12            << 
1407         l32i    a15, a2, PT_AREG15            << 
1408                                               << 
1409         movi    a2, 0                         << 
1410         rfe                                   << 
1411                                               << 
1412 .Linvalid_mask:                               << 
1413                                               << 
1414         /* We get here because of an unrecove << 
1415          * registers, so set up a dummy frame << 
1416          * Note: We assume EXC_TABLE_KSTK con << 
1417          */                                   << 
1418                                               << 
1419         movi    a0, 1                         << 
1420         movi    a1, 0                         << 
1421                                                  567 
1422         wsr     a0, windowstart               << 
1423         wsr     a1, windowbase                << 
1424         rsync                                 << 
1425                                               << 
1426         movi    a0, 0                         << 
1427                                               << 
1428         rsr     a3, excsave1                  << 
1429         l32i    a1, a3, EXC_TABLE_KSTK        << 
1430                                               << 
1431         movi    a4, KERNEL_PS_WOE_MASK | LOCK << 
1432         wsr     a4, ps                        << 
1433         rsync                                 << 
1434                                               << 
1435         movi    abi_arg0, SIGSEGV             << 
1436         abi_call        make_task_dead        << 
1437                                               << 
1438         /* shouldn't return, so panic */      << 
1439                                               << 
1440         wsr     a0, excsave1                  << 
1441         call0   unrecoverable_exception       << 
1442 1:      j       1b                            << 
1443                                               << 
1444                                               << 
1445 ENDPROC(fast_syscall_spill_registers)         << 
1446                                               << 
1447 /* Fixup handler.                             << 
1448  *                                            << 
1449  * We get here if the spill routine causes an << 
1450  * We basically restore WINDOWBASE and WINDOW << 
1451  * we entered the spill routine and jump to t << 
1452  *                                            << 
1453  * Note that we only need to restore the bits << 
1454  * been spilled yet by the _spill_register ro << 
1455  * rotated windowstart with only those bits s << 
1456  * spilled yet. Because a3 is rotated such th << 
1457  * frame for the current windowbase - 1, we n << 
1458  * value of the current windowbase + 1 and mo << 
1459  *                                            << 
1460  * a0: value of depc, original value in depc  << 
1461  * a2: trashed, original value in EXC_TABLE_D << 
1462  * a3: exctable, original value in excsave1   << 
1463  */                                           << 
1464                                               << 
1465 ENTRY(fast_syscall_spill_registers_fixup)     << 
1466                                               << 
1467         rsr     a2, windowbase  # get current << 
1468         xsr     a0, depc        # restore dep << 
1469         ssl     a2              # set shift ( << 
1470                                               << 
1471         /* We need to make sure the current r << 
1472          * To do this, we simply set the bit  << 
1473          * in WS, so that the exception handl << 
1474          *                                    << 
1475          * Note: we use a3 to set the windowb << 
1476          * of it, saving it in the original _ << 
1477          * the exception handler call.        << 
1478          */                                   << 
1479                                               << 
1480         xsr     a3, excsave1    # get spill-m << 
1481         slli    a3, a3, 1       # shift left  << 
1482         addi    a3, a3, 1       # set the bit << 
1483                                               << 
1484         slli    a2, a3, 32-WSBITS             << 
1485         src     a2, a3, a2      # a2 = xxwww1 << 
1486         wsr     a2, windowstart # set correct << 
1487                                               << 
1488         srli    a3, a3, 1                     << 
1489         rsr     a2, excsave1                  << 
1490         l32i    a2, a2, EXC_TABLE_DOUBLE_SAVE << 
1491         xsr     a2, excsave1                  << 
1492         s32i    a3, a2, EXC_TABLE_DOUBLE_SAVE << 
1493         l32i    a3, a2, EXC_TABLE_PARAM # ori << 
1494         xsr     a2, excsave1                  << 
1495                                               << 
1496         /* Return to the original (user task) << 
1497          * We leave the following frame behin << 
1498          * a0, a1, a2   same                  << 
1499          * a3:          trashed (saved in EXC << 
1500          * depc:        depc (we have to retu << 
1501          * excsave_1:   exctable              << 
1502          */                                   << 
1503                                               << 
1504         wsr     a3, windowbase                << 
1505         rsync                                 << 
1506                                               << 
1507         /* We are now in the original frame w << 
1508          *  a0: return address                << 
1509          *  a1: used, stack pointer           << 
1510          *  a2: kernel stack pointer          << 
1511          *  a3: available                     << 
1512          *  depc: exception address           << 
1513          *  excsave: exctable                 << 
1514          * Note: This frame might be the same << 
1515          */                                   << 
1516                                               << 
1517         /* Setup stack pointer. */            << 
1518                                               << 
1519         addi    a2, a2, -PT_USER_SIZE         << 
1520         s32i    a0, a2, PT_AREG0              << 
1521                                               << 
1522         /* Make sure we return to this fixup  << 
1523                                               << 
1524         movi    a3, fast_syscall_spill_regist << 
1525         s32i    a3, a2, PT_DEPC         # set << 
1526                                               << 
1527         /* Jump to the exception handler. */  << 
1528                                               << 
1529         rsr     a3, excsave1                  << 
1530         rsr     a0, exccause                  << 
1531         addx4   a0, a0, a3                    << 
1532         l32i    a0, a0, EXC_TABLE_FAST_USER   << 
1533         l32i    a3, a3, EXC_TABLE_DOUBLE_SAVE << 
1534         jx      a0                            << 
1535                                               << 
1536 ENDPROC(fast_syscall_spill_registers_fixup)   << 
1537                                               << 
1538 ENTRY(fast_syscall_spill_registers_fixup_retu << 
1539                                               << 
1540         /* When we return here, all registers << 
1541                                               << 
1542         wsr     a2, depc                # exc << 
1543                                               << 
1544         /* Restore fixup handler. */          << 
1545                                               << 
1546         rsr     a2, excsave1                  << 
1547         s32i    a3, a2, EXC_TABLE_DOUBLE_SAVE << 
1548         movi    a3, fast_syscall_spill_regist << 
1549         s32i    a3, a2, EXC_TABLE_FIXUP       << 
1550         rsr     a3, windowbase                << 
1551         s32i    a3, a2, EXC_TABLE_PARAM       << 
1552         l32i    a2, a2, EXC_TABLE_KSTK        << 
1553                                               << 
1554         /* Load WB at the time the exception  << 
1555                                               << 
1556         rsr     a3, sar                 # WB  << 
1557         neg     a3, a3                        << 
1558         wsr     a3, windowbase                << 
1559         rsync                                 << 
1560                                               << 
1561         rsr     a3, excsave1                  << 
1562         l32i    a3, a3, EXC_TABLE_DOUBLE_SAVE << 
1563                                               << 
1564         rfde                                  << 
1565                                               << 
1566 ENDPROC(fast_syscall_spill_registers_fixup_re << 
1567                                               << 
1568 #else /* CONFIG_FAST_SYSCALL_SPILL_REGISTERS  << 
1569                                               << 
1570 ENTRY(fast_syscall_spill_registers)           << 
1571                                               << 
1572         l32i    a0, a2, PT_AREG0        # res << 
1573         movi    a2, -ENOSYS                   << 
1574         rfe                                   << 
1575                                               << 
1576 ENDPROC(fast_syscall_spill_registers)         << 
1577                                               << 
1578 #endif /* CONFIG_FAST_SYSCALL_SPILL_REGISTERS << 
1579                                               << 
1580 #ifdef CONFIG_MMU                             << 
1581 /*                                               568 /*
1582  * We should never get here. Bail out!        !! 569  * PTRACE syscall handler
1583  */                                           << 
1584                                               << 
1585 ENTRY(fast_second_level_miss_double_kernel)   << 
1586                                               << 
1587 1:                                            << 
1588         call0   unrecoverable_exception       << 
1589 1:      j       1b                            << 
1590                                               << 
1591 ENDPROC(fast_second_level_miss_double_kernel) << 
1592                                               << 
1593 /* First-level entry handler for user, kernel << 
1594  * TLB miss exceptions.  Note that for now, u << 
1595  * exceptions share the same entry point and  << 
1596  *                                            << 
1597  * An old, less-efficient C version of this f << 
1598  * We include it below, interleaved as commen << 
1599  *                                            << 
1600  * Entry condition:                           << 
1601  *                                            << 
1602  *   a0:        trashed, original value saved << 
1603  *   a1:        a1                            << 
1604  *   a2:        new stack pointer, original i << 
1605  *   a3:        a3                            << 
1606  *   depc:      a2, original value saved on s << 
1607  *   excsave_1: dispatch table                << 
1608  *                                            << 
1609  *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRES << 
1610  *           <  VALID_DOUBLE_EXCEPTION_ADDRES << 
1611  */                                              570  */
1612                                                  571 
1613 ENTRY(fast_second_level_miss)                 !! 572         .align  4
1614                                               !! 573         .type   strace, @function
1615         /* Save a1 and a3. Note: we don't exp !! 574 strace:
1616                                               !! 575         /* set up signal stack, call syscall_trace */
1617         s32i    a1, a2, PT_AREG1              !! 576         // NB: if anyone adds preemption, this block will need to be protected
1618         s32i    a3, a2, PT_AREG3              !! 577         ldl     $1, TI_STATUS($8)
1619                                               !! 578         and     $1, TS_SAVED_FP, $3
1620         /* We need to map the page of PTEs fo !! 579         or      $1, TS_SAVED_FP, $2
1621          * the pointer to that page.  Also, i !! 580         bne     $3, 1f
1622          * to be NULL while tsk->active_mm is !! 581         stl     $2, TI_STATUS($8)
1623          * a vmalloc address.  In that rare c !! 582         bsr     $26, __save_fpu
1624          * active_mm instead to avoid a fault !! 583 1:
1625          *                                    !! 584         DO_SWITCH_STACK
1626          * http://mail.nl.linux.org/linux-mm/ !! 585         jsr     $26, syscall_trace_enter /* returns the syscall number */
1627          *   (or search Internet on "mm vs. a !! 586         UNDO_SWITCH_STACK
1628          *                                    !! 587 
1629          *      if (!mm)                      !! 588         /* get the arguments back.. */
1630          *              mm = tsk->active_mm;  !! 589         ldq     $16, SP_OFF+24($sp)
1631          *      pgd = pgd_offset (mm, regs->e !! 590         ldq     $17, SP_OFF+32($sp)
1632          *      pmd = pmd_offset (pgd, regs-> !! 591         ldq     $18, SP_OFF+40($sp)
1633          *      pmdval = *pmd;                !! 592         ldq     $19, 72($sp)
1634          */                                   !! 593         ldq     $20, 80($sp)
1635                                               !! 594         ldq     $21, 88($sp)
1636         GET_CURRENT(a1,a2)                    !! 595 
1637         l32i    a0, a1, TASK_MM         # tsk !! 596         /* get the system call pointer.. */
1638         beqz    a0, .Lfast_second_level_miss_ !! 597         lda     $1, NR_syscalls($31)
1639                                               !! 598         lda     $2, sys_call_table
1640 .Lfast_second_level_miss_continue:            !! 599         lda     $27, sys_ni_syscall
1641         rsr     a3, excvaddr            # fau !! 600         cmpult  $0, $1, $1
1642         _PGD_OFFSET(a0, a3, a1)               !! 601         s8addq  $0, $2, $2
1643         l32i    a0, a0, 0               # rea !! 602         beq     $1, 1f
1644         beqz    a0, .Lfast_second_level_miss_ !! 603         ldq     $27, 0($2)
1645                                               !! 604 1:      jsr     $26, ($27), sys_gettimeofday
1646         /* Read ptevaddr and convert to top o !! 605 ret_from_straced:
1647          *                                    !! 606         ldgp    $gp, 0($26)
1648          *      vpnval = read_ptevaddr_regist !! 607 
1649          *      vpnval += DTLB_WAY_PGTABLE;   !! 608         /* check return.. */
1650          *      pteval = mk_pte (virt_to_page !! 609         blt     $0, $strace_error       /* the call failed */
1651          *      write_dtlb_entry (pteval, vpn !! 610 $strace_success:
1652          *                                    !! 611         stq     $31, 72($sp)            /* a3=0 => no error */
1653          * The messy computation for 'pteval' !! 612         stq     $0, 0($sp)              /* save return value */
1654          * into the following:                !! 613 
1655          *                                    !! 614         DO_SWITCH_STACK
1656          * pteval = ((pmdval - PAGE_OFFSET +  !! 615         jsr     $26, syscall_trace_leave
1657          *                 | PAGE_DIRECTORY   !! 616         UNDO_SWITCH_STACK
1658          */                                   !! 617         br      $31, ret_from_sys_call
1659                                               !! 618 
1660         movi    a1, (PHYS_OFFSET - PAGE_OFFSE !! 619         .align  3
1661         add     a0, a0, a1              # pmd !! 620 $strace_error:
1662         extui   a1, a0, 0, PAGE_SHIFT   # ... !! 621         ldq     $18, 0($sp)     /* old syscall nr (zero if success) */
1663         xor     a0, a0, a1                    !! 622         beq     $18, $strace_success
1664                                               !! 623         ldq     $19, 72($sp)    /* .. and this a3 */
1665         movi    a1, _PAGE_DIRECTORY           !! 624 
1666         or      a0, a0, a1              # ... !! 625         subq    $31, $0, $0     /* with error in v0 */
1667                                               !! 626         addq    $31, 1, $1      /* set a3 for errno return */
1668         /*                                    !! 627         stq     $0, 0($sp)
1669          * We utilize all three wired-ways (7 !! 628         stq     $1, 72($sp)     /* a3 for return */
1670          * Memory regions are mapped to the D !! 629 
1671          * This allows to map the three most  !! 630         DO_SWITCH_STACK
1672          * DTLBs:                             !! 631         mov     $18, $9         /* save old syscall number */
1673          *  0,1 -> way 7        program (0040 !! 632         mov     $19, $10        /* save old a3 */
1674          *  2   -> way 8        shared libari !! 633         jsr     $26, syscall_trace_leave
1675          *  3   -> way 0        stack (3000.0 !! 634         mov     $9, $18
1676          */                                   !! 635         mov     $10, $19
1677                                               !! 636         UNDO_SWITCH_STACK
1678         extui   a3, a3, 28, 2           # add !! 637 
1679         rsr     a1, ptevaddr                  !! 638         mov     $31, $26        /* tell "ret_from_sys_call" we can restart */
1680         addx2   a3, a3, a3              # ->  !! 639         br      ret_from_sys_call
1681         srli    a1, a1, PAGE_SHIFT            !! 640 CFI_END_OSF_FRAME entSys
1682         extui   a3, a3, 2, 2            # ->  !! 641 
1683         slli    a1, a1, PAGE_SHIFT      # pte << 
1684         addi    a3, a3, DTLB_WAY_PGD          << 
1685         add     a1, a1, a3              # ... << 
1686                                               << 
1687 .Lfast_second_level_miss_wdtlb:               << 
1688         wdtlb   a0, a1                        << 
1689         dsync                                 << 
1690                                               << 
1691         /* Exit critical section. */          << 
1692 .Lfast_second_level_miss_skip_wdtlb:          << 
1693         rsr     a3, excsave1                  << 
1694         movi    a0, 0                         << 
1695         s32i    a0, a3, EXC_TABLE_FIXUP       << 
1696                                               << 
1697         /* Restore the working registers, and << 
1698                                               << 
1699         l32i    a0, a2, PT_AREG0              << 
1700         l32i    a1, a2, PT_AREG1              << 
1701         l32i    a3, a2, PT_AREG3              << 
1702         l32i    a2, a2, PT_DEPC               << 
1703                                               << 
1704         bgeui   a2, VALID_DOUBLE_EXCEPTION_AD << 
1705                                               << 
1706         /* Restore excsave1 and return. */    << 
1707                                               << 
1708         rsr     a2, depc                      << 
1709         rfe                                   << 
1710                                               << 
1711         /* Return from double exception. */   << 
1712                                               << 
1713 1:      xsr     a2, depc                      << 
1714         esync                                 << 
1715         rfde                                  << 
1716                                               << 
1717 .Lfast_second_level_miss_no_mm:               << 
1718         l32i    a0, a1, TASK_ACTIVE_MM  # unl << 
1719         bnez    a0, .Lfast_second_level_miss_ << 
1720                                               << 
1721         /* Even more unlikely case active_mm  << 
1722          * We can get here with NMI in the mi << 
1723          * touches vmalloc area.              << 
1724          */                                   << 
1725         movi    a0, init_mm                   << 
1726         j       .Lfast_second_level_miss_cont << 
1727                                               << 
1728 .Lfast_second_level_miss_no_pmd:              << 
1729 #if (DCACHE_WAY_SIZE > PAGE_SIZE)             << 
1730                                               << 
1731         /* Special case for cache aliasing.   << 
1732          * We (should) only get here if a cle << 
1733          * or the aliased cache flush functio << 
1734          * by another task. Re-establish temp << 
1735          * TLBTEMP_BASE areas.                << 
1736          */                                   << 
1737                                               << 
1738         /* We shouldn't be in a double except << 
1739                                               << 
1740         l32i    a0, a2, PT_DEPC               << 
1741         bgeui   a0, VALID_DOUBLE_EXCEPTION_AD << 
1742                                               << 
1743         /* Make sure the exception originated << 
1744                                               << 
1745         movi    a0, __tlbtemp_mapping_start   << 
1746         rsr     a3, epc1                      << 
1747         bltu    a3, a0, .Lfast_second_level_m << 
1748         movi    a0, __tlbtemp_mapping_end     << 
1749         bgeu    a3, a0, .Lfast_second_level_m << 
1750                                               << 
1751         /* Check if excvaddr was in one of th << 
1752                                               << 
1753         movi    a3, TLBTEMP_BASE_1            << 
1754         rsr     a0, excvaddr                  << 
1755         bltu    a0, a3, .Lfast_second_level_m << 
1756                                               << 
1757         addi    a1, a0, -TLBTEMP_SIZE         << 
1758         bgeu    a1, a3, .Lfast_second_level_m << 
1759                                               << 
1760         /* Check if we have to restore an ITL << 
1761                                               << 
1762         movi    a1, __tlbtemp_mapping_itlb    << 
1763         rsr     a3, epc1                      << 
1764         sub     a3, a3, a1                    << 
1765                                               << 
1766         /* Calculate VPN */                   << 
1767                                               << 
1768         movi    a1, PAGE_MASK                 << 
1769         and     a1, a1, a0                    << 
1770                                               << 
1771         /* Jump for ITLB entry */             << 
1772                                               << 
1773         bgez    a3, 1f                        << 
1774                                               << 
1775         /* We can use up to two TLBTEMP areas << 
1776                                               << 
1777         extui   a3, a0, PAGE_SHIFT + DCACHE_A << 
1778         add     a1, a3, a1                    << 
1779                                               << 
1780         /* PPN is in a6 for the first TLBTEMP << 
1781                                               << 
1782         mov     a0, a6                        << 
1783         movnez  a0, a7, a3                    << 
1784         j       .Lfast_second_level_miss_wdtl << 
1785                                               << 
1786         /* ITLB entry. We only use dst in a6. << 
1787                                               << 
1788 1:      witlb   a6, a1                        << 
1789         isync                                 << 
1790         j       .Lfast_second_level_miss_skip << 
1791                                               << 
1792                                               << 
1793 #endif  // DCACHE_WAY_SIZE > PAGE_SIZE        << 
1794                                               << 
1795         /* Invalid PGD, default exception han << 
1796 .Lfast_second_level_miss_slow:                << 
1797                                               << 
1798         rsr     a1, depc                      << 
1799         s32i    a1, a2, PT_AREG2              << 
1800         mov     a1, a2                        << 
1801                                               << 
1802         rsr     a2, ps                        << 
1803         bbsi.l  a2, PS_UM_BIT, 1f             << 
1804         call0   _kernel_exception             << 
1805 1:      call0   _user_exception               << 
1806                                               << 
1807 ENDPROC(fast_second_level_miss)               << 
1808                                               << 
1809 /*                                               642 /*
1810  * StoreProhibitedException                   !! 643  * Save and restore the switch stack -- aka the balance of the user context.
1811  *                                            << 
1812  * Update the pte and invalidate the itlb map << 
1813  *                                            << 
1814  * Entry condition:                           << 
1815  *                                            << 
1816  *   a0:        trashed, original value saved << 
1817  *   a1:        a1                            << 
1818  *   a2:        new stack pointer, original i << 
1819  *   a3:        a3                            << 
1820  *   depc:      a2, original value saved on s << 
1821  *   excsave_1: dispatch table                << 
1822  *                                            << 
1823  *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRES << 
1824  *           <  VALID_DOUBLE_EXCEPTION_ADDRES << 
1825  */                                              644  */
1826                                                  645 
1827 ENTRY(fast_store_prohibited)                  !! 646         .align  4
1828                                               !! 647         .type   do_switch_stack, @function
1829         /* Save a1 and a3. */                 !! 648         .cfi_startproc simple
1830                                               !! 649         .cfi_return_column 64
1831         s32i    a1, a2, PT_AREG1              !! 650         .cfi_def_cfa $sp, 0
1832         s32i    a3, a2, PT_AREG3              !! 651         .cfi_register 64, $1
1833                                               !! 652 do_switch_stack:
1834         GET_CURRENT(a1,a2)                    !! 653         lda     $sp, -SWITCH_STACK_SIZE($sp)
1835         l32i    a0, a1, TASK_MM         # tsk !! 654         .cfi_adjust_cfa_offset  SWITCH_STACK_SIZE
1836         beqz    a0, .Lfast_store_no_mm        !! 655         stq     $9, 0($sp)
1837                                               !! 656         stq     $10, 8($sp)
1838 .Lfast_store_continue:                        !! 657         stq     $11, 16($sp)
1839         rsr     a1, excvaddr            # fau !! 658         stq     $12, 24($sp)
1840         _PGD_OFFSET(a0, a1, a3)               !! 659         stq     $13, 32($sp)
1841         l32i    a0, a0, 0                     !! 660         stq     $14, 40($sp)
1842         beqz    a0, .Lfast_store_slow         !! 661         stq     $15, 48($sp)
1843                                               !! 662         stq     $26, 56($sp)
1844         /*                                    !! 663         ret     $31, ($1), 1
1845          * Note that we test _PAGE_WRITABLE_B !! 664         .cfi_endproc
1846          * and is not PAGE_NONE. See pgtable. !! 665         .size   do_switch_stack, .-do_switch_stack
1847          */                                   << 
1848                                               << 
1849         _PTE_OFFSET(a0, a1, a3)               << 
1850         l32i    a3, a0, 0               # rea << 
1851         movi    a1, _PAGE_CA_INVALID          << 
1852         ball    a3, a1, .Lfast_store_slow     << 
1853         bbci.l  a3, _PAGE_WRITABLE_BIT, .Lfas << 
1854                                               << 
1855         movi    a1, _PAGE_ACCESSED | _PAGE_DI << 
1856         or      a3, a3, a1                    << 
1857         rsr     a1, excvaddr                  << 
1858         s32i    a3, a0, 0                     << 
1859                                               << 
1860         /* We need to flush the cache if we h << 
1861 #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DC << 
1862         dhwb    a0, 0                         << 
1863 #endif                                        << 
1864         pdtlb   a0, a1                        << 
1865         wdtlb   a3, a0                        << 
1866                                               << 
1867         /* Exit critical section. */          << 
1868                                                  666 
1869         movi    a0, 0                         !! 667         .align  4
1870         rsr     a3, excsave1                  !! 668         .type   undo_switch_stack, @function
1871         s32i    a0, a3, EXC_TABLE_FIXUP       !! 669         .cfi_startproc simple
1872                                               !! 670         .cfi_def_cfa $sp, 0
1873         /* Restore the working registers, and !! 671         .cfi_register 64, $1
1874                                               !! 672 undo_switch_stack:
1875         l32i    a3, a2, PT_AREG3              !! 673         ldq     $9, 0($sp)
1876         l32i    a1, a2, PT_AREG1              !! 674         ldq     $10, 8($sp)
1877         l32i    a0, a2, PT_AREG0              !! 675         ldq     $11, 16($sp)
1878         l32i    a2, a2, PT_DEPC               !! 676         ldq     $12, 24($sp)
1879                                               !! 677         ldq     $13, 32($sp)
1880         bgeui   a2, VALID_DOUBLE_EXCEPTION_AD !! 678         ldq     $14, 40($sp)
1881         rsr     a2, depc                      !! 679         ldq     $15, 48($sp)
1882         rfe                                   !! 680         ldq     $26, 56($sp)
1883                                               !! 681         lda     $sp, SWITCH_STACK_SIZE($sp)
1884         /* Double exception. Restore FIXUP ha !! 682         ret     $31, ($1), 1
1885                                               !! 683         .cfi_endproc
1886 1:      xsr     a2, depc                      !! 684         .size   undo_switch_stack, .-undo_switch_stack
1887         esync                                 << 
1888         rfde                                  << 
1889                                               << 
1890 .Lfast_store_no_mm:                           << 
1891         l32i    a0, a1, TASK_ACTIVE_MM  # unl << 
1892         j       .Lfast_store_continue         << 
1893                                               << 
1894         /* If there was a problem, handle fau << 
1895 .Lfast_store_slow:                            << 
1896         rsr     a1, excvaddr                  << 
1897         pdtlb   a0, a1                        << 
1898         bbci.l  a0, DTLB_HIT_BIT, 1f          << 
1899         idtlb   a0                            << 
1900 1:                                            << 
1901         rsr     a3, depc        # still holds << 
1902         s32i    a3, a2, PT_AREG2              << 
1903         mov     a1, a2                        << 
1904                                               << 
1905         rsr     a2, ps                        << 
1906         bbsi.l  a2, PS_UM_BIT, 1f             << 
1907         call0   _kernel_exception             << 
1908 1:      call0   _user_exception               << 
1909                                                  685 
1910 ENDPROC(fast_store_prohibited)                !! 686 #define FR(n) n * 8 + TI_FP($8)
                                                   >> 687         .align  4
                                                   >> 688         .globl  __save_fpu
                                                   >> 689         .type   __save_fpu, @function
                                                   >> 690 __save_fpu:
                                                   >> 691 #define V(n) stt        $f##n, FR(n)
                                                   >> 692         V( 0); V( 1); V( 2); V( 3)
                                                   >> 693         V( 4); V( 5); V( 6); V( 7)
                                                   >> 694         V( 8); V( 9); V(10); V(11)
                                                   >> 695         V(12); V(13); V(14); V(15)
                                                   >> 696         V(16); V(17); V(18); V(19)
                                                   >> 697         V(20); V(21); V(22); V(23)
                                                   >> 698         V(24); V(25); V(26); V(27)
                                                   >> 699         mf_fpcr $f0             # get fpcr
                                                   >> 700         V(28); V(29); V(30)
                                                   >> 701         stt     $f0, FR(31)     # save fpcr in slot of $f31
                                                   >> 702         ldt     $f0, FR(0)      # don't let "__save_fpu" change fp state.
                                                   >> 703         ret
                                                   >> 704 #undef V
                                                   >> 705         .size   __save_fpu, .-__save_fpu
1911                                                  706 
1912 #endif /* CONFIG_MMU */                       !! 707         .align  4
                                                   >> 708 restore_fpu:
                                                   >> 709         and     $3, TS_RESTORE_FP, $3
                                                   >> 710         bic     $2, TS_SAVED_FP | TS_RESTORE_FP, $2
                                                   >> 711         beq     $3, 1f
                                                   >> 712 #define V(n) ldt        $f##n, FR(n)
                                                   >> 713         ldt     $f30, FR(31)    # get saved fpcr
                                                   >> 714         V( 0); V( 1); V( 2); V( 3)
                                                   >> 715         mt_fpcr $f30            # install saved fpcr
                                                   >> 716         V( 4); V( 5); V( 6); V( 7)
                                                   >> 717         V( 8); V( 9); V(10); V(11)
                                                   >> 718         V(12); V(13); V(14); V(15)
                                                   >> 719         V(16); V(17); V(18); V(19)
                                                   >> 720         V(20); V(21); V(22); V(23)
                                                   >> 721         V(24); V(25); V(26); V(27)
                                                   >> 722         V(28); V(29); V(30)
                                                   >> 723 1:      stl $2, TI_STATUS($8)
                                                   >> 724         br restore_other
                                                   >> 725 #undef V
1913                                                  726 
1914         .text                                 !! 727 
1915 /*                                               728 /*
1916  * System Calls.                              !! 729  * The meat of the context switch code.
1917  *                                            << 
1918  * void system_call (struct pt_regs* regs, in << 
1919  *                            a2              << 
1920  */                                              730  */
1921         .literal_position                     !! 731         .align  4
1922                                               !! 732         .globl  alpha_switch_to
1923 ENTRY(system_call)                            !! 733         .type   alpha_switch_to, @function
1924                                               !! 734         .cfi_startproc
1925 #if defined(__XTENSA_WINDOWED_ABI__)          !! 735 alpha_switch_to:
1926         abi_entry_default                     !! 736         DO_SWITCH_STACK
1927 #elif defined(__XTENSA_CALL0_ABI__)           !! 737         ldl     $1, TI_STATUS($8)
1928         abi_entry(12)                         !! 738         and     $1, TS_RESTORE_FP, $3
1929                                               !! 739         bne     $3, 1f
1930         s32i    a0, sp, 0                     !! 740         or      $1, TS_RESTORE_FP | TS_SAVED_FP, $2
1931         s32i    abi_saved0, sp, 4             !! 741         and     $1, TS_SAVED_FP, $3
1932         s32i    abi_saved1, sp, 8             !! 742         stl     $2, TI_STATUS($8)
1933         mov     abi_saved0, a2                !! 743         bne     $3, 1f
1934 #else                                         !! 744         bsr     $26, __save_fpu
1935 #error Unsupported Xtensa ABI                 !! 745 1:
1936 #endif                                        !! 746         call_pal PAL_swpctx
1937                                               !! 747         lda     $8, 0x3fff
1938         /* regs->syscall = regs->areg[2] */   !! 748         UNDO_SWITCH_STACK
1939                                               !! 749         bic     $sp, $8, $8
1940         l32i    a7, abi_saved0, PT_AREG2      !! 750         mov     $17, $0
1941         s32i    a7, abi_saved0, PT_SYSCALL    !! 751         ret
1942                                               !! 752         .cfi_endproc
1943         GET_THREAD_INFO(a4, a1)               !! 753         .size   alpha_switch_to, .-alpha_switch_to
1944         l32i    abi_saved1, a4, TI_FLAGS      << 
1945         movi    a4, _TIF_WORK_MASK            << 
1946         and     abi_saved1, abi_saved1, a4    << 
1947         beqz    abi_saved1, 1f                << 
1948                                               << 
1949         mov     abi_arg0, abi_saved0          << 
1950         abi_call        do_syscall_trace_ente << 
1951         beqz    abi_rv, .Lsyscall_exit        << 
1952         l32i    a7, abi_saved0, PT_SYSCALL    << 
1953                                               << 
1954 1:                                            << 
1955         /* syscall = sys_call_table[syscall_n << 
1956                                               << 
1957         movi    a4, sys_call_table            << 
1958         movi    a5, __NR_syscalls             << 
1959         movi    abi_rv, -ENOSYS               << 
1960         bgeu    a7, a5, 1f                    << 
1961                                               << 
1962         addx4   a4, a7, a4                    << 
1963         l32i    abi_tmp0, a4, 0               << 
1964                                               << 
1965         /* Load args: arg0 - arg5 are passed  << 
1966                                               << 
1967         l32i    abi_arg0, abi_saved0, PT_AREG << 
1968         l32i    abi_arg1, abi_saved0, PT_AREG << 
1969         l32i    abi_arg2, abi_saved0, PT_AREG << 
1970         l32i    abi_arg3, abi_saved0, PT_AREG << 
1971         l32i    abi_arg4, abi_saved0, PT_AREG << 
1972         l32i    abi_arg5, abi_saved0, PT_AREG << 
1973                                               << 
1974         abi_callx       abi_tmp0              << 
1975                                               << 
1976 1:      /* regs->areg[2] = return_value */    << 
1977                                               << 
1978         s32i    abi_rv, abi_saved0, PT_AREG2  << 
1979         bnez    abi_saved1, 1f                << 
1980 .Lsyscall_exit:                               << 
1981 #if defined(__XTENSA_WINDOWED_ABI__)          << 
1982         abi_ret_default                       << 
1983 #elif defined(__XTENSA_CALL0_ABI__)           << 
1984         l32i    a0, sp, 0                     << 
1985         l32i    abi_saved0, sp, 4             << 
1986         l32i    abi_saved1, sp, 8             << 
1987         abi_ret(12)                           << 
1988 #else                                         << 
1989 #error Unsupported Xtensa ABI                 << 
1990 #endif                                        << 
1991                                               << 
1992 1:                                            << 
1993         mov     abi_arg0, abi_saved0          << 
1994         abi_call        do_syscall_trace_leav << 
1995         j       .Lsyscall_exit                << 
1996                                               << 
1997 ENDPROC(system_call)                          << 
1998                                                  754 
1999 /*                                               755 /*
2000  * Spill live registers on the kernel stack m !! 756  * New processes begin life here.
2001  *                                            << 
2002  * Entry condition: ps.woe is set, ps.excm is << 
2003  * Exit condition: windowstart has single bit << 
2004  * May clobber: a12, a13                      << 
2005  */                                              757  */
2006         .macro  spill_registers_kernel        << 
2007                                                  758 
2008 #if XCHAL_NUM_AREGS > 16                      !! 759         .globl  ret_from_fork
2009         call12  1f                            << 
2010         _j      2f                            << 
2011         retw                                  << 
2012         .align  4                                760         .align  4
2013 1:                                            !! 761         .ent    ret_from_fork
2014         _entry  a1, 48                        !! 762 ret_from_fork:
2015         addi    a12, a0, 3                    !! 763         lda     $26, ret_to_user
2016 #if XCHAL_NUM_AREGS > 32                      !! 764         mov     $17, $16
2017         .rept   (XCHAL_NUM_AREGS - 32) / 12   !! 765         jmp     $31, schedule_tail
2018         _entry  a1, 48                        !! 766 .end ret_from_fork
2019         mov     a12, a0                       << 
2020         .endr                                 << 
2021 #endif                                        << 
2022         _entry  a1, 16                        << 
2023 #if XCHAL_NUM_AREGS % 12 == 0                 << 
2024         mov     a8, a8                        << 
2025 #elif XCHAL_NUM_AREGS % 12 == 4               << 
2026         mov     a12, a12                      << 
2027 #elif XCHAL_NUM_AREGS % 12 == 8               << 
2028         mov     a4, a4                        << 
2029 #endif                                        << 
2030         retw                                  << 
2031 2:                                            << 
2032 #else                                         << 
2033         mov     a12, a12                      << 
2034 #endif                                        << 
2035         .endm                                 << 
2036                                                  767 
2037 /*                                               768 /*
2038  * Task switch.                               !! 769  * ... and new kernel threads - here
2039  *                                            << 
2040  * struct task*  _switch_to (struct task* pre << 
2041  *         a2                              a2 << 
2042  */                                              770  */
                                                   >> 771         .align 4
                                                   >> 772         .globl  ret_from_kernel_thread
                                                   >> 773         .ent    ret_from_kernel_thread
                                                   >> 774 ret_from_kernel_thread:
                                                   >> 775         mov     $17, $16
                                                   >> 776         jsr     $26, schedule_tail
                                                   >> 777         mov     $9, $27
                                                   >> 778         mov     $10, $16
                                                   >> 779         jsr     $26, ($9)
                                                   >> 780         br      $31, ret_to_user
                                                   >> 781 .end ret_from_kernel_thread
2043                                                  782 
2044 ENTRY(_switch_to)                             !! 783 
2045                                               << 
2046 #if defined(__XTENSA_WINDOWED_ABI__)          << 
2047         abi_entry(XTENSA_SPILL_STACK_RESERVE) << 
2048 #elif defined(__XTENSA_CALL0_ABI__)           << 
2049         abi_entry(16)                         << 
2050                                               << 
2051         s32i    a12, sp, 0                    << 
2052         s32i    a13, sp, 4                    << 
2053         s32i    a14, sp, 8                    << 
2054         s32i    a15, sp, 12                   << 
2055 #else                                         << 
2056 #error Unsupported Xtensa ABI                 << 
2057 #endif                                        << 
2058         mov     a11, a3                 # and << 
2059                                               << 
2060         l32i    a4, a2, TASK_THREAD_INFO      << 
2061         l32i    a5, a3, TASK_THREAD_INFO      << 
2062                                               << 
2063         save_xtregs_user a4 a6 a8 a9 a12 a13  << 
2064                                               << 
2065 #if THREAD_RA > 1020 || THREAD_SP > 1020      << 
2066         addi    a10, a2, TASK_THREAD          << 
2067         s32i    a0, a10, THREAD_RA - TASK_THR << 
2068         s32i    a1, a10, THREAD_SP - TASK_THR << 
2069 #else                                         << 
2070         s32i    a0, a2, THREAD_RA       # sav << 
2071         s32i    a1, a2, THREAD_SP       # sav << 
2072 #endif                                        << 
2073                                               << 
2074 #if defined(CONFIG_STACKPROTECTOR) && !define << 
2075         movi    a6, __stack_chk_guard         << 
2076         l32i    a8, a3, TASK_STACK_CANARY     << 
2077         s32i    a8, a6, 0                     << 
2078 #endif                                        << 
2079                                               << 
2080         /* Disable ints while we manipulate t << 
2081                                               << 
2082         irq_save a14, a3                      << 
2083         rsync                                 << 
2084                                               << 
2085         /* Switch CPENABLE */                 << 
2086                                               << 
2087 #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_ << 
2088         l32i    a3, a5, THREAD_CPENABLE       << 
2089 #ifdef CONFIG_SMP                             << 
2090         beqz    a3, 1f                        << 
2091         memw                    # pairs with  << 
2092         l32i    a6, a5, THREAD_CP_OWNER_CPU   << 
2093         l32i    a7, a5, THREAD_CPU            << 
2094         beq     a6, a7, 1f      # load 0 into << 
2095         movi    a3, 0                         << 
2096 1:                                            << 
2097 #endif                                        << 
2098         wsr     a3, cpenable                  << 
2099 #endif                                        << 
2100                                               << 
2101 #if XCHAL_HAVE_EXCLUSIVE                      << 
2102         l32i    a3, a5, THREAD_ATOMCTL8       << 
2103         getex   a3                            << 
2104         s32i    a3, a4, THREAD_ATOMCTL8       << 
2105 #endif                                        << 
2106                                               << 
2107         /* Flush register file. */            << 
2108                                               << 
2109 #if defined(__XTENSA_WINDOWED_ABI__)          << 
2110         spill_registers_kernel                << 
2111 #endif                                        << 
2112                                               << 
2113         /* Set kernel stack (and leave critic << 
2114          * Note: It's save to set it here. Th << 
2115          *       because the kernel stack wil << 
2116          *       we return from kernel space. << 
2117          */                                   << 
2118                                               << 
2119         rsr     a3, excsave1            # exc << 
2120         addi    a7, a5, PT_REGS_OFFSET        << 
2121         s32i    a7, a3, EXC_TABLE_KSTK        << 
2122                                               << 
2123         /* restore context of the task 'next' << 
2124                                               << 
2125         l32i    a0, a11, THREAD_RA      # res << 
2126         l32i    a1, a11, THREAD_SP      # res << 
2127                                               << 
2128         load_xtregs_user a5 a6 a8 a9 a12 a13  << 
2129                                               << 
2130         wsr     a14, ps                       << 
2131         rsync                                 << 
2132                                               << 
2133 #if defined(__XTENSA_WINDOWED_ABI__)          << 
2134         abi_ret(XTENSA_SPILL_STACK_RESERVE)   << 
2135 #elif defined(__XTENSA_CALL0_ABI__)           << 
2136         l32i    a12, sp, 0                    << 
2137         l32i    a13, sp, 4                    << 
2138         l32i    a14, sp, 8                    << 
2139         l32i    a15, sp, 12                   << 
2140         abi_ret(16)                           << 
2141 #else                                         << 
2142 #error Unsupported Xtensa ABI                 << 
2143 #endif                                        << 
2144                                               << 
2145 ENDPROC(_switch_to)                           << 
2146                                               << 
2147 ENTRY(ret_from_fork)                          << 
2148                                               << 
2149         /* void schedule_tail (struct task_st << 
2150          * Note: prev is still in abi_arg0 (r << 
2151          */                                   << 
2152         abi_call        schedule_tail         << 
2153                                               << 
2154         mov             abi_arg0, a1          << 
2155         abi_call        do_syscall_trace_leav << 
2156         j               common_exception_retu << 
2157                                               << 
2158 ENDPROC(ret_from_fork)                        << 
2159                                               << 
2160 /*                                               784 /*
2161  * Kernel thread creation helper              !! 785  * Special system calls.  Most of these are special in that they either
2162  * On entry, set up by copy_thread: abi_saved !! 786  * have to play switch_stack games.
2163  * abi_saved1 = thread_fn arg. Left from _swi << 
2164  */                                              787  */
2165 ENTRY(ret_from_kernel_thread)                 << 
2166                                               << 
2167         abi_call        schedule_tail         << 
2168         mov             abi_arg0, abi_saved1  << 
2169         abi_callx       abi_saved0            << 
2170         j               common_exception_retu << 
2171                                                  788 
2172 ENDPROC(ret_from_kernel_thread)               !! 789 .macro  fork_like name
2173                                               << 
2174 #ifdef CONFIG_HIBERNATION                     << 
2175                                               << 
2176         .section        .bss, "aw"            << 
2177         .align  4                                790         .align  4
2178 .Lsaved_regs:                                 !! 791         .globl  alpha_\name
2179 #if defined(__XTENSA_WINDOWED_ABI__)          !! 792         .ent    alpha_\name
2180         .fill   2, 4                          !! 793 alpha_\name:
2181 #elif defined(__XTENSA_CALL0_ABI__)           !! 794         .prologue 0
2182         .fill   6, 4                          !! 795         bsr     $1, do_switch_stack
2183 #else                                         !! 796         // NB: if anyone adds preemption, this block will need to be protected
2184 #error Unsupported Xtensa ABI                 !! 797         ldl     $1, TI_STATUS($8)
2185 #endif                                        !! 798         and     $1, TS_SAVED_FP, $3
2186         .align  XCHAL_NCP_SA_ALIGN            !! 799         or      $1, TS_SAVED_FP, $2
2187 .Lsaved_user_regs:                            !! 800         bne     $3, 1f
2188         .fill   XTREGS_USER_SIZE, 1           !! 801         stl     $2, TI_STATUS($8)
2189                                               !! 802         bsr     $26, __save_fpu
2190         .previous                             !! 803 1:
2191                                               !! 804         jsr     $26, sys_\name
2192 ENTRY(swsusp_arch_suspend)                    !! 805         ldq     $26, 56($sp)
2193                                               !! 806         lda     $sp, SWITCH_STACK_SIZE($sp)
2194         abi_entry_default                     !! 807         ret
2195                                               !! 808 .end    alpha_\name
2196         movi            a2, .Lsaved_regs      !! 809 .endm
2197         movi            a3, .Lsaved_user_regs !! 810 
2198         s32i            a0, a2, 0             !! 811 fork_like fork
2199         s32i            a1, a2, 4             !! 812 fork_like vfork
2200         save_xtregs_user a3 a4 a5 a6 a7 a8 0  !! 813 fork_like clone
2201 #if defined(__XTENSA_WINDOWED_ABI__)          !! 814 fork_like clone3
2202         spill_registers_kernel                << 
2203 #elif defined(__XTENSA_CALL0_ABI__)           << 
2204         s32i            a12, a2, 8            << 
2205         s32i            a13, a2, 12           << 
2206         s32i            a14, a2, 16           << 
2207         s32i            a15, a2, 20           << 
2208 #else                                         << 
2209 #error Unsupported Xtensa ABI                 << 
2210 #endif                                        << 
2211         abi_call        swsusp_save           << 
2212         mov             a2, abi_rv            << 
2213         abi_ret_default                       << 
2214                                               << 
2215 ENDPROC(swsusp_arch_suspend)                  << 
2216                                               << 
2217 ENTRY(swsusp_arch_resume)                     << 
2218                                                  815 
2219         abi_entry_default                     !! 816 .macro  sigreturn_like name
2220                                               !! 817         .align  4
2221 #if defined(__XTENSA_WINDOWED_ABI__)          !! 818         .globl  sys_\name
2222         spill_registers_kernel                !! 819         .ent    sys_\name
2223 #endif                                        !! 820 sys_\name:
2224                                               !! 821         .prologue 0
2225         movi            a2, restore_pblist    !! 822         lda     $9, ret_from_straced
2226         l32i            a2, a2, 0             !! 823         cmpult  $26, $9, $9
2227                                               !! 824         lda     $sp, -SWITCH_STACK_SIZE($sp)
2228 .Lcopy_pbe:                                   !! 825         jsr     $26, do_\name
2229         l32i            a3, a2, PBE_ADDRESS   !! 826         bne     $9, 1f
2230         l32i            a4, a2, PBE_ORIG_ADDR !! 827         jsr     $26, syscall_trace_leave
2231                                               !! 828 1:      br      $1, undo_switch_stack
2232         __loopi         a3, a9, PAGE_SIZE, 16 !! 829         br      ret_from_sys_call
2233         l32i            a5, a3, 0             !! 830 .end sys_\name
2234         l32i            a6, a3, 4             !! 831 .endm
2235         l32i            a7, a3, 8             << 
2236         l32i            a8, a3, 12            << 
2237         addi            a3, a3, 16            << 
2238         s32i            a5, a4, 0             << 
2239         s32i            a6, a4, 4             << 
2240         s32i            a7, a4, 8             << 
2241         s32i            a8, a4, 12            << 
2242         addi            a4, a4, 16            << 
2243         __endl          a3, a9                << 
2244                                               << 
2245         l32i            a2, a2, PBE_NEXT      << 
2246         bnez            a2, .Lcopy_pbe        << 
2247                                               << 
2248         movi            a2, .Lsaved_regs      << 
2249         movi            a3, .Lsaved_user_regs << 
2250         l32i            a0, a2, 0             << 
2251         l32i            a1, a2, 4             << 
2252         load_xtregs_user a3 a4 a5 a6 a7 a8 0  << 
2253 #if defined(__XTENSA_CALL0_ABI__)             << 
2254         l32i            a12, a2, 8            << 
2255         l32i            a13, a2, 12           << 
2256         l32i            a14, a2, 16           << 
2257         l32i            a15, a2, 20           << 
2258 #endif                                        << 
2259         movi            a2, 0                 << 
2260         abi_ret_default                       << 
2261                                                  832 
2262 ENDPROC(swsusp_arch_resume)                   !! 833 sigreturn_like sigreturn
                                                   >> 834 sigreturn_like rt_sigreturn
2263                                                  835 
2264 #endif                                        !! 836         .align  4
                                                   >> 837         .globl  alpha_syscall_zero
                                                   >> 838         .ent    alpha_syscall_zero
                                                   >> 839 alpha_syscall_zero:
                                                   >> 840         .prologue 0
                                                   >> 841         /* Special because it needs to do something opposite to
                                                   >> 842            force_successful_syscall_return().  We use the saved
                                                   >> 843            syscall number for that, zero meaning "not an error".
                                                   >> 844            That works nicely, but for real syscall 0 we need to
                                                   >> 845            make sure that this logics doesn't get confused.
                                                   >> 846            Store a non-zero there - -ENOSYS we need in register
                                                   >> 847            for our return value will do just fine.
                                                   >> 848           */
                                                   >> 849         lda     $0, -ENOSYS
                                                   >> 850         unop
                                                   >> 851         stq     $0, 0($sp)
                                                   >> 852         ret
                                                   >> 853 .end alpha_syscall_zero
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php