diff options
Diffstat (limited to 'firmware/asm/mips')
-rw-r--r-- | firmware/asm/mips/thread-mips32.c | 71 | ||||
-rw-r--r-- | firmware/asm/mips/thread.h | 17 |
2 files changed, 52 insertions, 36 deletions
diff --git a/firmware/asm/mips/thread-mips32.c b/firmware/asm/mips/thread-mips32.c index e754df7e29..19efb6eea9 100644 --- a/firmware/asm/mips/thread-mips32.c +++ b/firmware/asm/mips/thread-mips32.c | |||
@@ -26,24 +26,23 @@ | |||
26 | *--------------------------------------------------------------------------- | 26 | *--------------------------------------------------------------------------- |
27 | */ | 27 | */ |
28 | 28 | ||
29 | void start_thread(void); /* Provide C access to ASM label */ | 29 | static void USED_ATTR start_thread(void *addr) |
30 | static void USED_ATTR _start_thread(void) | ||
31 | { | 30 | { |
32 | /* t1 = context */ | ||
33 | asm volatile ( | 31 | asm volatile ( |
34 | "start_thread: \n" | ||
35 | ".set noreorder \n" | 32 | ".set noreorder \n" |
36 | ".set noat \n" | 33 | ".set noat \n" |
37 | "lw $8, 4($9) \n" /* Fetch thread function pointer ($8 = t0, $9 = t1) */ | 34 | "lw $t9, 4(%0) \n" /* Fetch thread function pointer ($25 = t9) */ |
38 | "lw $29, 36($9) \n" /* Set initial sp(=$29) */ | 35 | "lw $sp, 40(%0) \n" /* Set initial sp(=$29) */ |
39 | "jalr $8 \n" /* Start the thread */ | 36 | "jalr $t9 \n" /* Start the thread */ |
40 | "sw $0, 44($9) \n" /* Clear start address */ | 37 | "sw $zero, 48(%0) \n" /* Clear start address */ |
41 | ".set at \n" | 38 | ".set at \n" |
42 | ".set reorder \n" | 39 | ".set reorder \n" |
40 | : : "r" (addr) : "t9" | ||
43 | ); | 41 | ); |
44 | thread_exit(); | 42 | thread_exit(); |
45 | } | 43 | } |
46 | 44 | ||
45 | |||
47 | /* Place context pointer in s0 slot, function pointer in s1 slot, and | 46 | /* Place context pointer in s0 slot, function pointer in s1 slot, and |
48 | * start_thread pointer in context_start */ | 47 | * start_thread pointer in context_start */ |
49 | #define THREAD_STARTUP_INIT(core, thread, function) \ | 48 | #define THREAD_STARTUP_INIT(core, thread, function) \ |
@@ -60,17 +59,18 @@ static inline void store_context(void* addr) | |||
60 | asm volatile ( | 59 | asm volatile ( |
61 | ".set noreorder \n" | 60 | ".set noreorder \n" |
62 | ".set noat \n" | 61 | ".set noat \n" |
63 | "sw $16, 0(%0) \n" /* s0 */ | 62 | "sw $s0, 0(%0) \n" /* s0 */ |
64 | "sw $17, 4(%0) \n" /* s1 */ | 63 | "sw $s1, 4(%0) \n" /* s1 */ |
65 | "sw $18, 8(%0) \n" /* s2 */ | 64 | "sw $s2, 8(%0) \n" /* s2 */ |
66 | "sw $19, 12(%0) \n" /* s3 */ | 65 | "sw $s3, 12(%0) \n" /* s3 */ |
67 | "sw $20, 16(%0) \n" /* s4 */ | 66 | "sw $s4, 16(%0) \n" /* s4 */ |
68 | "sw $21, 20(%0) \n" /* s5 */ | 67 | "sw $s5, 20(%0) \n" /* s5 */ |
69 | "sw $22, 24(%0) \n" /* s6 */ | 68 | "sw $s6, 24(%0) \n" /* s6 */ |
70 | "sw $23, 28(%0) \n" /* s7 */ | 69 | "sw $s7, 28(%0) \n" /* s7 */ |
71 | "sw $30, 32(%0) \n" /* fp */ | 70 | "sw $gp, 32(%0) \n" /* gp */ |
72 | "sw $29, 36(%0) \n" /* sp */ | 71 | "sw $fp, 36(%0) \n" /* fp */ |
73 | "sw $31, 40(%0) \n" /* ra */ | 72 | "sw $sp, 40(%0) \n" /* sp */ |
73 | "sw $ra, 44(%0) \n" /* ra */ | ||
74 | ".set at \n" | 74 | ".set at \n" |
75 | ".set reorder \n" | 75 | ".set reorder \n" |
76 | : : "r" (addr) | 76 | : : "r" (addr) |
@@ -86,26 +86,27 @@ static inline void load_context(const void* addr) | |||
86 | asm volatile ( | 86 | asm volatile ( |
87 | ".set noat \n" | 87 | ".set noat \n" |
88 | ".set noreorder \n" | 88 | ".set noreorder \n" |
89 | "lw $8, 44(%0) \n" /* Get start address ($8 = t0) */ | 89 | "lw $t9, 48(%0) \n" /* Get start address ($8 = t0) */ |
90 | "beqz $8, running \n" /* NULL -> already running */ | 90 | "beqz $t9, running \n" /* NULL -> already running */ |
91 | "nop \n" | 91 | "nop \n" |
92 | "jr $8 \n" | 92 | "jr $t9 \n" |
93 | "move $9, %0 \n" /* t1 = context */ | 93 | "move $a0, %0 \n" /* a0 = context branch delay slot anyway */ |
94 | "running: \n" | 94 | "running: \n" |
95 | "lw $16, 0(%0) \n" /* s0 */ | 95 | "lw $s0, 0(%0) \n" /* s0 */ |
96 | "lw $17, 4(%0) \n" /* s1 */ | 96 | "lw $s1, 4(%0) \n" /* s1 */ |
97 | "lw $18, 8(%0) \n" /* s2 */ | 97 | "lw $s2, 8(%0) \n" /* s2 */ |
98 | "lw $19, 12(%0) \n" /* s3 */ | 98 | "lw $s3, 12(%0) \n" /* s3 */ |
99 | "lw $20, 16(%0) \n" /* s4 */ | 99 | "lw $s4, 16(%0) \n" /* s4 */ |
100 | "lw $21, 20(%0) \n" /* s5 */ | 100 | "lw $s5, 20(%0) \n" /* s5 */ |
101 | "lw $22, 24(%0) \n" /* s6 */ | 101 | "lw $s6, 24(%0) \n" /* s6 */ |
102 | "lw $23, 28(%0) \n" /* s7 */ | 102 | "lw $s7, 28(%0) \n" /* s7 */ |
103 | "lw $30, 32(%0) \n" /* fp */ | 103 | "lw $gp, 32(%0) \n" /* gp */ |
104 | "lw $29, 36(%0) \n" /* sp */ | 104 | "lw $fp, 36(%0) \n" /* fp */ |
105 | "lw $31, 40(%0) \n" /* ra */ | 105 | "lw $sp, 40(%0) \n" /* sp */ |
106 | "lw $ra, 44(%0) \n" /* ra */ | ||
106 | ".set at \n" | 107 | ".set at \n" |
107 | ".set reorder \n" | 108 | ".set reorder \n" |
108 | : : "r" (addr) : "t0", "t1" | 109 | : : "r" (addr) : "t9" |
109 | ); | 110 | ); |
110 | } | 111 | } |
111 | 112 | ||
diff --git a/firmware/asm/mips/thread.h b/firmware/asm/mips/thread.h index ac37560a68..42b0f7049f 100644 --- a/firmware/asm/mips/thread.h +++ b/firmware/asm/mips/thread.h | |||
@@ -19,9 +19,24 @@ | |||
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 | */ | ||
22 | struct regs | 37 | struct regs |
23 | { | 38 | { |
24 | uint32_t r[9]; /* 0-32 - Registers s0-s7, fp */ | 39 | uint32_t r[10]; /* 0-32 - Registers s0-s7, gp, fp */ |
25 | uint32_t sp; /* 36 - Stack pointer */ | 40 | uint32_t sp; /* 36 - Stack pointer */ |
26 | uint32_t ra; /* 40 - Return address */ | 41 | uint32_t ra; /* 40 - Return address */ |
27 | uint32_t start; /* 44 - Thread start address, or NULL when started */ | 42 | uint32_t start; /* 44 - Thread start address, or NULL when started */ |