aboutsummaryrefslogtreecommitdiffstats
path: root/arch/openrisc/kernel/entry.S
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/openrisc/kernel/entry.S
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'arch/openrisc/kernel/entry.S')
-rw-r--r--arch/openrisc/kernel/entry.S79
1 files changed, 44 insertions, 35 deletions
diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S
index 5e5b30601bb..d5f9c35a583 100644
--- a/arch/openrisc/kernel/entry.S
+++ b/arch/openrisc/kernel/entry.S
@@ -95,6 +95,7 @@ handler: ;\
95 /* r1, EPCR, ESR a already saved */ ;\ 95 /* r1, EPCR, ESR a already saved */ ;\
96 l.sw PT_GPR2(r1),r2 ;\ 96 l.sw PT_GPR2(r1),r2 ;\
97 l.sw PT_GPR3(r1),r3 ;\ 97 l.sw PT_GPR3(r1),r3 ;\
98 l.sw PT_ORIG_GPR11(r1),r11 ;\
98 /* r4 already save */ ;\ 99 /* r4 already save */ ;\
99 l.sw PT_GPR5(r1),r5 ;\ 100 l.sw PT_GPR5(r1),r5 ;\
100 l.sw PT_GPR6(r1),r6 ;\ 101 l.sw PT_GPR6(r1),r6 ;\
@@ -124,9 +125,7 @@ handler: ;\
124 /* r30 already save */ ;\ 125 /* r30 already save */ ;\
125/* l.sw PT_GPR30(r1),r30*/ ;\ 126/* l.sw PT_GPR30(r1),r30*/ ;\
126 l.sw PT_GPR31(r1),r31 ;\ 127 l.sw PT_GPR31(r1),r31 ;\
127 /* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\ 128 l.sw PT_SYSCALLNO(r1),r0
128 l.addi r30,r0,-1 ;\
129 l.sw PT_ORIG_GPR11(r1),r30
130 129
131#define UNHANDLED_EXCEPTION(handler,vector) \ 130#define UNHANDLED_EXCEPTION(handler,vector) \
132 .global handler ;\ 131 .global handler ;\
@@ -134,6 +133,7 @@ handler: ;\
134 /* r1, EPCR, ESR already saved */ ;\ 133 /* r1, EPCR, ESR already saved */ ;\
135 l.sw PT_GPR2(r1),r2 ;\ 134 l.sw PT_GPR2(r1),r2 ;\
136 l.sw PT_GPR3(r1),r3 ;\ 135 l.sw PT_GPR3(r1),r3 ;\
136 l.sw PT_ORIG_GPR11(r1),r11 ;\
137 l.sw PT_GPR5(r1),r5 ;\ 137 l.sw PT_GPR5(r1),r5 ;\
138 l.sw PT_GPR6(r1),r6 ;\ 138 l.sw PT_GPR6(r1),r6 ;\
139 l.sw PT_GPR7(r1),r7 ;\ 139 l.sw PT_GPR7(r1),r7 ;\
@@ -162,9 +162,7 @@ handler: ;\
162 /* r31 already saved */ ;\ 162 /* r31 already saved */ ;\
163 l.sw PT_GPR30(r1),r30 ;\ 163 l.sw PT_GPR30(r1),r30 ;\
164/* l.sw PT_GPR31(r1),r31 */ ;\ 164/* l.sw PT_GPR31(r1),r31 */ ;\
165 /* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\ 165 l.sw PT_SYSCALLNO(r1),r0 ;\
166 l.addi r30,r0,-1 ;\
167 l.sw PT_ORIG_GPR11(r1),r30 ;\
168 l.addi r3,r1,0 ;\ 166 l.addi r3,r1,0 ;\
169 /* r4 is exception EA */ ;\ 167 /* r4 is exception EA */ ;\
170 l.addi r5,r0,vector ;\ 168 l.addi r5,r0,vector ;\
@@ -556,7 +554,6 @@ ENTRY(_sys_call_handler)
556 l.sw PT_GPR9(r1),r9 554 l.sw PT_GPR9(r1),r9
557 /* r10 already saved */ 555 /* r10 already saved */
558 l.sw PT_GPR11(r1),r11 556 l.sw PT_GPR11(r1),r11
559 /* orig_gpr11 must be set for syscalls */
560 l.sw PT_ORIG_GPR11(r1),r11 557 l.sw PT_ORIG_GPR11(r1),r11
561 /* r12,r13 already saved */ 558 /* r12,r13 already saved */
562 559
@@ -570,6 +567,9 @@ ENTRY(_sys_call_handler)
570 /* r30 is the only register we clobber in the fast path */ 567 /* r30 is the only register we clobber in the fast path */
571 /* r30 already saved */ 568 /* r30 already saved */
572/* l.sw PT_GPR30(r1),r30 */ 569/* l.sw PT_GPR30(r1),r30 */
570 /* This is used by do_signal to determine whether to check for
571 * syscall restart or not */
572 l.sw PT_SYSCALLNO(r1),r11
573 573
574_syscall_check_trace_enter: 574_syscall_check_trace_enter:
575 /* If TIF_SYSCALL_TRACE is set, then we want to do syscall tracing */ 575 /* If TIF_SYSCALL_TRACE is set, then we want to do syscall tracing */
@@ -731,7 +731,7 @@ _syscall_trace_enter:
731 * so that we can do the syscall for real and return to the syscall 731 * so that we can do the syscall for real and return to the syscall
732 * hot path. 732 * hot path.
733 */ 733 */
734 l.lwz r11,PT_GPR11(r1) 734 l.lwz r11,PT_SYSCALLNO(r1)
735 l.lwz r3,PT_GPR3(r1) 735 l.lwz r3,PT_GPR3(r1)
736 l.lwz r4,PT_GPR4(r1) 736 l.lwz r4,PT_GPR4(r1)
737 l.lwz r5,PT_GPR5(r1) 737 l.lwz r5,PT_GPR5(r1)
@@ -894,16 +894,6 @@ ENTRY(ret_from_fork)
894 l.jal schedule_tail 894 l.jal schedule_tail
895 l.nop 895 l.nop
896 896
897 /* Check if we are a kernel thread */
898 l.sfeqi r20,0
899 l.bf 1f
900 l.nop
901
902 /* ...we are a kernel thread so invoke the requested callback */
903 l.jalr r20
904 l.or r3,r22,r0
905
9061:
907 /* _syscall_returns expect r11 to contain return value */ 897 /* _syscall_returns expect r11 to contain return value */
908 l.lwz r11,PT_GPR11(r1) 898 l.lwz r11,PT_GPR11(r1)
909 899
@@ -925,6 +915,26 @@ ENTRY(ret_from_fork)
925 l.j _syscall_return 915 l.j _syscall_return
926 l.nop 916 l.nop
927 917
918/* Since syscalls don't save call-clobbered registers, the args to
919 * kernel_thread_helper will need to be passed through callee-saved
920 * registers and copied to the parameter registers when the thread
921 * begins running.
922 *
923 * See arch/openrisc/kernel/process.c:
924 * The args are passed as follows:
925 * arg1 (r3) : passed in r20
926 * arg2 (r4) : passed in r22
927 */
928
929ENTRY(_kernel_thread_helper)
930 l.or r3,r20,r0
931 l.or r4,r22,r0
932 l.movhi r31,hi(kernel_thread_helper)
933 l.ori r31,r31,lo(kernel_thread_helper)
934 l.jr r31
935 l.nop
936
937
928/* ========================================================[ switch ] === */ 938/* ========================================================[ switch ] === */
929 939
930/* 940/*
@@ -1034,13 +1044,8 @@ ENTRY(_switch)
1034 /* Unwind stack to pre-switch state */ 1044 /* Unwind stack to pre-switch state */
1035 l.addi r1,r1,(INT_FRAME_SIZE) 1045 l.addi r1,r1,(INT_FRAME_SIZE)
1036 1046
1037 /* Return via the link-register back to where we 'came from', where 1047 /* Return via the link-register back to where we 'came from', where that can be
1038 * that may be either schedule(), ret_from_fork(), or 1048 * either schedule() or return_from_fork()... */
1039 * ret_from_kernel_thread(). If we are returning to a new thread,
1040 * we are expected to have set up the arg to schedule_tail already,
1041 * hence we do so here unconditionally:
1042 */
1043 l.lwz r3,TI_STACK(r3) /* Load 'prev' as schedule_tail arg */
1044 l.jr r9 1049 l.jr r9
1045 l.nop 1050 l.nop
1046 1051
@@ -1071,18 +1076,22 @@ _fork_save_extra_regs_and_call:
1071 l.jr r29 1076 l.jr r29
1072 l.sw PT_GPR28(r1),r28 1077 l.sw PT_GPR28(r1),r28
1073 1078
1074ENTRY(__sys_clone) 1079ENTRY(sys_clone)
1075 l.movhi r29,hi(sys_clone) 1080 l.movhi r29,hi(_sys_clone)
1076 l.ori r29,r29,lo(sys_clone) 1081 l.ori r29,r29,lo(_sys_clone)
1077 l.j _fork_save_extra_regs_and_call 1082 l.j _fork_save_extra_regs_and_call
1078 l.addi r7,r1,0 1083 l.addi r7,r1,0
1079 1084
1080ENTRY(__sys_fork) 1085ENTRY(sys_fork)
1081 l.movhi r29,hi(sys_fork) 1086 l.movhi r29,hi(_sys_fork)
1082 l.ori r29,r29,lo(sys_fork) 1087 l.ori r29,r29,lo(_sys_fork)
1083 l.j _fork_save_extra_regs_and_call 1088 l.j _fork_save_extra_regs_and_call
1084 l.addi r3,r1,0 1089 l.addi r3,r1,0
1085 1090
1091ENTRY(sys_execve)
1092 l.j _sys_execve
1093 l.addi r6,r1,0
1094
1086ENTRY(sys_sigaltstack) 1095ENTRY(sys_sigaltstack)
1087 l.j _sys_sigaltstack 1096 l.j _sys_sigaltstack
1088 l.addi r5,r1,0 1097 l.addi r5,r1,0
@@ -1108,10 +1117,10 @@ ENTRY(sys_rt_sigreturn)
1108ENTRY(sys_or1k_atomic) 1117ENTRY(sys_or1k_atomic)
1109 /* FIXME: This ignores r3 and always does an XCHG */ 1118 /* FIXME: This ignores r3 and always does an XCHG */
1110 DISABLE_INTERRUPTS(r17,r19) 1119 DISABLE_INTERRUPTS(r17,r19)
1111 l.lwz r29,0(r4) 1120 l.lwz r30,0(r4)
1112 l.lwz r27,0(r5) 1121 l.lwz r28,0(r5)
1113 l.sw 0(r4),r27 1122 l.sw 0(r4),r28
1114 l.sw 0(r5),r29 1123 l.sw 0(r5),r30
1115 ENABLE_INTERRUPTS(r17) 1124 ENABLE_INTERRUPTS(r17)
1116 l.jr r9 1125 l.jr r9
1117 l.or r11,r0,r0 1126 l.or r11,r0,r0