diff options
-rw-r--r-- | firmware/asm/mips/thread-mips32.c | 83 | ||||
-rw-r--r-- | firmware/asm/mips/thread.h | 17 |
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 | ||
29 | static void USED_ATTR start_thread(void *addr) | 29 | void start_thread(void); /* Provide C access to ASM label */ |
30 | static 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 | */ | ||
37 | struct regs | 22 | struct 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 */ |