summaryrefslogtreecommitdiff
path: root/firmware/thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/thread.c')
-rw-r--r--firmware/thread.c75
1 files changed, 36 insertions, 39 deletions
diff --git a/firmware/thread.c b/firmware/thread.c
index 453fbf510a..6efe8252e7 100644
--- a/firmware/thread.c
+++ b/firmware/thread.c
@@ -937,23 +937,23 @@ static inline void core_sleep(void)
937void start_thread(void); /* Provide C access to ASM label */ 937void start_thread(void); /* Provide C access to ASM label */
938static void __attribute__((used)) _start_thread(void) 938static void __attribute__((used)) _start_thread(void)
939{ 939{
940 /* $t1 = context */ 940 /* t1 = context */
941 asm volatile ( 941 asm volatile (
942 "start_thread: \n" 942 "start_thread: \n"
943 ".set noreorder \n" 943 ".set noreorder \n"
944 ".set noat \n" 944 ".set noat \n"
945 "lw $8, 4($9) \n" /* Fetch thread function pointer ($8 = $t0, $9 = $t1) */ 945 "lw $8, 4($9) \n" /* Fetch thread function pointer ($8 = t0, $9 = t1) */
946 "lw $29, 40($9) \n" /* Set initial sp(=$29) */ 946 "lw $29, 40($9) \n" /* Set initial sp(=$29) */
947 "jalr $8 \n" /* Start the thread */
947 "sw $0, 48($9) \n" /* Clear start address */ 948 "sw $0, 48($9) \n" /* Clear start address */
948 "jr $8 \n" /* Start the thread */
949 "nop \n"
950 ".set at \n" 949 ".set at \n"
951 ".set reorder \n" 950 ".set reorder \n"
951 ::: "t0"
952 ); 952 );
953 thread_exit(); 953 thread_exit();
954} 954}
955 955
956/* Place context pointer in $s0 slot, function pointer in $s1 slot, and 956/* Place context pointer in s0 slot, function pointer in s1 slot, and
957 * start_thread pointer in context_start */ 957 * start_thread pointer in context_start */
958#define THREAD_STARTUP_INIT(core, thread, function) \ 958#define THREAD_STARTUP_INIT(core, thread, function) \
959 ({ (thread)->context.r[0] = (uint32_t)&(thread)->context, \ 959 ({ (thread)->context.r[0] = (uint32_t)&(thread)->context, \
@@ -969,22 +969,21 @@ static inline void store_context(void* addr)
969 asm volatile ( 969 asm volatile (
970 ".set noreorder \n" 970 ".set noreorder \n"
971 ".set noat \n" 971 ".set noat \n"
972 "move $8, %0 \n" 972 "sw $16, 0(%0) \n" /* s0 */
973 "sw $16, 0($8) \n" /* $s0 */ 973 "sw $17, 4(%0) \n" /* s1 */
974 "sw $17, 4($8) \n" /* $s1 */ 974 "sw $18, 8(%0) \n" /* s2 */
975 "sw $18, 8($8) \n" /* $s2 */ 975 "sw $19, 12(%0) \n" /* s3 */
976 "sw $19, 12($8) \n" /* $s3 */ 976 "sw $20, 16(%0) \n" /* s4 */
977 "sw $20, 16($8) \n" /* $s4 */ 977 "sw $21, 20(%0) \n" /* s5 */
978 "sw $21, 20($8) \n" /* $s5 */ 978 "sw $22, 24(%0) \n" /* s6 */
979 "sw $22, 24($8) \n" /* $s6 */ 979 "sw $23, 28(%0) \n" /* s7 */
980 "sw $23, 28($8) \n" /* $s7 */ 980 "sw $28, 32(%0) \n" /* gp */
981 "sw $28, 32($8) \n" /* gp */ 981 "sw $30, 36(%0) \n" /* fp */
982 "sw $30, 36($8) \n" /* fp */ 982 "sw $29, 40(%0) \n" /* sp */
983 "sw $29, 40($8) \n" /* sp */ 983 "sw $31, 44(%0) \n" /* ra */
984 "sw $31, 44($8) \n" /* ra */
985 ".set at \n" 984 ".set at \n"
986 ".set reorder \n" 985 ".set reorder \n"
987 : : "r" (addr) : "t0" 986 : : "r" (addr)
988 ); 987 );
989} 988}
990 989
@@ -997,29 +996,27 @@ static inline void load_context(const void* addr)
997 asm volatile ( 996 asm volatile (
998 ".set noat \n" 997 ".set noat \n"
999 ".set noreorder \n" 998 ".set noreorder \n"
1000 "lw $8, 48(%0) \n" /* Get start address ($8 = $t0) */ 999 "lw $8, 48(%0) \n" /* Get start address ($8 = t0) */
1001 "beqz $8, running \n" /* NULL -> already running */ 1000 "beqz $8, running \n" /* NULL -> already running */
1002 "nop \n" 1001 "nop \n"
1003 "move $9, %0 \n" /* $t1 = context */
1004 "jr $8 \n" 1002 "jr $8 \n"
1005 "nop \n" 1003 "move $9, %0 \n" /* t1 = context */
1006 "running: \n" 1004 "running: \n"
1007 "move $8, %0 \n" 1005 "lw $16, 0(%0) \n" /* s0 */
1008 "lw $16, 0($8) \n" /* $s0 */ 1006 "lw $17, 4(%0) \n" /* s1 */
1009 "lw $17, 4($8) \n" /* $s1 */ 1007 "lw $18, 8(%0) \n" /* s2 */
1010 "lw $18, 8($8) \n" /* $s2 */ 1008 "lw $19, 12(%0) \n" /* s3 */
1011 "lw $19, 12($8) \n" /* $s3 */ 1009 "lw $20, 16(%0) \n" /* s4 */
1012 "lw $20, 16($8) \n" /* $s4 */ 1010 "lw $21, 20(%0) \n" /* s5 */
1013 "lw $21, 20($8) \n" /* $s5 */ 1011 "lw $22, 24(%0) \n" /* s6 */
1014 "lw $22, 24($8) \n" /* $s6 */ 1012 "lw $23, 28(%0) \n" /* s7 */
1015 "lw $23, 28($8) \n" /* $s7 */ 1013 "lw $28, 32(%0) \n" /* gp */
1016 "lw $28, 32($8) \n" /* gp */ 1014 "lw $30, 36(%0) \n" /* fp */
1017 "lw $30, 36($8) \n" /* fp */ 1015 "lw $29, 40(%0) \n" /* sp */
1018 "lw $29, 40($8) \n" /* sp */ 1016 "lw $31, 44(%0) \n" /* ra */
1019 "lw $31, 44($8) \n" /* ra */
1020 ".set at \n" 1017 ".set at \n"
1021 ".set reorder \n" 1018 ".set reorder \n"
1022 : : "r" (addr) : "t0" /* only! */ 1019 : : "r" (addr) : "t0", "t1"
1023 ); 1020 );
1024} 1021}
1025 1022
@@ -1033,9 +1030,9 @@ static inline void core_sleep(void)
1033 __cpm_idle_mode(); 1030 __cpm_idle_mode();
1034#endif 1031#endif
1035 asm volatile(".set mips32r2 \n" 1032 asm volatile(".set mips32r2 \n"
1036 "mfc0 $8, $12 \n" /* mfc $t0, $12 */ 1033 "mfc0 $8, $12 \n" /* mfc t0, $12 */
1037 "move $9, $8 \n" /* move $t1, $t0 */ 1034 "move $9, $8 \n" /* move t1, t0 */
1038 "la $10, 0x8000000 \n" /* la $t2, 0x8000000 */ 1035 "la $10, 0x8000000 \n" /* la t2, 0x8000000 */
1039 "or $8, $8, $10 \n" /* Enable reduced power mode */ 1036 "or $8, $8, $10 \n" /* Enable reduced power mode */
1040 "mtc0 $8, $12 \n" 1037 "mtc0 $8, $12 \n"
1041 "wait \n" 1038 "wait \n"