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