18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * arch/arm/kernel/crunch-bits.S 48c2ecf20Sopenharmony_ci * Cirrus MaverickCrunch context switching and handling 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Shamelessly stolen from the iWMMXt code by Nicolas Pitre, which is 98c2ecf20Sopenharmony_ci * Copyright (c) 2003-2004, MontaVista Software, Inc. 108c2ecf20Sopenharmony_ci */ 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <linux/linkage.h> 138c2ecf20Sopenharmony_ci#include <asm/ptrace.h> 148c2ecf20Sopenharmony_ci#include <asm/thread_info.h> 158c2ecf20Sopenharmony_ci#include <asm/asm-offsets.h> 168c2ecf20Sopenharmony_ci#include <asm/assembler.h> 178c2ecf20Sopenharmony_ci#include <mach/ep93xx-regs.h> 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci/* 208c2ecf20Sopenharmony_ci * We can't use hex constants here due to a bug in gas. 218c2ecf20Sopenharmony_ci */ 228c2ecf20Sopenharmony_ci#define CRUNCH_MVDX0 0 238c2ecf20Sopenharmony_ci#define CRUNCH_MVDX1 8 248c2ecf20Sopenharmony_ci#define CRUNCH_MVDX2 16 258c2ecf20Sopenharmony_ci#define CRUNCH_MVDX3 24 268c2ecf20Sopenharmony_ci#define CRUNCH_MVDX4 32 278c2ecf20Sopenharmony_ci#define CRUNCH_MVDX5 40 288c2ecf20Sopenharmony_ci#define CRUNCH_MVDX6 48 298c2ecf20Sopenharmony_ci#define CRUNCH_MVDX7 56 308c2ecf20Sopenharmony_ci#define CRUNCH_MVDX8 64 318c2ecf20Sopenharmony_ci#define CRUNCH_MVDX9 72 328c2ecf20Sopenharmony_ci#define CRUNCH_MVDX10 80 338c2ecf20Sopenharmony_ci#define CRUNCH_MVDX11 88 348c2ecf20Sopenharmony_ci#define CRUNCH_MVDX12 96 358c2ecf20Sopenharmony_ci#define CRUNCH_MVDX13 104 368c2ecf20Sopenharmony_ci#define CRUNCH_MVDX14 112 378c2ecf20Sopenharmony_ci#define CRUNCH_MVDX15 120 388c2ecf20Sopenharmony_ci#define CRUNCH_MVAX0L 128 398c2ecf20Sopenharmony_ci#define CRUNCH_MVAX0M 132 408c2ecf20Sopenharmony_ci#define CRUNCH_MVAX0H 136 418c2ecf20Sopenharmony_ci#define CRUNCH_MVAX1L 140 428c2ecf20Sopenharmony_ci#define CRUNCH_MVAX1M 144 438c2ecf20Sopenharmony_ci#define CRUNCH_MVAX1H 148 448c2ecf20Sopenharmony_ci#define CRUNCH_MVAX2L 152 458c2ecf20Sopenharmony_ci#define CRUNCH_MVAX2M 156 468c2ecf20Sopenharmony_ci#define CRUNCH_MVAX2H 160 478c2ecf20Sopenharmony_ci#define CRUNCH_MVAX3L 164 488c2ecf20Sopenharmony_ci#define CRUNCH_MVAX3M 168 498c2ecf20Sopenharmony_ci#define CRUNCH_MVAX3H 172 508c2ecf20Sopenharmony_ci#define CRUNCH_DSPSC 176 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci#define CRUNCH_SIZE 184 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci .text 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci/* 578c2ecf20Sopenharmony_ci * Lazy switching of crunch coprocessor context 588c2ecf20Sopenharmony_ci * 598c2ecf20Sopenharmony_ci * r10 = struct thread_info pointer 608c2ecf20Sopenharmony_ci * r9 = ret_from_exception 618c2ecf20Sopenharmony_ci * lr = undefined instr exit 628c2ecf20Sopenharmony_ci * 638c2ecf20Sopenharmony_ci * called from prefetch exception handler with interrupts enabled 648c2ecf20Sopenharmony_ci */ 658c2ecf20Sopenharmony_ciENTRY(crunch_task_enable) 668c2ecf20Sopenharmony_ci inc_preempt_count r10, r3 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci ldr r8, =(EP93XX_APB_VIRT_BASE + 0x00130000) @ syscon addr 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci ldr r1, [r8, #0x80] 718c2ecf20Sopenharmony_ci tst r1, #0x00800000 @ access to crunch enabled? 728c2ecf20Sopenharmony_ci bne 2f @ if so no business here 738c2ecf20Sopenharmony_ci mov r3, #0xaa @ unlock syscon swlock 748c2ecf20Sopenharmony_ci str r3, [r8, #0xc0] 758c2ecf20Sopenharmony_ci orr r1, r1, #0x00800000 @ enable access to crunch 768c2ecf20Sopenharmony_ci str r1, [r8, #0x80] 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci ldr r3, =crunch_owner 798c2ecf20Sopenharmony_ci add r0, r10, #TI_CRUNCH_STATE @ get task crunch save area 808c2ecf20Sopenharmony_ci ldr r2, [sp, #60] @ current task pc value 818c2ecf20Sopenharmony_ci ldr r1, [r3] @ get current crunch owner 828c2ecf20Sopenharmony_ci str r0, [r3] @ this task now owns crunch 838c2ecf20Sopenharmony_ci sub r2, r2, #4 @ adjust pc back 848c2ecf20Sopenharmony_ci str r2, [sp, #60] 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci ldr r2, [r8, #0x80] 878c2ecf20Sopenharmony_ci mov r2, r2 @ flush out enable (@@@) 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci teq r1, #0 @ test for last ownership 908c2ecf20Sopenharmony_ci mov lr, r9 @ normal exit from exception 918c2ecf20Sopenharmony_ci beq crunch_load @ no owner, skip save 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cicrunch_save: 948c2ecf20Sopenharmony_ci cfstr64 mvdx0, [r1, #CRUNCH_MVDX0] @ save 64b registers 958c2ecf20Sopenharmony_ci cfstr64 mvdx1, [r1, #CRUNCH_MVDX1] 968c2ecf20Sopenharmony_ci cfstr64 mvdx2, [r1, #CRUNCH_MVDX2] 978c2ecf20Sopenharmony_ci cfstr64 mvdx3, [r1, #CRUNCH_MVDX3] 988c2ecf20Sopenharmony_ci cfstr64 mvdx4, [r1, #CRUNCH_MVDX4] 998c2ecf20Sopenharmony_ci cfstr64 mvdx5, [r1, #CRUNCH_MVDX5] 1008c2ecf20Sopenharmony_ci cfstr64 mvdx6, [r1, #CRUNCH_MVDX6] 1018c2ecf20Sopenharmony_ci cfstr64 mvdx7, [r1, #CRUNCH_MVDX7] 1028c2ecf20Sopenharmony_ci cfstr64 mvdx8, [r1, #CRUNCH_MVDX8] 1038c2ecf20Sopenharmony_ci cfstr64 mvdx9, [r1, #CRUNCH_MVDX9] 1048c2ecf20Sopenharmony_ci cfstr64 mvdx10, [r1, #CRUNCH_MVDX10] 1058c2ecf20Sopenharmony_ci cfstr64 mvdx11, [r1, #CRUNCH_MVDX11] 1068c2ecf20Sopenharmony_ci cfstr64 mvdx12, [r1, #CRUNCH_MVDX12] 1078c2ecf20Sopenharmony_ci cfstr64 mvdx13, [r1, #CRUNCH_MVDX13] 1088c2ecf20Sopenharmony_ci cfstr64 mvdx14, [r1, #CRUNCH_MVDX14] 1098c2ecf20Sopenharmony_ci cfstr64 mvdx15, [r1, #CRUNCH_MVDX15] 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci#ifdef __ARMEB__ 1128c2ecf20Sopenharmony_ci#error fix me for ARMEB 1138c2ecf20Sopenharmony_ci#endif 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci cfmv32al mvfx0, mvax0 @ save 72b accumulators 1168c2ecf20Sopenharmony_ci cfstr32 mvfx0, [r1, #CRUNCH_MVAX0L] 1178c2ecf20Sopenharmony_ci cfmv32am mvfx0, mvax0 1188c2ecf20Sopenharmony_ci cfstr32 mvfx0, [r1, #CRUNCH_MVAX0M] 1198c2ecf20Sopenharmony_ci cfmv32ah mvfx0, mvax0 1208c2ecf20Sopenharmony_ci cfstr32 mvfx0, [r1, #CRUNCH_MVAX0H] 1218c2ecf20Sopenharmony_ci cfmv32al mvfx0, mvax1 1228c2ecf20Sopenharmony_ci cfstr32 mvfx0, [r1, #CRUNCH_MVAX1L] 1238c2ecf20Sopenharmony_ci cfmv32am mvfx0, mvax1 1248c2ecf20Sopenharmony_ci cfstr32 mvfx0, [r1, #CRUNCH_MVAX1M] 1258c2ecf20Sopenharmony_ci cfmv32ah mvfx0, mvax1 1268c2ecf20Sopenharmony_ci cfstr32 mvfx0, [r1, #CRUNCH_MVAX1H] 1278c2ecf20Sopenharmony_ci cfmv32al mvfx0, mvax2 1288c2ecf20Sopenharmony_ci cfstr32 mvfx0, [r1, #CRUNCH_MVAX2L] 1298c2ecf20Sopenharmony_ci cfmv32am mvfx0, mvax2 1308c2ecf20Sopenharmony_ci cfstr32 mvfx0, [r1, #CRUNCH_MVAX2M] 1318c2ecf20Sopenharmony_ci cfmv32ah mvfx0, mvax2 1328c2ecf20Sopenharmony_ci cfstr32 mvfx0, [r1, #CRUNCH_MVAX2H] 1338c2ecf20Sopenharmony_ci cfmv32al mvfx0, mvax3 1348c2ecf20Sopenharmony_ci cfstr32 mvfx0, [r1, #CRUNCH_MVAX3L] 1358c2ecf20Sopenharmony_ci cfmv32am mvfx0, mvax3 1368c2ecf20Sopenharmony_ci cfstr32 mvfx0, [r1, #CRUNCH_MVAX3M] 1378c2ecf20Sopenharmony_ci cfmv32ah mvfx0, mvax3 1388c2ecf20Sopenharmony_ci cfstr32 mvfx0, [r1, #CRUNCH_MVAX3H] 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci cfmv32sc mvdx0, dspsc @ save status word 1418c2ecf20Sopenharmony_ci cfstr64 mvdx0, [r1, #CRUNCH_DSPSC] 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci teq r0, #0 @ anything to load? 1448c2ecf20Sopenharmony_ci cfldr64eq mvdx0, [r1, #CRUNCH_MVDX0] @ mvdx0 was clobbered 1458c2ecf20Sopenharmony_ci beq 1f 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_cicrunch_load: 1488c2ecf20Sopenharmony_ci cfldr64 mvdx0, [r0, #CRUNCH_DSPSC] @ load status word 1498c2ecf20Sopenharmony_ci cfmvsc32 dspsc, mvdx0 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci cfldr32 mvfx0, [r0, #CRUNCH_MVAX0L] @ load 72b accumulators 1528c2ecf20Sopenharmony_ci cfmval32 mvax0, mvfx0 1538c2ecf20Sopenharmony_ci cfldr32 mvfx0, [r0, #CRUNCH_MVAX0M] 1548c2ecf20Sopenharmony_ci cfmvam32 mvax0, mvfx0 1558c2ecf20Sopenharmony_ci cfldr32 mvfx0, [r0, #CRUNCH_MVAX0H] 1568c2ecf20Sopenharmony_ci cfmvah32 mvax0, mvfx0 1578c2ecf20Sopenharmony_ci cfldr32 mvfx0, [r0, #CRUNCH_MVAX1L] 1588c2ecf20Sopenharmony_ci cfmval32 mvax1, mvfx0 1598c2ecf20Sopenharmony_ci cfldr32 mvfx0, [r0, #CRUNCH_MVAX1M] 1608c2ecf20Sopenharmony_ci cfmvam32 mvax1, mvfx0 1618c2ecf20Sopenharmony_ci cfldr32 mvfx0, [r0, #CRUNCH_MVAX1H] 1628c2ecf20Sopenharmony_ci cfmvah32 mvax1, mvfx0 1638c2ecf20Sopenharmony_ci cfldr32 mvfx0, [r0, #CRUNCH_MVAX2L] 1648c2ecf20Sopenharmony_ci cfmval32 mvax2, mvfx0 1658c2ecf20Sopenharmony_ci cfldr32 mvfx0, [r0, #CRUNCH_MVAX2M] 1668c2ecf20Sopenharmony_ci cfmvam32 mvax2, mvfx0 1678c2ecf20Sopenharmony_ci cfldr32 mvfx0, [r0, #CRUNCH_MVAX2H] 1688c2ecf20Sopenharmony_ci cfmvah32 mvax2, mvfx0 1698c2ecf20Sopenharmony_ci cfldr32 mvfx0, [r0, #CRUNCH_MVAX3L] 1708c2ecf20Sopenharmony_ci cfmval32 mvax3, mvfx0 1718c2ecf20Sopenharmony_ci cfldr32 mvfx0, [r0, #CRUNCH_MVAX3M] 1728c2ecf20Sopenharmony_ci cfmvam32 mvax3, mvfx0 1738c2ecf20Sopenharmony_ci cfldr32 mvfx0, [r0, #CRUNCH_MVAX3H] 1748c2ecf20Sopenharmony_ci cfmvah32 mvax3, mvfx0 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci cfldr64 mvdx0, [r0, #CRUNCH_MVDX0] @ load 64b registers 1778c2ecf20Sopenharmony_ci cfldr64 mvdx1, [r0, #CRUNCH_MVDX1] 1788c2ecf20Sopenharmony_ci cfldr64 mvdx2, [r0, #CRUNCH_MVDX2] 1798c2ecf20Sopenharmony_ci cfldr64 mvdx3, [r0, #CRUNCH_MVDX3] 1808c2ecf20Sopenharmony_ci cfldr64 mvdx4, [r0, #CRUNCH_MVDX4] 1818c2ecf20Sopenharmony_ci cfldr64 mvdx5, [r0, #CRUNCH_MVDX5] 1828c2ecf20Sopenharmony_ci cfldr64 mvdx6, [r0, #CRUNCH_MVDX6] 1838c2ecf20Sopenharmony_ci cfldr64 mvdx7, [r0, #CRUNCH_MVDX7] 1848c2ecf20Sopenharmony_ci cfldr64 mvdx8, [r0, #CRUNCH_MVDX8] 1858c2ecf20Sopenharmony_ci cfldr64 mvdx9, [r0, #CRUNCH_MVDX9] 1868c2ecf20Sopenharmony_ci cfldr64 mvdx10, [r0, #CRUNCH_MVDX10] 1878c2ecf20Sopenharmony_ci cfldr64 mvdx11, [r0, #CRUNCH_MVDX11] 1888c2ecf20Sopenharmony_ci cfldr64 mvdx12, [r0, #CRUNCH_MVDX12] 1898c2ecf20Sopenharmony_ci cfldr64 mvdx13, [r0, #CRUNCH_MVDX13] 1908c2ecf20Sopenharmony_ci cfldr64 mvdx14, [r0, #CRUNCH_MVDX14] 1918c2ecf20Sopenharmony_ci cfldr64 mvdx15, [r0, #CRUNCH_MVDX15] 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci1: 1948c2ecf20Sopenharmony_ci#ifdef CONFIG_PREEMPT_COUNT 1958c2ecf20Sopenharmony_ci get_thread_info r10 1968c2ecf20Sopenharmony_ci#endif 1978c2ecf20Sopenharmony_ci2: dec_preempt_count r10, r3 1988c2ecf20Sopenharmony_ci ret lr 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci/* 2018c2ecf20Sopenharmony_ci * Back up crunch regs to save area and disable access to them 2028c2ecf20Sopenharmony_ci * (mainly for gdb or sleep mode usage) 2038c2ecf20Sopenharmony_ci * 2048c2ecf20Sopenharmony_ci * r0 = struct thread_info pointer of target task or NULL for any 2058c2ecf20Sopenharmony_ci */ 2068c2ecf20Sopenharmony_ciENTRY(crunch_task_disable) 2078c2ecf20Sopenharmony_ci stmfd sp!, {r4, r5, lr} 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci mrs ip, cpsr 2108c2ecf20Sopenharmony_ci orr r2, ip, #PSR_I_BIT @ disable interrupts 2118c2ecf20Sopenharmony_ci msr cpsr_c, r2 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci ldr r4, =(EP93XX_APB_VIRT_BASE + 0x00130000) @ syscon addr 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci ldr r3, =crunch_owner 2168c2ecf20Sopenharmony_ci add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area 2178c2ecf20Sopenharmony_ci ldr r1, [r3] @ get current crunch owner 2188c2ecf20Sopenharmony_ci teq r1, #0 @ any current owner? 2198c2ecf20Sopenharmony_ci beq 1f @ no: quit 2208c2ecf20Sopenharmony_ci teq r0, #0 @ any owner? 2218c2ecf20Sopenharmony_ci teqne r1, r2 @ or specified one? 2228c2ecf20Sopenharmony_ci bne 1f @ no: quit 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci ldr r5, [r4, #0x80] @ enable access to crunch 2258c2ecf20Sopenharmony_ci mov r2, #0xaa 2268c2ecf20Sopenharmony_ci str r2, [r4, #0xc0] 2278c2ecf20Sopenharmony_ci orr r5, r5, #0x00800000 2288c2ecf20Sopenharmony_ci str r5, [r4, #0x80] 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci mov r0, #0 @ nothing to load 2318c2ecf20Sopenharmony_ci str r0, [r3] @ no more current owner 2328c2ecf20Sopenharmony_ci ldr r2, [r4, #0x80] @ flush out enable (@@@) 2338c2ecf20Sopenharmony_ci mov r2, r2 2348c2ecf20Sopenharmony_ci bl crunch_save 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci mov r2, #0xaa @ disable access to crunch 2378c2ecf20Sopenharmony_ci str r2, [r4, #0xc0] 2388c2ecf20Sopenharmony_ci bic r5, r5, #0x00800000 2398c2ecf20Sopenharmony_ci str r5, [r4, #0x80] 2408c2ecf20Sopenharmony_ci ldr r5, [r4, #0x80] @ flush out enable (@@@) 2418c2ecf20Sopenharmony_ci mov r5, r5 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci1: msr cpsr_c, ip @ restore interrupt mode 2448c2ecf20Sopenharmony_ci ldmfd sp!, {r4, r5, pc} 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci/* 2478c2ecf20Sopenharmony_ci * Copy crunch state to given memory address 2488c2ecf20Sopenharmony_ci * 2498c2ecf20Sopenharmony_ci * r0 = struct thread_info pointer of target task 2508c2ecf20Sopenharmony_ci * r1 = memory address where to store crunch state 2518c2ecf20Sopenharmony_ci * 2528c2ecf20Sopenharmony_ci * this is called mainly in the creation of signal stack frames 2538c2ecf20Sopenharmony_ci */ 2548c2ecf20Sopenharmony_ciENTRY(crunch_task_copy) 2558c2ecf20Sopenharmony_ci mrs ip, cpsr 2568c2ecf20Sopenharmony_ci orr r2, ip, #PSR_I_BIT @ disable interrupts 2578c2ecf20Sopenharmony_ci msr cpsr_c, r2 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci ldr r3, =crunch_owner 2608c2ecf20Sopenharmony_ci add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area 2618c2ecf20Sopenharmony_ci ldr r3, [r3] @ get current crunch owner 2628c2ecf20Sopenharmony_ci teq r2, r3 @ does this task own it... 2638c2ecf20Sopenharmony_ci beq 1f 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci @ current crunch values are in the task save area 2668c2ecf20Sopenharmony_ci msr cpsr_c, ip @ restore interrupt mode 2678c2ecf20Sopenharmony_ci mov r0, r1 2688c2ecf20Sopenharmony_ci mov r1, r2 2698c2ecf20Sopenharmony_ci mov r2, #CRUNCH_SIZE 2708c2ecf20Sopenharmony_ci b memcpy 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci1: @ this task owns crunch regs -- grab a copy from there 2738c2ecf20Sopenharmony_ci mov r0, #0 @ nothing to load 2748c2ecf20Sopenharmony_ci mov r3, lr @ preserve return address 2758c2ecf20Sopenharmony_ci bl crunch_save 2768c2ecf20Sopenharmony_ci msr cpsr_c, ip @ restore interrupt mode 2778c2ecf20Sopenharmony_ci ret r3 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci/* 2808c2ecf20Sopenharmony_ci * Restore crunch state from given memory address 2818c2ecf20Sopenharmony_ci * 2828c2ecf20Sopenharmony_ci * r0 = struct thread_info pointer of target task 2838c2ecf20Sopenharmony_ci * r1 = memory address where to get crunch state from 2848c2ecf20Sopenharmony_ci * 2858c2ecf20Sopenharmony_ci * this is used to restore crunch state when unwinding a signal stack frame 2868c2ecf20Sopenharmony_ci */ 2878c2ecf20Sopenharmony_ciENTRY(crunch_task_restore) 2888c2ecf20Sopenharmony_ci mrs ip, cpsr 2898c2ecf20Sopenharmony_ci orr r2, ip, #PSR_I_BIT @ disable interrupts 2908c2ecf20Sopenharmony_ci msr cpsr_c, r2 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_ci ldr r3, =crunch_owner 2938c2ecf20Sopenharmony_ci add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area 2948c2ecf20Sopenharmony_ci ldr r3, [r3] @ get current crunch owner 2958c2ecf20Sopenharmony_ci teq r2, r3 @ does this task own it... 2968c2ecf20Sopenharmony_ci beq 1f 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci @ this task doesn't own crunch regs -- use its save area 2998c2ecf20Sopenharmony_ci msr cpsr_c, ip @ restore interrupt mode 3008c2ecf20Sopenharmony_ci mov r0, r2 3018c2ecf20Sopenharmony_ci mov r2, #CRUNCH_SIZE 3028c2ecf20Sopenharmony_ci b memcpy 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci1: @ this task owns crunch regs -- load them directly 3058c2ecf20Sopenharmony_ci mov r0, r1 3068c2ecf20Sopenharmony_ci mov r1, #0 @ nothing to save 3078c2ecf20Sopenharmony_ci mov r3, lr @ preserve return address 3088c2ecf20Sopenharmony_ci bl crunch_load 3098c2ecf20Sopenharmony_ci msr cpsr_c, ip @ restore interrupt mode 3108c2ecf20Sopenharmony_ci ret r3 311