/* 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 |