summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/asm/mips/thread-mips32.c83
-rw-r--r--firmware/asm/mips/thread.h17
2 files changed, 47 insertions, 53 deletions
diff --git a/firmware/asm/mips/thread-mips32.c b/firmware/asm/mips/thread-mips32.c
index 3e38685f1b..b8e684bb80 100644
--- a/firmware/asm/mips/thread-mips32.c
+++ b/firmware/asm/mips/thread-mips32.c
@@ -26,23 +26,24 @@
26 *--------------------------------------------------------------------------- 26 *---------------------------------------------------------------------------
27 */ 27 */
28 28
29static void USED_ATTR start_thread(void *addr) 29void start_thread(void); /* Provide C access to ASM label */
30static void USED_ATTR _start_thread(void)
30{ 31{
32 /* t1 = context */
31 asm volatile ( 33 asm volatile (
34 "start_thread: \n"
32 ".set noreorder \n" 35 ".set noreorder \n"
33 ".set noat \n" 36 ".set noat \n"
34 "lw $25, 4(%0) \n" /* Fetch thread function pointer ($25 = t9) */ 37 "lw $8, 4($9) \n" /* Fetch thread function pointer ($8 = t0, $9 = t1) */
35 "lw $25, 40(%0) \n" /* Set initial sp(=$29) */ 38 "lw $29, 36($9) \n" /* Set initial sp(=$29) */
36 "jalr $25 \n" /* Start the thread */ 39 "jalr $8 \n" /* Start the thread */
37 "sw $0, 48(%0) \n" /* Clear start address */ 40 "sw $0, 44($9) \n" /* Clear start address */
38 ".set at \n" 41 ".set at \n"
39 ".set reorder \n" 42 ".set reorder \n"
40 : : "r" (addr) : "$25"
41 ); 43 );
42 thread_exit(); 44 thread_exit();
43} 45}
44 46
45
46/* Place context pointer in s0 slot, function pointer in s1 slot, and 47/* Place context pointer in s0 slot, function pointer in s1 slot, and
47 * start_thread pointer in context_start */ 48 * start_thread pointer in context_start */
48#define THREAD_STARTUP_INIT(core, thread, function) \ 49#define THREAD_STARTUP_INIT(core, thread, function) \
@@ -59,21 +60,25 @@ static inline void store_context(void* addr)
59 asm volatile ( 60 asm volatile (
60 ".set noreorder \n" 61 ".set noreorder \n"
61 ".set noat \n" 62 ".set noat \n"
62 "sw $16, 0(%0) \n" /* s0 */ 63 "move $8, %0 \n" /* Store addr in clobbered t0 othrewise
63 "sw $17, 4(%0) \n" /* s1 */ 64 * compiler could select %0 to be s0-s7
64 "sw $18, 8(%0) \n" /* s2 */ 65 * during inlining which would break
65 "sw $19, 12(%0) \n" /* s3 */ 66 * things horribly.
66 "sw $20, 16(%0) \n" /* s4 */ 67 */
67 "sw $21, 20(%0) \n" /* s5 */ 68 "sw $16, 0($8) \n" /* s0 */
68 "sw $22, 24(%0) \n" /* s6 */ 69 "sw $17, 4($8) \n" /* s1 */
69 "sw $23, 28(%0) \n" /* s7 */ 70 "sw $18, 8($8) \n" /* s2 */
70 "sw $28, 32(%0) \n" /* gp */ 71 "sw $19, 12($8) \n" /* s3 */
71 "sw $30, 36(%0) \n" /* fp */ 72 "sw $20, 16($8) \n" /* s4 */
72 "sw $29, 40(%0) \n" /* sp */ 73 "sw $21, 20($8) \n" /* s5 */
73 "sw $31, 44(%0) \n" /* ra */ 74 "sw $22, 24($8) \n" /* s6 */
75 "sw $23, 28($8) \n" /* s7 */
76 "sw $30, 32($8) \n" /* fp */
77 "sw $29, 36($8) \n" /* sp */
78 "sw $31, 40($8) \n" /* ra */
74 ".set at \n" 79 ".set at \n"
75 ".set reorder \n" 80 ".set reorder \n"
76 : : "r" (addr) 81 : : "r" (addr) : "t0"
77 ); 82 );
78} 83}
79 84
@@ -86,27 +91,31 @@ static inline void load_context(const void* addr)
86 asm volatile ( 91 asm volatile (
87 ".set noat \n" 92 ".set noat \n"
88 ".set noreorder \n" 93 ".set noreorder \n"
89 "lw $25, 48(%0) \n" /* Get start address (t9 = $25) */ 94 "lw $8, 44(%0) \n" /* Get start address ($8 = t0) */
90 "beqz $25, running \n" /* NULL -> already running */ 95 "beqz $8, running \n" /* NULL -> already running */
91 "nop \n" 96 "nop \n"
92 "jr $25 \n" 97 "jr $8 \n"
93 "move $4, %0 \n" /* a0 = context branch delay slot anyway */ 98 "move $9, %0 \n" /* t1 = context */
94 "running: \n" 99 "running: \n"
95 "lw $16, 0(%0) \n" /* s0 */ 100 "move $8, %0 \n" /* Store addr in clobbered t0 otherwise
96 "lw $17, 4(%0) \n" /* s1 */ 101 * compiler could select %0 to be s0-s7
97 "lw $18, 8(%0) \n" /* s2 */ 102 * during inlining which would break
98 "lw $19, 12(%0) \n" /* s3 */ 103 * things horribly.
99 "lw $20, 16(%0) \n" /* s4 */ 104 */
100 "lw $21, 20(%0) \n" /* s5 */ 105 "lw $16, 0($8) \n" /* s0 */
101 "lw $22, 24(%0) \n" /* s6 */ 106 "lw $17, 4($8) \n" /* s1 */
102 "lw $23, 28(%0) \n" /* s7 */ 107 "lw $18, 8($8) \n" /* s2 */
103 "lw $28, 32(%0) \n" /* gp */ 108 "lw $19, 12($8) \n" /* s3 */
104 "lw $30, 36(%0) \n" /* fp */ 109 "lw $20, 16($8) \n" /* s4 */
105 "lw $29, 40(%0) \n" /* sp */ 110 "lw $21, 20($8) \n" /* s5 */
106 "lw $31, 44(%0) \n" /* ra */ 111 "lw $22, 24($8) \n" /* s6 */
112 "lw $23, 28($8) \n" /* s7 */
113 "lw $30, 32($8) \n" /* fp */
114 "lw $29, 36($8) \n" /* sp */
115 "lw $31, 40($8) \n" /* ra */
107 ".set at \n" 116 ".set at \n"
108 ".set reorder \n" 117 ".set reorder \n"
109 : : "r" (addr) : "$25" 118 : : "r" (addr) : "t0", "t1"
110 ); 119 );
111} 120}
112 121
diff --git a/firmware/asm/mips/thread.h b/firmware/asm/mips/thread.h
index 42b0f7049f..ac37560a68 100644
--- a/firmware/asm/mips/thread.h
+++ b/firmware/asm/mips/thread.h
@@ -19,24 +19,9 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22/* index offset register
23 * 0 0 $16 s0
24 * 1 4 $17 s1
25 * 2 8 $18 s2
26 * 3 12 $19 s3
27 * 4 16 $20 s4
28 * 5 20 $21 s5
29 * 6 24 $22 s6
30 * 7 28 $23 s7
31 * 8 32 $28 gp
32 * 9 36 $30 s8 (s8)
33 * 10 40 $29 sp
34 * 11 44 $31 ra
35 * 12 48 start
36 */
37struct regs 22struct regs
38{ 23{
39 uint32_t r[10]; /* 0-32 - Registers s0-s7, gp, fp */ 24 uint32_t r[9]; /* 0-32 - Registers s0-s7, fp */
40 uint32_t sp; /* 36 - Stack pointer */ 25 uint32_t sp; /* 36 - Stack pointer */
41 uint32_t ra; /* 40 - Return address */ 26 uint32_t ra; /* 40 - Return address */
42 uint32_t start; /* 44 - Thread start address, or NULL when started */ 27 uint32_t start; /* 44 - Thread start address, or NULL when started */