1/* 2 * Copyright (c) 2023-2025 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 "runtime/fibers/arch/asm_macros.h" 17#include "runtime/fibers/arch/arm/context_layout.h" 18 19.extern abort 20 21LOCAL_FUNCTION_START(FiberExitBridge) 22 // indicate abnormal exit by calling exit(-1) 23 // because fibers should not return from FiberProc 24 // mov r0, #-1 25 // bl exit 26 27 // let's make the exit more violent than exit(-1) for now 28 // TODO(konstanting, #IAD5MH): revert to exit() when everything is tested and works 29 bl abort 30FUNCTION_END(FiberExitBridge) 31 32#define GPR_O(reg) FCTX_GPR_OFFSET_BYTES_ ## reg 33#define FP_O(reg) FCTX_FP_OFFSET_BYTES_ ## reg 34 35/** 36 * arguments: 37 * r0: uint8_t* ctx_memory 38 * r1: void (*func)(void*) 39 * r2: void* argument 40 * r3: uint8_t* stack 41 * [sp]: size_t stack_size_bytes 42 */ 43FUNCTION_START(UpdateContext) 44 // context->PC = func 45 str r1, [r0, # GPR_O(PC)] 46 // now we can reuse r1 47 // context->LR = FiberExitBridge (for the case when Fiber returns) 48 adr r1, FiberExitBridge 49 str r1, [r0, # GPR_O(LR)] 50 // context->R0 = argument 51 str r2, [r0, # GPR_O(R0)] 52 53 /** 54 * r1 will hold the new SP value: 55 * NEW_SP = align((stack + stack_size), 16B) 56 */ 57 58 // r1 = stack + stack_size_bytes 59 ldr r1, [sp] 60 add r1, r3, r1 61 // r1 = align(r1, 16B) 62 and r1, r1, #-16 63 // context->SP = r1 64 str r1, [r0, # GPR_O(SP)] 65 // context->FP = 0 66 mov r1, #0 67 str r1, [r0, # GPR_O(R11)] 68 69 // return success 70 mov r0, #0 71 blx lr 72FUNCTION_END(UpdateContext) 73 74/** 75 * arguments: 76 * r0: uint8_t* ctx_memory 77 * r1: void (*func)(void*) 78 * r2: void* argument 79 */ 80FUNCTION_START(UpdateContextKeepStack) 81 // r4 = context->PC 82 ldr r4, [r0, # GPR_O(PC)] 83 // context->PC = func 84 str r1, [r0, # GPR_O(PC)] 85 // context->R0 = argument 86 str r2, [r0, # GPR_O(R0)] 87 88 // pretend that we called the func(), i.e. put context's PC to LR 89 // context->LR = r4 90 str r4, [r0, # GPR_O(LR)] 91 92 // return success 93 mov r0, #0 94 blx lr 95FUNCTION_END(UpdateContextKeepStack) 96 97#undef GPR_O 98#undef FP_O 99 100// we don't need executable stack. 101.section .note.GNU-stack,"",%progbits