2011-10-04 11:10:02 -04:00
;
; Port on Texas Instruments TMS320C6x architecture
;
; Copyright (C) 2004-2011 Texas Instruments Incorporated
; Author: Aurelien Jacquiot (aurelien.jacquiot@virtuallogix.com)
; Updated for 2.6.34: Mark Salter <msalter@redhat.com>
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License version 2 as
; published by the Free Software Foundation.
;
# include < l i n u x / s y s . h >
# include < l i n u x / l i n k a g e . h >
# include < a s m / t h r e a d _ i n f o . h >
# include < a s m / a s m - o f f s e t s . h >
# include < a s m / u n i s t d . h >
# include < a s m / e r r n o . h >
; Registers naming
# define D P B 1 4
# define S P B 1 5
# ifndef C O N F I G _ P R E E M P T
# define r e s u m e _ k e r n e l r e s t o r e _ a l l
# endif
.altmacro
.macro MASK_INT reg
MVC . S 2 C S R ,r e g
CLR . S 2 r e g ,0 ,0 ,r e g
MVC . S 2 r e g ,C S R
.endm
.macro UNMASK_INT reg
MVC . S 2 C S R ,r e g
SET . S 2 r e g ,0 ,0 ,r e g
MVC . S 2 r e g ,C S R
.endm
.macro GET_THREAD_INFO reg
SHR . S 1 X S P ,T H R E A D _ S H I F T ,r e g
SHL . S 1 r e g ,T H R E A D _ S H I F T ,r e g
.endm
;;
;; This defines the normal kernel pt_regs layout.
;;
.macro SAVE_ALL _ _ rp _ _ t s r
STW . D 2 T 2 B 0 ,* S P - - [ 2 ] ; save original B0
MVKL . S 2 c u r r e n t _ k s p ,B 0
MVKH . S 2 c u r r e n t _ k s p ,B 0
LDW . D 2 T 2 * B 0 ,B 1 ; KSP
NOP 3
STW . D 2 T 2 B 1 ,* + S P [ 1 ] ; save original B1
XOR . D 2 S P ,B 1 ,B 0 ; (SP ^ KSP)
LDW . D 2 T 2 * + S P [ 1 ] ,B 1 ; restore B0/B1
LDW . D 2 T 2 * + + S P [ 2 ] ,B 0
SHR . S 2 B 0 ,T H R E A D _ S H I F T ,B 0 ; 0 if already using kstack
[ B0 ] S T D W . D 2 T 2 S P : D P ,* - - B 1 [ 1 ] ; user: save user sp/dp kstack
[ B0 ] M V . S 2 B 1 ,S P ; and switch to kstack
| | [ ! B0 ] S T D W . D 2 T 2 S P : D P ,* - - S P [ 1 ] ; kernel: save on current stack
SUBAW . D 2 S P ,2 ,S P
ADD . D 1 X S P ,- 8 ,A 1 5
| | STDW . D 2 T 1 A 1 5 : A 1 4 ,* S P - - [ 1 6 ] ; save A15:A14
STDW . D 2 T 2 B 1 3 : B 1 2 ,* S P - - [ 1 ]
| | STDW . D 1 T 1 A 1 3 : A 1 2 ,* A 1 5 - - [ 1 ]
| | MVC . S 2 _ _ r p ,B 1 3
STDW . D 2 T 2 B 1 1 : B 1 0 ,* S P - - [ 1 ]
| | STDW . D 1 T 1 A 1 1 : A 1 0 ,* A 1 5 - - [ 1 ]
| | MVC . S 2 C S R ,B 1 2
STDW . D 2 T 2 B 9 : B 8 ,* S P - - [ 1 ]
| | STDW . D 1 T 1 A 9 : A 8 ,* A 1 5 - - [ 1 ]
| | MVC . S 2 R I L C ,B 1 1
STDW . D 2 T 2 B 7 : B 6 ,* S P - - [ 1 ]
| | STDW . D 1 T 1 A 7 : A 6 ,* A 1 5 - - [ 1 ]
| | MVC . S 2 I L C ,B 1 0
STDW . D 2 T 2 B 5 : B 4 ,* S P - - [ 1 ]
| | STDW . D 1 T 1 A 5 : A 4 ,* A 1 5 - - [ 1 ]
STDW . D 2 T 2 B 3 : B 2 ,* S P - - [ 1 ]
| | STDW . D 1 T 1 A 3 : A 2 ,* A 1 5 - - [ 1 ]
| | MVC . S 2 _ _ t s r ,B 5
STDW . D 2 T 2 B 1 : B 0 ,* S P - - [ 1 ]
| | STDW . D 1 T 1 A 1 : A 0 ,* A 1 5 - - [ 1 ]
| | MV . S 1 X B 5 ,A 5
STDW . D 2 T 2 B 3 1 : B 3 0 ,* S P - - [ 1 ]
| | STDW . D 1 T 1 A 3 1 : A 3 0 ,* A 1 5 - - [ 1 ]
STDW . D 2 T 2 B 2 9 : B 2 8 ,* S P - - [ 1 ]
| | STDW . D 1 T 1 A 2 9 : A 2 8 ,* A 1 5 - - [ 1 ]
STDW . D 2 T 2 B 2 7 : B 2 6 ,* S P - - [ 1 ]
| | STDW . D 1 T 1 A 2 7 : A 2 6 ,* A 1 5 - - [ 1 ]
STDW . D 2 T 2 B 2 5 : B 2 4 ,* S P - - [ 1 ]
| | STDW . D 1 T 1 A 2 5 : A 2 4 ,* A 1 5 - - [ 1 ]
STDW . D 2 T 2 B 2 3 : B 2 2 ,* S P - - [ 1 ]
| | STDW . D 1 T 1 A 2 3 : A 2 2 ,* A 1 5 - - [ 1 ]
STDW . D 2 T 2 B 2 1 : B 2 0 ,* S P - - [ 1 ]
| | STDW . D 1 T 1 A 2 1 : A 2 0 ,* A 1 5 - - [ 1 ]
STDW . D 2 T 2 B 1 9 : B 1 8 ,* S P - - [ 1 ]
| | STDW . D 1 T 1 A 1 9 : A 1 8 ,* A 1 5 - - [ 1 ]
STDW . D 2 T 2 B 1 7 : B 1 6 ,* S P - - [ 1 ]
| | STDW . D 1 T 1 A 1 7 : A 1 6 ,* A 1 5 - - [ 1 ]
STDW . D 2 T 2 B 1 3 : B 1 2 ,* S P - - [ 1 ] ; save PC and CSR
STDW . D 2 T 2 B 1 1 : B 1 0 ,* S P - - [ 1 ] ; save RILC and ILC
STDW . D 2 T 1 A 5 : A 4 ,* S P - - [ 1 ] ; save TSR and orig A4
;; We left an unused word on the stack just above pt_regs.
;; It is used to save whether or not this frame is due to
;; a syscall. It is cleared here, but the syscall handler
;; sets it to a non-zero value.
MVK . L 2 0 ,B 1
STW . D 2 T 2 B 1 ,* + S P ( R E G S _ _ E N D + 8 ) ; clear syscall flag
.endm
.macro RESTORE_ALL _ _ rp _ _ t s r
LDDW . D 2 T 2 * + + S P [ 1 ] ,B 9 : B 8 ; get TSR (B9)
LDDW . D 2 T 2 * + + S P [ 1 ] ,B 1 1 : B 1 0 ; get RILC (B11) and ILC (B10)
LDDW . D 2 T 2 * + + S P [ 1 ] ,B 1 3 : B 1 2 ; get PC (B13) and CSR (B12)
ADDAW . D 1 X S P ,3 0 ,A 1 5
LDDW . D 1 T 1 * + + A 1 5 [ 1 ] ,A 1 7 : A 1 6
| | LDDW . D 2 T 2 * + + S P [ 1 ] ,B 1 7 : B 1 6
LDDW . D 1 T 1 * + + A 1 5 [ 1 ] ,A 1 9 : A 1 8
| | LDDW . D 2 T 2 * + + S P [ 1 ] ,B 1 9 : B 1 8
LDDW . D 1 T 1 * + + A 1 5 [ 1 ] ,A 2 1 : A 2 0
| | LDDW . D 2 T 2 * + + S P [ 1 ] ,B 2 1 : B 2 0
LDDW . D 1 T 1 * + + A 1 5 [ 1 ] ,A 2 3 : A 2 2
| | LDDW . D 2 T 2 * + + S P [ 1 ] ,B 2 3 : B 2 2
LDDW . D 1 T 1 * + + A 1 5 [ 1 ] ,A 2 5 : A 2 4
| | LDDW . D 2 T 2 * + + S P [ 1 ] ,B 2 5 : B 2 4
LDDW . D 1 T 1 * + + A 1 5 [ 1 ] ,A 2 7 : A 2 6
| | LDDW . D 2 T 2 * + + S P [ 1 ] ,B 2 7 : B 2 6
LDDW . D 1 T 1 * + + A 1 5 [ 1 ] ,A 2 9 : A 2 8
| | LDDW . D 2 T 2 * + + S P [ 1 ] ,B 2 9 : B 2 8
LDDW . D 1 T 1 * + + A 1 5 [ 1 ] ,A 3 1 : A 3 0
| | LDDW . D 2 T 2 * + + S P [ 1 ] ,B 3 1 : B 3 0
LDDW . D 1 T 1 * + + A 1 5 [ 1 ] ,A 1 : A 0
| | LDDW . D 2 T 2 * + + S P [ 1 ] ,B 1 : B 0
LDDW . D 1 T 1 * + + A 1 5 [ 1 ] ,A 3 : A 2
| | LDDW . D 2 T 2 * + + S P [ 1 ] ,B 3 : B 2
| | MVC . S 2 B 9 ,_ _ t s r
LDDW . D 1 T 1 * + + A 1 5 [ 1 ] ,A 5 : A 4
| | LDDW . D 2 T 2 * + + S P [ 1 ] ,B 5 : B 4
| | MVC . S 2 B 1 1 ,R I L C
LDDW . D 1 T 1 * + + A 1 5 [ 1 ] ,A 7 : A 6
| | LDDW . D 2 T 2 * + + S P [ 1 ] ,B 7 : B 6
| | MVC . S 2 B 1 0 ,I L C
LDDW . D 1 T 1 * + + A 1 5 [ 1 ] ,A 9 : A 8
| | LDDW . D 2 T 2 * + + S P [ 1 ] ,B 9 : B 8
| | MVC . S 2 B 1 3 ,_ _ r p
LDDW . D 1 T 1 * + + A 1 5 [ 1 ] ,A 1 1 : A 1 0
| | LDDW . D 2 T 2 * + + S P [ 1 ] ,B 1 1 : B 1 0
| | MVC . S 2 B 1 2 ,C S R
LDDW . D 1 T 1 * + + A 1 5 [ 1 ] ,A 1 3 : A 1 2
| | LDDW . D 2 T 2 * + + S P [ 1 ] ,B 1 3 : B 1 2
MV . D 2 X A 1 5 ,S P
| | MVKL . S 1 c u r r e n t _ k s p ,A 1 5
MVKH . S 1 c u r r e n t _ k s p ,A 1 5
| | ADDAW . D 1 X S P ,6 ,A 1 4
STW . D 1 T 1 A 1 4 ,* A 1 5 ; save kernel stack pointer
LDDW . D 2 T 1 * + + S P [ 1 ] ,A 1 5 : A 1 4
B . S 2 _ _ r p ; return from interruption
LDDW . D 2 T 2 * + S P [ 1 ] ,S P : D P
NOP 4
.endm
.section .text
;;
;; Jump to schedule() then return to ret_from_exception
;;
_reschedule :
# ifdef C O N F I G _ C 6 X _ B I G _ K E R N E L
MVKL . S 1 s c h e d u l e ,A 0
MVKH . S 1 s c h e d u l e ,A 0
B . S 2 X A 0
# else
B . S 1 s c h e d u l e
# endif
ADDKPC . S 2 r e t _ f r o m _ e x c e p t i o n ,B 3 ,4
;;
;; Called before syscall handler when process is being debugged
;;
tracesys_on :
# ifdef C O N F I G _ C 6 X _ B I G _ K E R N E L
MVKL . S 1 s y s c a l l _ t r a c e _ e n t r y ,A 0
MVKH . S 1 s y s c a l l _ t r a c e _ e n t r y ,A 0
B . S 2 X A 0
# else
B . S 1 s y s c a l l _ t r a c e _ e n t r y
# endif
ADDKPC . S 2 r e t _ f r o m _ s y s c a l l _ t r a c e ,B 3 ,3
ADD . S 1 X 8 ,S P ,A 4
ret_from_syscall_trace :
;; tracing returns (possibly new) syscall number
MV . D 2 X A 4 ,B 0
| | MVK . S 2 _ _ N R _ s y s c a l l s ,B 1
CMPLTU . L 2 B 0 ,B 1 ,B 1
[ ! B1 ] B N O P . S 2 r e t _ f r o m _ s y s c a l l _ f u n c t i o n ,5
| | MVK . S 1 - E N O S Y S ,A 4
;; reload syscall args from (possibly modified) stack frame
;; and get syscall handler addr from sys_call_table:
LDW . D 2 T 2 * + S P ( R E G S _ B 4 + 8 ) ,B 4
| | MVKL . S 2 s y s _ c a l l _ t a b l e ,B 1
LDW . D 2 T 1 * + S P ( R E G S _ A 6 + 8 ) ,A 6
| | MVKH . S 2 s y s _ c a l l _ t a b l e ,B 1
LDW . D 2 T 2 * + B 1 [ B 0 ] ,B 0
| | MVKL . S 2 r e t _ f r o m _ s y s c a l l _ f u n c t i o n ,B 3
LDW . D 2 T 2 * + S P ( R E G S _ B 6 + 8 ) ,B 6
| | MVKH . S 2 r e t _ f r o m _ s y s c a l l _ f u n c t i o n ,B 3
LDW . D 2 T 1 * + S P ( R E G S _ A 8 + 8 ) ,A 8
LDW . D 2 T 2 * + S P ( R E G S _ B 8 + 8 ) ,B 8
NOP
; B0 = sys_call_table[__NR_*]
BNOP . S 2 B 0 ,5 ; branch to syscall handler
| | LDW . D 2 T 1 * + S P ( R E G S _ O R I G _ A 4 + 8 ) ,A 4
syscall_exit_work :
AND . D 1 _ T I F _ S Y S C A L L _ T R A C E ,A 2 ,A 0
[ ! A0 ] B N O P . S 1 w o r k _ p e n d i n g ,5
[ A0 ] B . S 2 s y s c a l l _ t r a c e _ e x i t
ADDKPC . S 2 r e s u m e _ u s e r s p a c e ,B 3 ,1
MVC . S 2 C S R ,B 1
SET . S 2 B 1 ,0 ,0 ,B 1
MVC . S 2 B 1 ,C S R ; enable ints
work_pending :
AND . D 1 _ T I F _ N E E D _ R E S C H E D ,A 2 ,A 0
[ ! A0 ] B N O P . S 1 w o r k _ n o t i f y s i g ,5
work_resched :
# ifdef C O N F I G _ C 6 X _ B I G _ K E R N E L
MVKL . S 1 s c h e d u l e ,A 1
MVKH . S 1 s c h e d u l e ,A 1
B . S 2 X A 1
# else
B . S 2 s c h e d u l e
# endif
ADDKPC . S 2 w o r k _ r e s c h e d u l e d ,B 3 ,4
work_rescheduled :
;; make sure we don't miss an interrupt setting need_resched or
;; sigpending between sampling and the rti
MASK_ I N T B 2
GET_ T H R E A D _ I N F O A 1 2
LDW . D 1 T 1 * + A 1 2 ( T H R E A D _ I N F O _ F L A G S ) ,A 2
MVK . S 1 _ T I F _ W O R K _ M A S K ,A 1
MVK . S 1 _ T I F _ N E E D _ R E S C H E D ,A 3
NOP 2
AND . D 1 A 1 ,A 2 ,A 0
| | AND . S 1 A 3 ,A 2 ,A 1
[ ! A0 ] B N O P . S 1 r e s t o r e _ a l l ,5
[ A1 ] B N O P . S 1 w o r k _ r e s c h e d ,5
work_notifysig :
2012-11-26 18:06:13 -05:00
;; enable interrupts for do_notify_resume()
UNMASK_ I N T B 2
2011-10-04 11:10:02 -04:00
B . S 2 d o _ n o t i f y _ r e s u m e
LDW . D 2 T 1 * + S P ( R E G S _ _ E N D + 8 ) ,A 6 ; syscall flag
ADDKPC . S 2 r e s u m e _ u s e r s p a c e ,B 3 ,1
ADD . S 1 X 8 ,S P ,A 4 ; pt_regs pointer is first arg
MV . D 2 X A 2 ,B 4 ; thread_info flags is second arg
;;
;; On C64x+, the return way from exception and interrupt
;; is a little bit different
;;
ENTRY( r e t _ f r o m _ e x c e p t i o n )
# ifdef C O N F I G _ P R E E M P T
MASK_ I N T B 2
# endif
ENTRY( r e t _ f r o m _ i n t e r r u p t )
;;
;; Check if we are comming from user mode.
;;
LDW . D 2 T 2 * + S P ( R E G S _ T S R + 8 ) ,B 0
MVK . S 2 0 x40 ,B 1
NOP 3
AND . D 2 B 0 ,B 1 ,B 0
[ ! B0 ] B N O P . S 2 r e s u m e _ k e r n e l ,5
resume_userspace :
;; make sure we don't miss an interrupt setting need_resched or
;; sigpending between sampling and the rti
MASK_ I N T B 2
GET_ T H R E A D _ I N F O A 1 2
LDW . D 1 T 1 * + A 1 2 ( T H R E A D _ I N F O _ F L A G S ) ,A 2
MVK . S 1 _ T I F _ W O R K _ M A S K ,A 1
MVK . S 1 _ T I F _ N E E D _ R E S C H E D ,A 3
NOP 2
AND . D 1 A 1 ,A 2 ,A 0
[ A0 ] B N O P . S 1 w o r k _ p e n d i n g ,5
BNOP . S 1 r e s t o r e _ a l l ,5
;;
;; System call handling
;; B0 = syscall number (in sys_call_table)
;; A4,B4,A6,B6,A8,B8 = arguments of the syscall function
;; A4 is the return value register
;;
system_call_saved :
MVK . L 2 1 ,B 2
STW . D 2 T 2 B 2 ,* + S P ( R E G S _ _ E N D + 8 ) ; set syscall flag
MVC . S 2 B 2 ,E C R ; ack the software exception
UNMASK_ I N T B 2 ; re-enable global IT
system_call_saved_noack :
;; Check system call number
MVK . S 2 _ _ N R _ s y s c a l l s ,B 1
# ifdef C O N F I G _ C 6 X _ B I G _ K E R N E L
| | MVKL . S 1 s y s _ n i _ s y s c a l l ,A 0
# endif
CMPLTU . L 2 B 0 ,B 1 ,B 1
# ifdef C O N F I G _ C 6 X _ B I G _ K E R N E L
| | MVKH . S 1 s y s _ n i _ s y s c a l l ,A 0
# endif
;; Check for ptrace
GET_ T H R E A D _ I N F O A 1 2
# ifdef C O N F I G _ C 6 X _ B I G _ K E R N E L
[ ! B1 ] B . S 2 X A 0
# else
[ ! B1 ] B . S 2 s y s _ n i _ s y s c a l l
# endif
[ ! B1 ] A D D K P C . S 2 r e t _ f r o m _ s y s c a l l _ f u n c t i o n ,B 3 ,4
;; Get syscall handler addr from sys_call_table
;; call tracesys_on or call syscall handler
LDW . D 1 T 1 * + A 1 2 ( T H R E A D _ I N F O _ F L A G S ) ,A 2
| | MVKL . S 2 s y s _ c a l l _ t a b l e ,B 1
MVKH . S 2 s y s _ c a l l _ t a b l e ,B 1
LDW . D 2 T 2 * + B 1 [ B 0 ] ,B 0
NOP 2
; A2 = thread_info flags
AND . D 1 _ T I F _ S Y S C A L L _ T R A C E ,A 2 ,A 2
[ A2 ] B N O P . S 1 t r a c e s y s _ o n ,5
;; B0 = _sys_call_table[__NR_*]
B . S 2 B 0
ADDKPC . S 2 r e t _ f r o m _ s y s c a l l _ f u n c t i o n ,B 3 ,4
ret_from_syscall_function :
STW . D 2 T 1 A 4 ,* + S P ( R E G S _ A 4 + 8 ) ; save return value in A4
; original A4 is in orig_A4
syscall_exit :
;; make sure we don't miss an interrupt setting need_resched or
;; sigpending between sampling and the rti
MASK_ I N T B 2
LDW . D 1 T 1 * + A 1 2 ( T H R E A D _ I N F O _ F L A G S ) ,A 2
MVK . S 1 _ T I F _ A L L W O R K _ M A S K ,A 1
NOP 3
AND . D 1 A 1 ,A 2 ,A 2 ; check for work to do
[ A2 ] B N O P . S 1 s y s c a l l _ e x i t _ w o r k ,5
restore_all :
RESTORE_ A L L N R P ,N T S R
;;
;; After a fork we jump here directly from resume,
;; so that A4 contains the previous task structure.
;;
ENTRY( r e t _ f r o m _ f o r k )
# ifdef C O N F I G _ C 6 X _ B I G _ K E R N E L
MVKL . S 1 s c h e d u l e _ t a i l ,A 0
MVKH . S 1 s c h e d u l e _ t a i l ,A 0
B . S 2 X A 0
# else
B . S 2 s c h e d u l e _ t a i l
# endif
ADDKPC . S 2 r e t _ f r o m _ f o r k _ 2 ,B 3 ,4
ret_from_fork_2 :
;; return 0 in A4 for child process
GET_ T H R E A D _ I N F O A 1 2
BNOP . S 2 s y s c a l l _ e x i t ,3
MVK . L 2 0 ,B 0
STW . D 2 T 2 B 0 ,* + S P ( R E G S _ A 4 + 8 )
ENDPROC( r e t _ f r o m _ f o r k )
2012-09-21 12:26:37 -04:00
ENTRY( r e t _ f r o m _ k e r n e l _ t h r e a d )
# ifdef C O N F I G _ C 6 X _ B I G _ K E R N E L
MVKL . S 1 s c h e d u l e _ t a i l ,A 0
MVKH . S 1 s c h e d u l e _ t a i l ,A 0
B . S 2 X A 0
# else
B . S 2 s c h e d u l e _ t a i l
# endif
LDW . D 2 T 2 * + S P ( R E G S _ A 0 + 8 ) ,B 1 0 / * g e t f n * /
ADDKPC . S 2 0 f ,B 3 ,3
0 :
B . S 2 B 1 0 / * c a l l f n * /
LDW . D 2 T 1 * + S P ( R E G S _ A 1 + 8 ) ,A 4 / * g e t a r g * /
2012-10-13 02:35:21 -04:00
ADDKPC . S 2 r e t _ f r o m _ f o r k _ 2 ,B 3 ,3
2012-09-21 12:26:37 -04:00
ENDPROC( r e t _ f r o m _ k e r n e l _ t h r e a d )
2011-10-04 11:10:02 -04:00
;;
2012-11-26 18:14:00 -05:00
;; These are the interrupt handlers, responsible for calling c6x_do_IRQ()
2011-10-04 11:10:02 -04:00
;;
.macro SAVE_ALL_INT
SAVE_ A L L I R P ,I T S R
.endm
.macro CALL_INT int
# ifdef C O N F I G _ C 6 X _ B I G _ K E R N E L
MVKL . S 1 c6 x _ d o _ I R Q ,A 0
MVKH . S 1 c6 x _ d o _ I R Q ,A 0
BNOP . S 2 X A 0 ,1
MVK . S 1 i n t ,A 4
ADDAW . D 2 S P ,2 ,B 4
MVKL . S 2 r e t _ f r o m _ i n t e r r u p t ,B 3
MVKH . S 2 r e t _ f r o m _ i n t e r r u p t ,B 3
# else
CALLP . S 2 c6 x _ d o _ I R Q ,B 3
| | MVK . S 1 i n t ,A 4
| | ADDAW . D 2 S P ,2 ,B 4
B . S 1 r e t _ f r o m _ i n t e r r u p t
NOP 5
# endif
.endm
ENTRY( _ i n t 4 _ h a n d l e r )
SAVE_ A L L _ I N T
CALL_ I N T 4
ENDPROC( _ i n t 4 _ h a n d l e r )
ENTRY( _ i n t 5 _ h a n d l e r )
SAVE_ A L L _ I N T
CALL_ I N T 5
ENDPROC( _ i n t 5 _ h a n d l e r )
ENTRY( _ i n t 6 _ h a n d l e r )
SAVE_ A L L _ I N T
CALL_ I N T 6
ENDPROC( _ i n t 6 _ h a n d l e r )
ENTRY( _ i n t 7 _ h a n d l e r )
SAVE_ A L L _ I N T
CALL_ I N T 7
ENDPROC( _ i n t 7 _ h a n d l e r )
ENTRY( _ i n t 8 _ h a n d l e r )
SAVE_ A L L _ I N T
CALL_ I N T 8
ENDPROC( _ i n t 8 _ h a n d l e r )
ENTRY( _ i n t 9 _ h a n d l e r )
SAVE_ A L L _ I N T
CALL_ I N T 9
ENDPROC( _ i n t 9 _ h a n d l e r )
ENTRY( _ i n t 1 0 _ h a n d l e r )
SAVE_ A L L _ I N T
CALL_ I N T 1 0
ENDPROC( _ i n t 1 0 _ h a n d l e r )
ENTRY( _ i n t 1 1 _ h a n d l e r )
SAVE_ A L L _ I N T
CALL_ I N T 1 1
ENDPROC( _ i n t 1 1 _ h a n d l e r )
ENTRY( _ i n t 1 2 _ h a n d l e r )
SAVE_ A L L _ I N T
CALL_ I N T 1 2
ENDPROC( _ i n t 1 2 _ h a n d l e r )
ENTRY( _ i n t 1 3 _ h a n d l e r )
SAVE_ A L L _ I N T
CALL_ I N T 1 3
ENDPROC( _ i n t 1 3 _ h a n d l e r )
ENTRY( _ i n t 1 4 _ h a n d l e r )
SAVE_ A L L _ I N T
CALL_ I N T 1 4
ENDPROC( _ i n t 1 4 _ h a n d l e r )
ENTRY( _ i n t 1 5 _ h a n d l e r )
SAVE_ A L L _ I N T
CALL_ I N T 1 5
ENDPROC( _ i n t 1 5 _ h a n d l e r )
;;
;; Handler for uninitialized and spurious interrupts
;;
ENTRY( _ b a d _ i n t e r r u p t )
B . S 2 I R P
NOP 5
ENDPROC( _ b a d _ i n t e r r u p t )
;;
;; Entry for NMI/exceptions/syscall
;;
ENTRY( _ n m i _ h a n d l e r )
SAVE_ A L L N R P ,N T S R
MVC . S 2 E F R ,B 2
CMPEQ . L 2 1 ,B 2 ,B 2
| | MVC . S 2 T S R ,B 1
CLR . S 2 B 1 ,1 0 ,1 0 ,B 1
MVC . S 2 B 1 ,T S R
# ifdef C O N F I G _ C 6 X _ B I G _ K E R N E L
[ ! B2 ] M V K L . S 1 p r o c e s s _ e x c e p t i o n ,A 0
[ ! B2 ] M V K H . S 1 p r o c e s s _ e x c e p t i o n ,A 0
[ ! B2 ] B . S 2 X A 0
# else
[ ! B2 ] B . S 2 p r o c e s s _ e x c e p t i o n
# endif
[ B2 ] B . S 2 s y s t e m _ c a l l _ s a v e d
[ ! B2 ] A D D A W . D 2 S P ,2 ,B 1
[ ! B2 ] M V . D 1 X B 1 ,A 4
ADDKPC . S 2 r e t _ f r o m _ t r a p ,B 3 ,2
ret_from_trap :
MV . D 2 X A 4 ,B 0
[ ! B0 ] B N O P . S 2 r e t _ f r o m _ e x c e p t i o n ,5
# ifdef C O N F I G _ C 6 X _ B I G _ K E R N E L
MVKL . S 2 s y s t e m _ c a l l _ s a v e d _ n o a c k ,B 3
MVKH . S 2 s y s t e m _ c a l l _ s a v e d _ n o a c k ,B 3
# endif
LDW . D 2 T 2 * + S P ( R E G S _ B 0 + 8 ) ,B 0
LDW . D 2 T 1 * + S P ( R E G S _ A 4 + 8 ) ,A 4
LDW . D 2 T 2 * + S P ( R E G S _ B 4 + 8 ) ,B 4
LDW . D 2 T 1 * + S P ( R E G S _ A 6 + 8 ) ,A 6
LDW . D 2 T 2 * + S P ( R E G S _ B 6 + 8 ) ,B 6
LDW . D 2 T 1 * + S P ( R E G S _ A 8 + 8 ) ,A 8
# ifdef C O N F I G _ C 6 X _ B I G _ K E R N E L
| | B . S 2 B 3
# else
| | B . S 2 s y s t e m _ c a l l _ s a v e d _ n o a c k
# endif
LDW . D 2 T 2 * + S P ( R E G S _ B 8 + 8 ) ,B 8
NOP 4
ENDPROC( _ n m i _ h a n d l e r )
;;
;; Jump to schedule() then return to ret_from_isr
;;
# ifdef C O N F I G _ P R E E M P T
resume_kernel :
GET_ T H R E A D _ I N F O A 1 2
LDW . D 1 T 1 * + A 1 2 ( T H R E A D _ I N F O _ P R E E M P T _ C O U N T ) ,A 1
NOP 4
[ A1 ] B N O P . S 2 r e s t o r e _ a l l ,5
preempt_schedule :
GET_ T H R E A D _ I N F O A 2
LDW . D 1 T 1 * + A 2 ( T H R E A D _ I N F O _ F L A G S ) ,A 1
# ifdef C O N F I G _ C 6 X _ B I G _ K E R N E L
MVKL . S 2 p r e e m p t _ s c h e d u l e _ i r q ,B 0
MVKH . S 2 p r e e m p t _ s c h e d u l e _ i r q ,B 0
NOP 2
# else
NOP 4
# endif
AND . D 1 _ T I F _ N E E D _ R E S C H E D ,A 1 ,A 1
[ ! A1 ] B N O P . S 2 r e s t o r e _ a l l ,5
# ifdef C O N F I G _ C 6 X _ B I G _ K E R N E L
B . S 2 B 0
# else
B . S 2 p r e e m p t _ s c h e d u l e _ i r q
# endif
ADDKPC . S 2 p r e e m p t _ s c h e d u l e ,B 3 ,4
# endif / * C O N F I G _ P R E E M P T * /
ENTRY( e n a b l e _ e x c e p t i o n )
DINT
MVC . S 2 T S R ,B 0
MVC . S 2 B 3 ,N R P
MVK . L 2 0 x c ,B 1
OR . D 2 B 0 ,B 1 ,B 0
MVC . S 2 B 0 ,T S R ; Set GEE and XEN in TSR
B . S 2 N R P
NOP 5
ENDPROC( e n a b l e _ e x c e p t i o n )
;;
;; Special system calls
;; return address is in B3
;;
ENTRY( s y s _ r t _ s i g r e t u r n )
ADD . D 1 X S P ,8 ,A 4
# ifdef C O N F I G _ C 6 X _ B I G _ K E R N E L
| | MVKL . S 1 d o _ r t _ s i g r e t u r n ,A 0
MVKH . S 1 d o _ r t _ s i g r e t u r n ,A 0
BNOP . S 2 X A 0 ,5
# else
| | B . S 2 d o _ r t _ s i g r e t u r n
NOP 5
# endif
ENDPROC( s y s _ r t _ s i g r e t u r n )
ENTRY( s y s _ p r e a d _ c6 x )
MV . D 2 X A 8 ,B 7
# ifdef C O N F I G _ C 6 X _ B I G _ K E R N E L
| | MVKL . S 1 s y s _ p r e a d64 ,A 0
MVKH . S 1 s y s _ p r e a d64 ,A 0
BNOP . S 2 X A 0 ,5
# else
| | B . S 2 s y s _ p r e a d64
NOP 5
# endif
ENDPROC( s y s _ p r e a d _ c6 x )
ENTRY( s y s _ p w r i t e _ c6 x )
MV . D 2 X A 8 ,B 7
# ifdef C O N F I G _ C 6 X _ B I G _ K E R N E L
| | MVKL . S 1 s y s _ p w r i t e 6 4 ,A 0
MVKH . S 1 s y s _ p w r i t e 6 4 ,A 0
BNOP . S 2 X A 0 ,5
# else
| | B . S 2 s y s _ p w r i t e 6 4
NOP 5
# endif
ENDPROC( s y s _ p w r i t e _ c6 x )
;; On Entry
;; A4 - path
;; B4 - offset_lo (LE), offset_hi (BE)
;; A6 - offset_lo (BE), offset_hi (LE)
ENTRY( s y s _ t r u n c a t e 6 4 _ c6 x )
# ifdef C O N F I G _ C P U _ B I G _ E N D I A N
MV . S 2 B 4 ,B 5
MV . D 2 X A 6 ,B 4
# else
MV . D 2 X A 6 ,B 5
# endif
# ifdef C O N F I G _ C 6 X _ B I G _ K E R N E L
| | MVKL . S 1 s y s _ t r u n c a t e 6 4 ,A 0
MVKH . S 1 s y s _ t r u n c a t e 6 4 ,A 0
BNOP . S 2 X A 0 ,5
# else
| | B . S 2 s y s _ t r u n c a t e 6 4
NOP 5
# endif
ENDPROC( s y s _ t r u n c a t e 6 4 _ c6 x )
;; On Entry
;; A4 - fd
;; B4 - offset_lo (LE), offset_hi (BE)
;; A6 - offset_lo (BE), offset_hi (LE)
ENTRY( s y s _ f t r u n c a t e 6 4 _ c6 x )
# ifdef C O N F I G _ C P U _ B I G _ E N D I A N
MV . S 2 B 4 ,B 5
MV . D 2 X A 6 ,B 4
# else
MV . D 2 X A 6 ,B 5
# endif
# ifdef C O N F I G _ C 6 X _ B I G _ K E R N E L
| | MVKL . S 1 s y s _ f t r u n c a t e 6 4 ,A 0
MVKH . S 1 s y s _ f t r u n c a t e 6 4 ,A 0
BNOP . S 2 X A 0 ,5
# else
| | B . S 2 s y s _ f t r u n c a t e 6 4
NOP 5
# endif
ENDPROC( s y s _ f t r u n c a t e 6 4 _ c6 x )
;; On Entry
;; A4 - fd
;; B4 - offset_lo (LE), offset_hi (BE)
;; A6 - offset_lo (BE), offset_hi (LE)
;; B6 - len_lo (LE), len_hi (BE)
;; A8 - len_lo (BE), len_hi (LE)
;; B8 - advice
ENTRY( s y s _ f a d v i s e 6 4 _ 6 4 _ c6 x )
# ifdef C O N F I G _ C 6 X _ B I G _ K E R N E L
MVKL . S 1 s y s _ f a d v i s e 6 4 _ 6 4 ,A 0
MVKH . S 1 s y s _ f a d v i s e 6 4 _ 6 4 ,A 0
BNOP . S 2 X A 0 ,2
# else
B . S 2 s y s _ f a d v i s e 6 4 _ 6 4
NOP 2
# endif
# ifdef C O N F I G _ C P U _ B I G _ E N D I A N
MV . L 2 B 4 ,B 5
| | MV . D 2 X A 6 ,B 4
MV . L 1 A 8 ,A 6
| | MV . D 1 X B 6 ,A 7
# else
MV . D 2 X A 6 ,B 5
MV . L 1 A 8 ,A 7
| | MV . D 1 X B 6 ,A 6
# endif
MV . L 2 B 8 ,B 6
ENDPROC( s y s _ f a d v i s e 6 4 _ 6 4 _ c6 x )
;; On Entry
;; A4 - fd
;; B4 - mode
;; A6 - offset_hi
;; B6 - offset_lo
;; A8 - len_hi
;; B8 - len_lo
ENTRY( s y s _ f a l l o c a t e _ c6 x )
# ifdef C O N F I G _ C 6 X _ B I G _ K E R N E L
MVKL . S 1 s y s _ f a l l o c a t e ,A 0
MVKH . S 1 s y s _ f a l l o c a t e ,A 0
BNOP . S 2 X A 0 ,1
# else
B . S 2 s y s _ f a l l o c a t e
NOP
# endif
MV . D 1 A 6 ,A 7
MV . D 1 X B 6 ,A 6
MV . D 2 X A 8 ,B 7
MV . D 2 B 8 ,B 6
ENDPROC( s y s _ f a l l o c a t e _ c6 x )
;; put this in .neardata for faster access when using DSBT mode
.section .neardata , " aw" ,@progbits
.global current_ksp
.hidden current_ksp
current_ksp :
.word init_thread_union + THREAD_ S T A R T _ S P