linux/arch/c6x/kernel/entry.S
<<
>>
Prefs
   1;
   2;  Port on Texas Instruments TMS320C6x architecture
   3;
   4;  Copyright (C) 2004-2011 Texas Instruments Incorporated
   5;  Author: Aurelien Jacquiot (aurelien.jacquiot@virtuallogix.com)
   6;  Updated for 2.6.34: Mark Salter <msalter@redhat.com>
   7;
   8;  This program is free software; you can redistribute it and/or modify
   9;  it under the terms of the GNU General Public License version 2 as
  10;  published by the Free Software Foundation.
  11;
  12
  13#include <linux/sys.h>
  14#include <linux/linkage.h>
  15#include <asm/thread_info.h>
  16#include <asm/asm-offsets.h>
  17#include <asm/unistd.h>
  18#include <asm/errno.h>
  19
  20; Registers naming
  21#define DP      B14
  22#define SP      B15
  23
  24#ifndef CONFIG_PREEMPT
  25#define resume_kernel restore_all
  26#endif
  27
  28        .altmacro
  29
  30        .macro MASK_INT reg
  31        MVC     .S2     CSR,reg
  32        CLR     .S2     reg,0,0,reg
  33        MVC     .S2     reg,CSR
  34        .endm
  35
  36        .macro UNMASK_INT reg
  37        MVC     .S2     CSR,reg
  38        SET     .S2     reg,0,0,reg
  39        MVC     .S2     reg,CSR
  40        .endm
  41
  42        .macro GET_THREAD_INFO reg
  43        SHR     .S1X    SP,THREAD_SHIFT,reg
  44        SHL     .S1     reg,THREAD_SHIFT,reg
  45        .endm
  46
  47        ;;
  48        ;;  This defines the normal kernel pt_regs layout.
  49        ;;
  50        .macro SAVE_ALL __rp __tsr
  51        STW     .D2T2   B0,*SP--[2]             ; save original B0
  52        MVKL    .S2     current_ksp,B0
  53        MVKH    .S2     current_ksp,B0
  54        LDW     .D2T2   *B0,B1                  ; KSP
  55
  56        NOP     3
  57        STW     .D2T2   B1,*+SP[1]              ; save original B1
  58        XOR     .D2     SP,B1,B0                ; (SP ^ KSP)
  59        LDW     .D2T2   *+SP[1],B1              ; restore B0/B1
  60        LDW     .D2T2   *++SP[2],B0
  61        SHR     .S2     B0,THREAD_SHIFT,B0      ; 0 if already using kstack
  62  [B0]  STDW    .D2T2   SP:DP,*--B1[1]          ; user: save user sp/dp kstack
  63  [B0]  MV      .S2     B1,SP                   ;    and switch to kstack
  64||[!B0] STDW    .D2T2   SP:DP,*--SP[1]          ; kernel: save on current stack
  65
  66        SUBAW   .D2     SP,2,SP
  67
  68        ADD     .D1X    SP,-8,A15
  69 ||     STDW    .D2T1   A15:A14,*SP--[16]       ; save A15:A14
  70
  71        STDW    .D2T2   B13:B12,*SP--[1]
  72 ||     STDW    .D1T1   A13:A12,*A15--[1]
  73 ||     MVC     .S2     __rp,B13
  74
  75        STDW    .D2T2   B11:B10,*SP--[1]
  76 ||     STDW    .D1T1   A11:A10,*A15--[1]
  77 ||     MVC     .S2     CSR,B12
  78
  79        STDW    .D2T2   B9:B8,*SP--[1]
  80 ||     STDW    .D1T1   A9:A8,*A15--[1]
  81 ||     MVC     .S2     RILC,B11
  82        STDW    .D2T2   B7:B6,*SP--[1]
  83 ||     STDW    .D1T1   A7:A6,*A15--[1]
  84 ||     MVC     .S2     ILC,B10
  85
  86        STDW    .D2T2   B5:B4,*SP--[1]
  87 ||     STDW    .D1T1   A5:A4,*A15--[1]
  88
  89        STDW    .D2T2   B3:B2,*SP--[1]
  90 ||     STDW    .D1T1   A3:A2,*A15--[1]
  91 ||     MVC     .S2     __tsr,B5
  92
  93        STDW    .D2T2   B1:B0,*SP--[1]
  94 ||     STDW    .D1T1   A1:A0,*A15--[1]
  95 ||     MV      .S1X    B5,A5
  96
  97        STDW    .D2T2   B31:B30,*SP--[1]
  98 ||     STDW    .D1T1   A31:A30,*A15--[1]
  99        STDW    .D2T2   B29:B28,*SP--[1]
 100 ||     STDW    .D1T1   A29:A28,*A15--[1]
 101        STDW    .D2T2   B27:B26,*SP--[1]
 102 ||     STDW    .D1T1   A27:A26,*A15--[1]
 103        STDW    .D2T2   B25:B24,*SP--[1]
 104 ||     STDW    .D1T1   A25:A24,*A15--[1]
 105        STDW    .D2T2   B23:B22,*SP--[1]
 106 ||     STDW    .D1T1   A23:A22,*A15--[1]
 107        STDW    .D2T2   B21:B20,*SP--[1]
 108 ||     STDW    .D1T1   A21:A20,*A15--[1]
 109        STDW    .D2T2   B19:B18,*SP--[1]
 110 ||     STDW    .D1T1   A19:A18,*A15--[1]
 111        STDW    .D2T2   B17:B16,*SP--[1]
 112 ||     STDW    .D1T1   A17:A16,*A15--[1]
 113
 114        STDW    .D2T2   B13:B12,*SP--[1]        ; save PC and CSR
 115
 116        STDW    .D2T2   B11:B10,*SP--[1]        ; save RILC and ILC
 117        STDW    .D2T1   A5:A4,*SP--[1]          ; save TSR and orig A4
 118
 119        ;; We left an unused word on the stack just above pt_regs.
 120        ;; It is used to save whether or not this frame is due to
 121        ;; a syscall. It is cleared here, but the syscall handler
 122        ;; sets it to a non-zero value.
 123        MVK     .L2     0,B1
 124        STW     .D2T2   B1,*+SP(REGS__END+8)    ; clear syscall flag
 125        .endm
 126
 127        .macro RESTORE_ALL __rp __tsr
 128        LDDW    .D2T2   *++SP[1],B9:B8          ; get TSR (B9)
 129        LDDW    .D2T2   *++SP[1],B11:B10        ; get RILC (B11) and ILC (B10)
 130        LDDW    .D2T2   *++SP[1],B13:B12        ; get PC (B13) and CSR (B12)
 131
 132        ADDAW   .D1X    SP,30,A15
 133
 134        LDDW    .D1T1   *++A15[1],A17:A16
 135 ||     LDDW    .D2T2   *++SP[1],B17:B16
 136        LDDW    .D1T1   *++A15[1],A19:A18
 137 ||     LDDW    .D2T2   *++SP[1],B19:B18
 138        LDDW    .D1T1   *++A15[1],A21:A20
 139 ||     LDDW    .D2T2   *++SP[1],B21:B20
 140        LDDW    .D1T1   *++A15[1],A23:A22
 141 ||     LDDW    .D2T2   *++SP[1],B23:B22
 142        LDDW    .D1T1   *++A15[1],A25:A24
 143 ||     LDDW    .D2T2   *++SP[1],B25:B24
 144        LDDW    .D1T1   *++A15[1],A27:A26
 145 ||     LDDW    .D2T2   *++SP[1],B27:B26
 146        LDDW    .D1T1   *++A15[1],A29:A28
 147 ||     LDDW    .D2T2   *++SP[1],B29:B28
 148        LDDW    .D1T1   *++A15[1],A31:A30
 149 ||     LDDW    .D2T2   *++SP[1],B31:B30
 150
 151        LDDW    .D1T1   *++A15[1],A1:A0
 152 ||     LDDW    .D2T2   *++SP[1],B1:B0
 153
 154        LDDW    .D1T1   *++A15[1],A3:A2
 155 ||     LDDW    .D2T2   *++SP[1],B3:B2
 156 ||     MVC     .S2     B9,__tsr
 157        LDDW    .D1T1   *++A15[1],A5:A4
 158 ||     LDDW    .D2T2   *++SP[1],B5:B4
 159 ||     MVC     .S2     B11,RILC
 160        LDDW    .D1T1   *++A15[1],A7:A6
 161 ||     LDDW    .D2T2   *++SP[1],B7:B6
 162 ||     MVC     .S2     B10,ILC
 163
 164        LDDW    .D1T1   *++A15[1],A9:A8
 165 ||     LDDW    .D2T2   *++SP[1],B9:B8
 166 ||     MVC     .S2     B13,__rp
 167
 168        LDDW    .D1T1   *++A15[1],A11:A10
 169 ||     LDDW    .D2T2   *++SP[1],B11:B10
 170 ||     MVC     .S2     B12,CSR
 171
 172        LDDW    .D1T1   *++A15[1],A13:A12
 173 ||     LDDW    .D2T2   *++SP[1],B13:B12
 174
 175        MV      .D2X    A15,SP
 176 ||     MVKL    .S1     current_ksp,A15
 177        MVKH    .S1     current_ksp,A15
 178 ||     ADDAW   .D1X    SP,6,A14
 179        STW     .D1T1   A14,*A15        ; save kernel stack pointer
 180
 181        LDDW    .D2T1   *++SP[1],A15:A14
 182
 183        B       .S2     __rp            ; return from interruption
 184        LDDW    .D2T2   *+SP[1],SP:DP
 185        NOP     4
 186        .endm
 187
 188        .section .text
 189
 190        ;;
 191        ;; Jump to schedule() then return to ret_from_exception
 192        ;;
 193_reschedule:
 194#ifdef CONFIG_C6X_BIG_KERNEL
 195        MVKL    .S1     schedule,A0
 196        MVKH    .S1     schedule,A0
 197        B       .S2X    A0
 198#else
 199        B       .S1     schedule
 200#endif
 201        ADDKPC  .S2     ret_from_exception,B3,4
 202
 203        ;;
 204        ;; Called before syscall handler when process is being debugged
 205        ;;
 206tracesys_on:
 207#ifdef CONFIG_C6X_BIG_KERNEL
 208        MVKL    .S1     syscall_trace_entry,A0
 209        MVKH    .S1     syscall_trace_entry,A0
 210        B       .S2X    A0
 211#else
 212        B       .S1     syscall_trace_entry
 213#endif
 214        ADDKPC  .S2     ret_from_syscall_trace,B3,3
 215        ADD     .S1X    8,SP,A4
 216
 217ret_from_syscall_trace:
 218        ;; tracing returns (possibly new) syscall number
 219        MV      .D2X    A4,B0
 220 ||     MVK     .S2     __NR_syscalls,B1
 221        CMPLTU  .L2     B0,B1,B1
 222
 223 [!B1]  BNOP    .S2     ret_from_syscall_function,5
 224 ||     MVK     .S1     -ENOSYS,A4
 225
 226        ;; reload syscall args from (possibly modified) stack frame
 227        ;; and get syscall handler addr from sys_call_table:
 228        LDW     .D2T2   *+SP(REGS_B4+8),B4
 229 ||     MVKL    .S2     sys_call_table,B1
 230        LDW     .D2T1   *+SP(REGS_A6+8),A6
 231 ||     MVKH    .S2     sys_call_table,B1
 232        LDW     .D2T2   *+B1[B0],B0
 233 ||     MVKL    .S2     ret_from_syscall_function,B3
 234        LDW     .D2T2   *+SP(REGS_B6+8),B6
 235 ||     MVKH    .S2     ret_from_syscall_function,B3
 236        LDW     .D2T1   *+SP(REGS_A8+8),A8
 237        LDW     .D2T2   *+SP(REGS_B8+8),B8
 238        NOP
 239        ; B0 = sys_call_table[__NR_*]
 240        BNOP    .S2     B0,5                    ; branch to syscall handler
 241 ||     LDW     .D2T1   *+SP(REGS_ORIG_A4+8),A4
 242
 243syscall_exit_work:
 244        AND     .D1     _TIF_SYSCALL_TRACE,A2,A0
 245 [!A0]  BNOP    .S1     work_pending,5
 246 [A0]   B       .S2     syscall_trace_exit
 247        ADDKPC  .S2     resume_userspace,B3,1
 248        MVC     .S2     CSR,B1
 249        SET     .S2     B1,0,0,B1
 250        MVC     .S2     B1,CSR          ; enable ints
 251
 252work_pending:
 253        AND     .D1     _TIF_NEED_RESCHED,A2,A0
 254 [!A0]  BNOP    .S1     work_notifysig,5
 255
 256work_resched:
 257#ifdef CONFIG_C6X_BIG_KERNEL
 258        MVKL    .S1     schedule,A1
 259        MVKH    .S1     schedule,A1
 260        B       .S2X    A1
 261#else
 262        B       .S2     schedule
 263#endif
 264        ADDKPC  .S2     work_rescheduled,B3,4
 265work_rescheduled:
 266        ;; make sure we don't miss an interrupt setting need_resched or
 267        ;; sigpending between sampling and the rti
 268        MASK_INT B2
 269        GET_THREAD_INFO A12
 270        LDW     .D1T1   *+A12(THREAD_INFO_FLAGS),A2
 271        MVK     .S1     _TIF_WORK_MASK,A1
 272        MVK     .S1     _TIF_NEED_RESCHED,A3
 273        NOP     2
 274        AND     .D1     A1,A2,A0
 275 ||     AND     .S1     A3,A2,A1
 276 [!A0]  BNOP    .S1     restore_all,5
 277 [A1]   BNOP    .S1     work_resched,5
 278
 279work_notifysig:
 280        ;; enable interrupts for do_notify_resume()
 281        UNMASK_INT B2
 282        B       .S2     do_notify_resume
 283        LDW     .D2T1   *+SP(REGS__END+8),A6 ; syscall flag
 284        ADDKPC  .S2     resume_userspace,B3,1
 285        ADD     .S1X    8,SP,A4         ; pt_regs pointer is first arg
 286        MV      .D2X    A2,B4           ; thread_info flags is second arg
 287
 288        ;;
 289        ;; On C64x+, the return way from exception and interrupt
 290        ;; is a little bit different
 291        ;;
 292ENTRY(ret_from_exception)
 293#ifdef CONFIG_PREEMPT
 294        MASK_INT B2
 295#endif
 296
 297ENTRY(ret_from_interrupt)
 298        ;;
 299        ;; Check if we are comming from user mode.
 300        ;;
 301        LDW     .D2T2   *+SP(REGS_TSR+8),B0
 302        MVK     .S2     0x40,B1
 303        NOP     3
 304        AND     .D2     B0,B1,B0
 305 [!B0]  BNOP    .S2     resume_kernel,5
 306
 307resume_userspace:
 308        ;; make sure we don't miss an interrupt setting need_resched or
 309        ;; sigpending between sampling and the rti
 310        MASK_INT B2
 311        GET_THREAD_INFO A12
 312        LDW     .D1T1   *+A12(THREAD_INFO_FLAGS),A2
 313        MVK     .S1     _TIF_WORK_MASK,A1
 314        MVK     .S1     _TIF_NEED_RESCHED,A3
 315        NOP     2
 316        AND     .D1     A1,A2,A0
 317 [A0]   BNOP    .S1     work_pending,5
 318        BNOP    .S1     restore_all,5
 319
 320        ;;
 321        ;; System call handling
 322        ;; B0 = syscall number (in sys_call_table)
 323        ;; A4,B4,A6,B6,A8,B8 = arguments of the syscall function
 324        ;; A4 is the return value register
 325        ;;
 326system_call_saved:
 327        MVK     .L2     1,B2
 328        STW     .D2T2   B2,*+SP(REGS__END+8)    ; set syscall flag
 329        MVC     .S2     B2,ECR                  ; ack the software exception
 330
 331        UNMASK_INT B2                   ; re-enable global IT
 332
 333system_call_saved_noack:
 334        ;; Check system call number
 335        MVK     .S2     __NR_syscalls,B1
 336#ifdef CONFIG_C6X_BIG_KERNEL
 337 ||     MVKL    .S1     sys_ni_syscall,A0
 338#endif
 339        CMPLTU  .L2     B0,B1,B1
 340#ifdef CONFIG_C6X_BIG_KERNEL
 341 ||     MVKH    .S1     sys_ni_syscall,A0
 342#endif
 343
 344        ;; Check for ptrace
 345        GET_THREAD_INFO A12
 346
 347#ifdef CONFIG_C6X_BIG_KERNEL
 348 [!B1]  B       .S2X    A0
 349#else
 350 [!B1]  B       .S2     sys_ni_syscall
 351#endif
 352 [!B1]  ADDKPC  .S2     ret_from_syscall_function,B3,4
 353
 354        ;; Get syscall handler addr from sys_call_table
 355        ;; call tracesys_on or call syscall handler
 356        LDW     .D1T1   *+A12(THREAD_INFO_FLAGS),A2
 357 ||     MVKL    .S2     sys_call_table,B1
 358        MVKH    .S2     sys_call_table,B1
 359        LDW     .D2T2   *+B1[B0],B0
 360        NOP     2
 361        ; A2 = thread_info flags
 362        AND     .D1     _TIF_SYSCALL_TRACE,A2,A2
 363 [A2]   BNOP    .S1     tracesys_on,5
 364        ;; B0 = _sys_call_table[__NR_*]
 365        B       .S2     B0
 366        ADDKPC  .S2     ret_from_syscall_function,B3,4
 367
 368ret_from_syscall_function:
 369        STW     .D2T1   A4,*+SP(REGS_A4+8)      ; save return value in A4
 370                                                ; original A4 is in orig_A4
 371syscall_exit:
 372        ;; make sure we don't miss an interrupt setting need_resched or
 373        ;; sigpending between sampling and the rti
 374        MASK_INT B2
 375        LDW     .D1T1   *+A12(THREAD_INFO_FLAGS),A2
 376        MVK     .S1     _TIF_ALLWORK_MASK,A1
 377        NOP     3
 378        AND     .D1     A1,A2,A2 ; check for work to do
 379 [A2]   BNOP    .S1     syscall_exit_work,5
 380
 381restore_all:
 382        RESTORE_ALL NRP,NTSR
 383
 384        ;;
 385        ;; After a fork we jump here directly from resume,
 386        ;; so that A4 contains the previous task structure.
 387        ;;
 388ENTRY(ret_from_fork)
 389#ifdef CONFIG_C6X_BIG_KERNEL
 390        MVKL    .S1     schedule_tail,A0
 391        MVKH    .S1     schedule_tail,A0
 392        B       .S2X    A0
 393#else
 394        B       .S2     schedule_tail
 395#endif
 396        ADDKPC  .S2     ret_from_fork_2,B3,4
 397ret_from_fork_2:
 398        ;; return 0 in A4 for child process
 399        GET_THREAD_INFO A12
 400        BNOP    .S2     syscall_exit,3
 401        MVK     .L2     0,B0
 402        STW     .D2T2   B0,*+SP(REGS_A4+8)
 403ENDPROC(ret_from_fork)
 404
 405ENTRY(ret_from_kernel_thread)
 406#ifdef CONFIG_C6X_BIG_KERNEL
 407        MVKL    .S1     schedule_tail,A0
 408        MVKH    .S1     schedule_tail,A0
 409        B       .S2X    A0
 410#else
 411        B       .S2     schedule_tail
 412#endif
 413        LDW     .D2T2   *+SP(REGS_A0+8),B10 /* get fn  */
 414        ADDKPC  .S2     0f,B3,3
 4150:
 416        B       .S2     B10                /* call fn */
 417        LDW     .D2T1   *+SP(REGS_A1+8),A4 /* get arg */
 418        ADDKPC  .S2     ret_from_fork_2,B3,3
 419ENDPROC(ret_from_kernel_thread)
 420
 421        ;;
 422        ;; These are the interrupt handlers, responsible for calling c6x_do_IRQ()
 423        ;;
 424        .macro SAVE_ALL_INT
 425        SAVE_ALL IRP,ITSR
 426        .endm
 427
 428        .macro CALL_INT int
 429#ifdef CONFIG_C6X_BIG_KERNEL
 430        MVKL    .S1     c6x_do_IRQ,A0
 431        MVKH    .S1     c6x_do_IRQ,A0
 432        BNOP    .S2X    A0,1
 433        MVK     .S1     int,A4
 434        ADDAW   .D2     SP,2,B4
 435        MVKL    .S2     ret_from_interrupt,B3
 436        MVKH    .S2     ret_from_interrupt,B3
 437#else
 438        CALLP   .S2     c6x_do_IRQ,B3
 439 ||     MVK     .S1     int,A4
 440 ||     ADDAW   .D2     SP,2,B4
 441        B       .S1     ret_from_interrupt
 442        NOP     5
 443#endif
 444        .endm
 445
 446ENTRY(_int4_handler)
 447        SAVE_ALL_INT
 448        CALL_INT 4
 449ENDPROC(_int4_handler)
 450
 451ENTRY(_int5_handler)
 452        SAVE_ALL_INT
 453        CALL_INT 5
 454ENDPROC(_int5_handler)
 455
 456ENTRY(_int6_handler)
 457        SAVE_ALL_INT
 458        CALL_INT 6
 459ENDPROC(_int6_handler)
 460
 461ENTRY(_int7_handler)
 462        SAVE_ALL_INT
 463        CALL_INT 7
 464ENDPROC(_int7_handler)
 465
 466ENTRY(_int8_handler)
 467        SAVE_ALL_INT
 468        CALL_INT 8
 469ENDPROC(_int8_handler)
 470
 471ENTRY(_int9_handler)
 472        SAVE_ALL_INT
 473        CALL_INT 9
 474ENDPROC(_int9_handler)
 475
 476ENTRY(_int10_handler)
 477        SAVE_ALL_INT
 478        CALL_INT 10
 479ENDPROC(_int10_handler)
 480
 481ENTRY(_int11_handler)
 482        SAVE_ALL_INT
 483        CALL_INT 11
 484ENDPROC(_int11_handler)
 485
 486ENTRY(_int12_handler)
 487        SAVE_ALL_INT
 488        CALL_INT 12
 489ENDPROC(_int12_handler)
 490
 491ENTRY(_int13_handler)
 492        SAVE_ALL_INT
 493        CALL_INT 13
 494ENDPROC(_int13_handler)
 495
 496ENTRY(_int14_handler)
 497        SAVE_ALL_INT
 498        CALL_INT 14
 499ENDPROC(_int14_handler)
 500
 501ENTRY(_int15_handler)
 502        SAVE_ALL_INT
 503        CALL_INT 15
 504ENDPROC(_int15_handler)
 505
 506        ;;
 507        ;; Handler for uninitialized and spurious interrupts
 508        ;;
 509ENTRY(_bad_interrupt)
 510        B       .S2     IRP
 511        NOP     5
 512ENDPROC(_bad_interrupt)
 513
 514        ;;
 515        ;; Entry for NMI/exceptions/syscall
 516        ;;
 517ENTRY(_nmi_handler)
 518        SAVE_ALL NRP,NTSR
 519
 520        MVC     .S2     EFR,B2
 521        CMPEQ   .L2     1,B2,B2
 522 ||     MVC     .S2     TSR,B1
 523        CLR     .S2     B1,10,10,B1
 524        MVC     .S2     B1,TSR
 525#ifdef CONFIG_C6X_BIG_KERNEL
 526 [!B2]  MVKL    .S1     process_exception,A0
 527 [!B2]  MVKH    .S1     process_exception,A0
 528 [!B2]  B       .S2X    A0
 529#else
 530 [!B2]  B       .S2     process_exception
 531#endif
 532 [B2]   B       .S2     system_call_saved
 533 [!B2]  ADDAW   .D2     SP,2,B1
 534 [!B2]  MV      .D1X    B1,A4
 535        ADDKPC  .S2     ret_from_trap,B3,2
 536
 537ret_from_trap:
 538        MV      .D2X    A4,B0
 539 [!B0]  BNOP    .S2     ret_from_exception,5
 540
 541#ifdef CONFIG_C6X_BIG_KERNEL
 542        MVKL    .S2     system_call_saved_noack,B3
 543        MVKH    .S2     system_call_saved_noack,B3
 544#endif
 545        LDW     .D2T2   *+SP(REGS_B0+8),B0
 546        LDW     .D2T1   *+SP(REGS_A4+8),A4
 547        LDW     .D2T2   *+SP(REGS_B4+8),B4
 548        LDW     .D2T1   *+SP(REGS_A6+8),A6
 549        LDW     .D2T2   *+SP(REGS_B6+8),B6
 550        LDW     .D2T1   *+SP(REGS_A8+8),A8
 551#ifdef CONFIG_C6X_BIG_KERNEL
 552 ||     B       .S2     B3
 553#else
 554 ||     B       .S2     system_call_saved_noack
 555#endif
 556        LDW     .D2T2   *+SP(REGS_B8+8),B8
 557        NOP     4
 558ENDPROC(_nmi_handler)
 559
 560        ;;
 561        ;; Jump to schedule() then return to ret_from_isr
 562        ;;
 563#ifdef  CONFIG_PREEMPT
 564resume_kernel:
 565        GET_THREAD_INFO A12
 566        LDW     .D1T1   *+A12(THREAD_INFO_PREEMPT_COUNT),A1
 567        NOP     4
 568 [A1]   BNOP    .S2     restore_all,5
 569
 570preempt_schedule:
 571        GET_THREAD_INFO A2
 572        LDW     .D1T1   *+A2(THREAD_INFO_FLAGS),A1
 573#ifdef CONFIG_C6X_BIG_KERNEL
 574        MVKL    .S2     preempt_schedule_irq,B0
 575        MVKH    .S2     preempt_schedule_irq,B0
 576        NOP     2
 577#else
 578        NOP     4
 579#endif
 580        AND     .D1     _TIF_NEED_RESCHED,A1,A1
 581 [!A1]  BNOP    .S2     restore_all,5
 582#ifdef CONFIG_C6X_BIG_KERNEL
 583        B       .S2     B0
 584#else
 585        B       .S2     preempt_schedule_irq
 586#endif
 587        ADDKPC  .S2     preempt_schedule,B3,4
 588#endif /* CONFIG_PREEMPT */
 589
 590ENTRY(enable_exception)
 591        DINT
 592        MVC     .S2     TSR,B0
 593        MVC     .S2     B3,NRP
 594        MVK     .L2     0xc,B1
 595        OR      .D2     B0,B1,B0
 596        MVC     .S2     B0,TSR                  ;  Set GEE and XEN in TSR
 597        B       .S2     NRP
 598        NOP     5
 599ENDPROC(enable_exception)
 600
 601        ;;
 602        ;; Special system calls
 603        ;; return address is in B3
 604        ;;
 605ENTRY(sys_rt_sigreturn)
 606        ADD     .D1X    SP,8,A4
 607#ifdef CONFIG_C6X_BIG_KERNEL
 608 ||     MVKL    .S1     do_rt_sigreturn,A0
 609        MVKH    .S1     do_rt_sigreturn,A0
 610        BNOP    .S2X    A0,5
 611#else
 612 ||     B       .S2     do_rt_sigreturn
 613        NOP     5
 614#endif
 615ENDPROC(sys_rt_sigreturn)
 616
 617ENTRY(sys_pread_c6x)
 618        MV      .D2X    A8,B7
 619#ifdef CONFIG_C6X_BIG_KERNEL
 620 ||     MVKL    .S1     sys_pread64,A0
 621        MVKH    .S1     sys_pread64,A0
 622        BNOP    .S2X    A0,5
 623#else
 624 ||     B       .S2     sys_pread64
 625        NOP     5
 626#endif
 627ENDPROC(sys_pread_c6x)
 628
 629ENTRY(sys_pwrite_c6x)
 630        MV      .D2X    A8,B7
 631#ifdef CONFIG_C6X_BIG_KERNEL
 632 ||     MVKL    .S1     sys_pwrite64,A0
 633        MVKH    .S1     sys_pwrite64,A0
 634        BNOP    .S2X    A0,5
 635#else
 636 ||     B       .S2     sys_pwrite64
 637        NOP     5
 638#endif
 639ENDPROC(sys_pwrite_c6x)
 640
 641;; On Entry
 642;;   A4 - path
 643;;   B4 - offset_lo (LE), offset_hi (BE)
 644;;   A6 - offset_lo (BE), offset_hi (LE)
 645ENTRY(sys_truncate64_c6x)
 646#ifdef CONFIG_CPU_BIG_ENDIAN
 647        MV      .S2     B4,B5
 648        MV      .D2X    A6,B4
 649#else
 650        MV      .D2X    A6,B5
 651#endif
 652#ifdef CONFIG_C6X_BIG_KERNEL
 653 ||     MVKL    .S1     sys_truncate64,A0
 654        MVKH    .S1     sys_truncate64,A0
 655        BNOP    .S2X    A0,5
 656#else
 657 ||     B       .S2     sys_truncate64
 658        NOP     5
 659#endif
 660ENDPROC(sys_truncate64_c6x)
 661
 662;; On Entry
 663;;   A4 - fd
 664;;   B4 - offset_lo (LE), offset_hi (BE)
 665;;   A6 - offset_lo (BE), offset_hi (LE)
 666ENTRY(sys_ftruncate64_c6x)
 667#ifdef CONFIG_CPU_BIG_ENDIAN
 668        MV      .S2     B4,B5
 669        MV      .D2X    A6,B4
 670#else
 671        MV      .D2X    A6,B5
 672#endif
 673#ifdef CONFIG_C6X_BIG_KERNEL
 674 ||     MVKL    .S1     sys_ftruncate64,A0
 675        MVKH    .S1     sys_ftruncate64,A0
 676        BNOP    .S2X    A0,5
 677#else
 678 ||     B       .S2     sys_ftruncate64
 679        NOP     5
 680#endif
 681ENDPROC(sys_ftruncate64_c6x)
 682
 683;; On Entry
 684;;   A4 - fd
 685;;   B4 - offset_lo (LE), offset_hi (BE)
 686;;   A6 - offset_lo (BE), offset_hi (LE)
 687;;   B6 - len_lo (LE), len_hi (BE)
 688;;   A8 - len_lo (BE), len_hi (LE)
 689;;   B8 - advice
 690ENTRY(sys_fadvise64_64_c6x)
 691#ifdef CONFIG_C6X_BIG_KERNEL
 692        MVKL    .S1     sys_fadvise64_64,A0
 693        MVKH    .S1     sys_fadvise64_64,A0
 694        BNOP    .S2X    A0,2
 695#else
 696        B       .S2     sys_fadvise64_64
 697        NOP     2
 698#endif
 699#ifdef CONFIG_CPU_BIG_ENDIAN
 700        MV      .L2     B4,B5
 701 ||     MV      .D2X    A6,B4
 702        MV      .L1     A8,A6
 703 ||     MV      .D1X    B6,A7
 704#else
 705        MV      .D2X    A6,B5
 706        MV      .L1     A8,A7
 707 ||     MV      .D1X    B6,A6
 708#endif
 709        MV      .L2     B8,B6
 710ENDPROC(sys_fadvise64_64_c6x)
 711
 712;; On Entry
 713;;   A4 - fd
 714;;   B4 - mode
 715;;   A6 - offset_hi
 716;;   B6 - offset_lo
 717;;   A8 - len_hi
 718;;   B8 - len_lo
 719ENTRY(sys_fallocate_c6x)
 720#ifdef CONFIG_C6X_BIG_KERNEL
 721        MVKL    .S1     sys_fallocate,A0
 722        MVKH    .S1     sys_fallocate,A0
 723        BNOP    .S2X    A0,1
 724#else
 725        B       .S2     sys_fallocate
 726        NOP
 727#endif
 728        MV      .D1     A6,A7
 729        MV      .D1X    B6,A6
 730        MV      .D2X    A8,B7
 731        MV      .D2     B8,B6
 732ENDPROC(sys_fallocate_c6x)
 733
 734        ;; put this in .neardata for faster access when using DSBT mode
 735        .section .neardata,"aw",@progbits
 736        .global current_ksp
 737        .hidden current_ksp
 738current_ksp:
 739        .word   init_thread_union + THREAD_START_SP
 740