mirror of https://gitee.com/openkylin/linux.git
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
|