• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "eu/co2_context.h"
17 #include "c/fiber.h"
18 
19 #include <errno.h>
20 #define API_ATTRIBUTE(attr) __attribute__(attr)
21 
22 void context_entry(void);
23 
24 #if defined(__aarch64__)
25 asm(".global context_entry; .type context_entry, %function; context_entry:\n"
26     "ldp x0, x1, [sp], #0x10\n"
27     "mov lr, xzr\n"
28     "br  x1\n"
29     ".size context_entry, . - context_entry\n"
30     ".global co2_save_context; .type co2_save_context, %function; co2_save_context:\n"
31     "stp x19, x20, [x0,#0]\n"
32     "stp x21, x22, [x0,#16]\n"
33     "stp x23, x24, [x0,#32]\n"
34     "stp x25, x26, [x0,#48]\n"
35     "stp x27, x28, [x0,#64]\n"
36     "stp x29, x30, [x0,#80]\n"
37     "mov x2, sp\n"
38     "str x2, [x0,#104]\n"
39     "stp  d8,  d9, [x0,#112]\n"
40     "stp d10, d11, [x0,#128]\n"
41     "stp d12, d13, [x0,#144]\n"
42     "stp d14, d15, [x0,#160]\n"
43     "mov x0, #0\n"
44     "ret\n"
45     ".size co2_save_context, . - co2_save_context\n"
46     ".global co2_restore_context; .type co2_restore_context, %function; co2_restore_context:\n"
47     "ldp x19, x20, [x0,#0]\n"
48     "ldp x21, x22, [x0,#16]\n"
49     "ldp x23, x24, [x0,#32]\n"
50     "ldp x25, x26, [x0,#48]\n"
51     "ldp x27, x28, [x0,#64]\n"
52     "ldp x29, x30, [x0,#80]\n"
53     "ldr x2, [x0,#104]\n"
54     "mov sp, x2\n"
55     "ldp  d8,  d9, [x0,#112]\n"
56     "ldp d10, d11, [x0,#128]\n"
57     "ldp d12, d13, [x0,#144]\n"
58     "ldp d14, d15, [x0,#160]\n"
59     "mov x0, #1\n"
60     "ret\n"
61     ".size co2_restore_context, . - co2_restore_context\n");
62 #elif defined(__arm__)
63 asm(".global context_entry; .type context_entry, %function; context_entry:\n"
64     "pop {r0, r1}\n"
65     "mov lr, #0\n"
66     "bx  r1\n"
67     ".size context_entry, . - context_entry\n"
68     ".global co2_save_context; .type co2_save_context, %function; co2_save_context:\n"
69     "mov ip, r0\n"
70     "str sp, [ip], #4\n"
71     "str lr, [ip], #4\n"
72     "stmia ip!, {v1-v6, sl, fp}\n"
73     ".fpu vfp\n"
74     "vstmia ip!, {d8-d15}\n"
75     "mov r0, #0\n"
76     "bx lr\n"
77     ".size co2_save_context, . - co2_save_context\n"
78     ".global co2_restore_context; .type co2_restore_context, %function; co2_restore_context:\n"
79     "mov ip, r0\n"
80     "ldr a4, [ip], #4\n"
81     "ldr r4, [ip], #4\n"
82     "mov sp, a4\n"
83     "mov lr, r4\n"
84     "ldmia ip!, {v1-v6, sl, fp}\n"
85     ".fpu vfp\n"
86     "vldmia ip!, {d8-d15}\n"
87     "mov r0, #1\n"
88     "bx lr\n"
89     ".size co2_restore_context, . - co2_restore_context\n");
90 #elif (defined(__x86_64__) && !defined _MSC_VER)
91 asm(".global context_entry; .type context_entry, %function; context_entry:\n"
92     "pop %rdi\n"
93     "jmp *(%rsp)\n"
94     ".size context_entry, . - context_entry\n"
95     ".global co2_save_context; .type co2_save_context, %function; co2_save_context:\n"
96     "mov %rbx, (%rdi)\n"
97     "mov %rbp, 8(%rdi)\n"
98     "mov %r12, 16(%rdi)\n"
99     "mov %r13, 24(%rdi)\n"
100     "mov %r14, 32(%rdi)\n"
101     "mov %r15, 40(%rdi)\n"
102     "lea 8(%rsp), %rdx\n"
103     "mov %rdx, 48(%rdi)\n"
104     "mov (%rsp), %rdx\n"
105     "mov %rdx, 56(%rdi)\n"
106     "xor %rax, %rax\n"
107     "ret\n"
108     ".size co2_save_context, . - co2_save_context\n"
109     ".global co2_restore_context; .type co2_restore_context, %function; co2_restore_context:\n"
110     "xor %rax, %rax\n"
111     "inc %rax\n"
112     "mov (%rdi), %rbx\n"
113     "mov 8(%rdi), %rbp\n"
114     "mov 16(%rdi), %r12\n"
115     "mov 24(%rdi), %r13\n"
116     "mov 32(%rdi), %r14\n"
117     "mov 40(%rdi), %r15\n"
118     "mov 48(%rdi), %rdx\n"
119     "mov %rdx, %rsp\n"
120     "jmp *56(%rdi)\n"
121     ".size co2_restore_context, . - co2_restore_context\n");
122 #elif defined(__riscv) && __riscv_xlen == 64
123 asm(".global context_entry; .type context_entry, %function; context_entry:\n"
124     "ld a0, 0(sp)\n"
125     "ld a1, 8(sp)\n"
126     "jalr a1\n"
127     ".size context_entry, . - context_entry\n"
128 #ifndef __riscv_float_abi_soft
129     ".attribute arch,\"rv64gc\" // LLVM Bug: https://github.com/llvm/llvm-project/issues/61991\n"
130 #endif
131     ".global co2_save_context; .type co2_save_context, %function; co2_save_context:\n"
132     "sd ra,    0(a0)\n"
133     "sd s0,    8(a0)\n"
134     "sd s1,    16(a0)\n"
135     "sd s2,    24(a0)\n"
136     "sd s3,    32(a0)\n"
137     "sd s4,    40(a0)\n"
138     "sd s5,    48(a0)\n"
139     "sd s6,    56(a0)\n"
140     "sd s7,    64(a0)\n"
141     "sd s8,    72(a0)\n"
142     "sd s9,    80(a0)\n"
143     "sd s10,   88(a0)\n"
144     "sd s11,   96(a0)\n"
145     "sd sp,    104(a0)\n"
146 #ifndef __riscv_float_abi_soft
147     "fsd fs0,  112(a0)\n"
148     "fsd fs1,  120(a0)\n"
149     "fsd fs2,  128(a0)\n"
150     "fsd fs3,  136(a0)\n"
151     "fsd fs4,  144(a0)\n"
152     "fsd fs5,  152(a0)\n"
153     "fsd fs6,  160(a0)\n"
154     "fsd fs7,  168(a0)\n"
155     "fsd fs8,  176(a0)\n"
156     "fsd fs9,  184(a0)\n"
157     "fsd fs10, 192(a0)\n"
158     "fsd fs11, 200(a0)\n"
159 #endif
160     "li a0, 0\n"
161     "ret\n"
162     ".size co2_save_context, . - co2_save_context\n"
163     ".global co2_restore_context; .type co2_restore_context, %function; co2_restore_context:\n"
164     "ld ra,    0(a0)\n"
165     "ld s0,    8(a0)\n"
166     "ld s1,    16(a0)\n"
167     "ld s2,    24(a0)\n"
168     "ld s3,    32(a0)\n"
169     "ld s4,    40(a0)\n"
170     "ld s5,    48(a0)\n"
171     "ld s6,    56(a0)\n"
172     "ld s7,    64(a0)\n"
173     "ld s8,    72(a0)\n"
174     "ld s9,    80(a0)\n"
175     "ld s10,   88(a0)\n"
176     "ld s11,   96(a0)\n"
177     "ld sp,    104(a0)\n"
178 #ifndef __riscv_float_abi_soft
179     "fld fs0,  112(a0)\n"
180     "fld fs1,  120(a0)\n"
181     "fld fs2,  128(a0)\n"
182     "fld fs3,  136(a0)\n"
183     "fld fs4,  144(a0)\n"
184     "fld fs5,  152(a0)\n"
185     "fld fs6,  160(a0)\n"
186     "fld fs7,  168(a0)\n"
187     "fld fs8,  176(a0)\n"
188     "fld fs9,  184(a0)\n"
189     "fld fs10, 192(a0)\n"
190     "fld fs11, 200(a0)\n"
191 #endif
192     "li a0, 1\n"
193     "ret\n"
194     ".size co2_restore_context, . - co2_restore_context\n");
195 #endif
196 
197 API_ATTRIBUTE((visibility("default")))
ffrt_fiber_init(ffrt_fiber_t * fiber,void (* func)(void *),void * arg,void * stack,size_t stack_size)198 int ffrt_fiber_init(ffrt_fiber_t* fiber, void(*func)(void*), void* arg, void* stack, size_t stack_size)
199 {
200     if (stack_size < 0x4 * sizeof(uintptr_t)) {
201         return EINVAL;
202     }
203 
204     uintptr_t stack_top = (uintptr_t)stack + stack_size - 0x2 * sizeof(uintptr_t);
205     stack_top -= stack_top % (0x2 * sizeof(uintptr_t));
206     uintptr_t* data = (uintptr_t*)stack_top;
207 
208     fiber->storage[FFRT_REG_LR] = (uintptr_t)context_entry;
209     fiber->storage[FFRT_REG_SP] = stack_top;
210 
211     data[0] = (uintptr_t)arg;
212     data[1] = (uintptr_t)func;
213     return 0;
214 }
215 
216 API_ATTRIBUTE((visibility("default")))
ffrt_fiber_switch(ffrt_fiber_t * from,ffrt_fiber_t * to)217 void ffrt_fiber_switch(ffrt_fiber_t* from, ffrt_fiber_t* to)
218 {
219     co2_switch_context(from, to);
220 }
221