linux/arch/nds32/kernel/sleep.S
Vincent Chen e46bf83c18 nds32: nds32 FPU port
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>
2018-11-22 18:13:13 +08:00

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