diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/openrisc/kernel/entry.S | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'arch/openrisc/kernel/entry.S')
-rw-r--r-- | arch/openrisc/kernel/entry.S | 79 |
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 | |||
906 | 1: | ||
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 | |||
929 | ENTRY(_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 | ||
1074 | ENTRY(__sys_clone) | 1079 | ENTRY(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 | ||
1080 | ENTRY(__sys_fork) | 1085 | ENTRY(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 | ||
1091 | ENTRY(sys_execve) | ||
1092 | l.j _sys_execve | ||
1093 | l.addi r6,r1,0 | ||
1094 | |||
1086 | ENTRY(sys_sigaltstack) | 1095 | ENTRY(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) | |||
1108 | ENTRY(sys_or1k_atomic) | 1117 | ENTRY(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 |