forked from Minki/linux
e46bf83c18
This patch set contains basic components for supporting the nds32 FPU, such as exception handlers and context switch for FPU registers. By default, the lazy FPU scheme is supported and the user can configure it via CONFIG_LZAY_FPU. Signed-off-by: Vincent Chen <vincentc@andestech.com> Acked-by: Greentime Hu <greentime@andestech.com> Signed-off-by: Greentime Hu <greentime@andestech.com>
132 lines
2.2 KiB
ArmAsm
132 lines
2.2 KiB
ArmAsm
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/* Copyright (C) 2017 Andes Technology Corporation */
|
|
|
|
#include <asm/memory.h>
|
|
|
|
.data
|
|
.global sp_tmp
|
|
sp_tmp:
|
|
.long
|
|
|
|
.text
|
|
.globl suspend2ram
|
|
.globl cpu_resume
|
|
|
|
suspend2ram:
|
|
pushm $r0, $r31
|
|
#if defined(CONFIG_HWZOL)
|
|
mfusr $r0, $lc
|
|
mfusr $r1, $le
|
|
mfusr $r2, $lb
|
|
#endif
|
|
mfsr $r3, $mr0
|
|
mfsr $r4, $mr1
|
|
mfsr $r5, $mr4
|
|
mfsr $r6, $mr6
|
|
mfsr $r7, $mr7
|
|
mfsr $r8, $mr8
|
|
mfsr $r9, $ir0
|
|
mfsr $r10, $ir1
|
|
mfsr $r11, $ir2
|
|
mfsr $r12, $ir3
|
|
mfsr $r13, $ir9
|
|
mfsr $r14, $ir10
|
|
mfsr $r15, $ir12
|
|
mfsr $r16, $ir13
|
|
mfsr $r17, $ir14
|
|
mfsr $r18, $ir15
|
|
pushm $r0, $r19
|
|
#if defined(CONFIG_FPU)
|
|
jal store_fpu_for_suspend
|
|
#endif
|
|
tlbop FlushAll
|
|
isb
|
|
|
|
// transfer $sp from va to pa
|
|
sethi $r0, hi20(PAGE_OFFSET)
|
|
ori $r0, $r0, lo12(PAGE_OFFSET)
|
|
movi $r2, PHYS_OFFSET
|
|
sub $r1, $sp, $r0
|
|
add $r2, $r1, $r2
|
|
|
|
// store pa($sp) to sp_tmp
|
|
sethi $r1, hi20(sp_tmp)
|
|
swi $r2, [$r1 + lo12(sp_tmp)]
|
|
|
|
pushm $r16, $r25
|
|
pushm $r29, $r30
|
|
#ifdef CONFIG_CACHE_L2
|
|
jal dcache_wb_all_level
|
|
#else
|
|
jal cpu_dcache_wb_all
|
|
#endif
|
|
popm $r29, $r30
|
|
popm $r16, $r25
|
|
|
|
// get wake_mask and loop in standby
|
|
la $r1, wake_mask
|
|
lwi $r1, [$r1]
|
|
self_loop:
|
|
standby wake_grant
|
|
mfsr $r2, $ir15
|
|
and $r2, $r1, $r2
|
|
beqz $r2, self_loop
|
|
|
|
// set ipc to resume address
|
|
la $r1, resume_addr
|
|
lwi $r1, [$r1]
|
|
mtsr $r1, $ipc
|
|
isb
|
|
|
|
// reset psw, turn off the address translation
|
|
li $r2, 0x7000a
|
|
mtsr $r2, $ipsw
|
|
isb
|
|
|
|
iret
|
|
cpu_resume:
|
|
// translate the address of sp_tmp variable to pa
|
|
la $r1, sp_tmp
|
|
sethi $r0, hi20(PAGE_OFFSET)
|
|
ori $r0, $r0, lo12(PAGE_OFFSET)
|
|
movi $r2, PHYS_OFFSET
|
|
sub $r1, $r1, $r0
|
|
add $r1, $r1, $r2
|
|
|
|
// access the sp_tmp to get stack pointer
|
|
lwi $sp, [$r1]
|
|
|
|
popm $r0, $r19
|
|
#if defined(CONFIG_HWZOL)
|
|
mtusr $r0, $lb
|
|
mtusr $r1, $lc
|
|
mtusr $r2, $le
|
|
#endif
|
|
mtsr $r3, $mr0
|
|
mtsr $r4, $mr1
|
|
mtsr $r5, $mr4
|
|
mtsr $r6, $mr6
|
|
mtsr $r7, $mr7
|
|
mtsr $r8, $mr8
|
|
// set original psw to ipsw
|
|
mtsr $r9, $ir1
|
|
|
|
mtsr $r11, $ir2
|
|
mtsr $r12, $ir3
|
|
|
|
// set ipc to RR
|
|
la $r13, RR
|
|
mtsr $r13, $ir9
|
|
|
|
mtsr $r14, $ir10
|
|
mtsr $r15, $ir12
|
|
mtsr $r16, $ir13
|
|
mtsr $r17, $ir14
|
|
mtsr $r18, $ir15
|
|
popm $r0, $r31
|
|
|
|
isb
|
|
iret
|
|
RR:
|
|
ret
|