/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2017 Andes Technology Corporation */ #include .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