2026-01-21 18:59:54 +08:00

125 lines
2.5 KiB
ArmAsm

/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
#include <asm/page.h>
#include <asm/regdef.h>
.text
.set noat
ENTRY(swsusp_arch_suspend)
ldi $16, hibernate_state
ldi $1, PSTATE_REGS($16)
stl $9, CALLEE_R9($1)
stl $10, CALLEE_R10($1)
stl $11, CALLEE_R11($1)
stl $12, CALLEE_R12($1)
stl $13, CALLEE_R13($1)
stl $14, CALLEE_R14($1)
stl $15, CALLEE_R15($1)
stl $26, CALLEE_RA($1)
/* SIMD-FP */
ldi $1, PSTATE_FPREGS($16)
vstd $f2, CALLEE_F2($1)
vstd $f3, CALLEE_F3($1)
vstd $f4, CALLEE_F4($1)
vstd $f5, CALLEE_F5($1)
vstd $f6, CALLEE_F6($1)
vstd $f7, CALLEE_F7($1)
vstd $f8, CALLEE_F8($1)
vstd $f9, CALLEE_F9($1)
rfpcr $f0
fstd $f0, PSTATE_FPCR($16)
ldi $1, PSTATE_PCB($16)
stl sp, PCB_KSP($1)
call swsusp_save
ldi $16, hibernate_state
ldi $1, PSTATE_REGS($16)
ldl $26, CALLEE_RA($1)
/* save current_thread_info()->pcbb */
ret
END(swsusp_arch_suspend)
ENTRY(restore_image)
/* prepare to copy image data to their original locations */
ldi t0, restore_pblist
ldl t0, 0(t0)
$loop:
beq t0, $done
/* get addresses from the pbe and copy the page */
ldl t1, PBE_ADDR(t0) /* source */
ldl t2, PBE_ORIG_ADDR(t0) /* destination */
ldi t3, PAGE_SIZE
addl t1, t3, t3
$cpyloop:
ldl t8, 0(t1)
stl t8, 0(t2)
addl t1, 8, t1
addl t2, 8, t2
cmpeq t1, t3, t4
beq t4, $cpyloop
/* progress to the next pbe */
ldl t0, PBE_NEXT(t0)
bne t0, $loop
$done:
/* tell the hibernation core that we've just restored the memory */
ldi $0, in_suspend
stl $31, 0($0)
ldi $16, hibernate_state
ldi $1, PSTATE_REGS($16)
ldl $9, CALLEE_R9($1)
ldl $10, CALLEE_R10($1)
ldl $11, CALLEE_R11($1)
ldl $12, CALLEE_R12($1)
ldl $13, CALLEE_R13($1)
ldl $14, CALLEE_R14($1)
ldl $15, CALLEE_R15($1)
ldl $26, CALLEE_RA($1)
/* SIMD-FP */
fldd $f0, PSTATE_FPCR($16)
wfpcr $f0
fimovd $f0, $2
and $2, 0x3, $2
beq $2, $hibernate_setfpec_0
subl $2, 0x1, $2
beq $2, $hibernate_setfpec_1
subl $2, 0x1, $2
beq $2, $hibernate_setfpec_2
setfpec3
br $hibernate_setfpec_over
$hibernate_setfpec_0:
setfpec0
br $hibernate_setfpec_over
$hibernate_setfpec_1:
setfpec1
br $hibernate_setfpec_over
$hibernate_setfpec_2:
setfpec2
$hibernate_setfpec_over:
ldi $1, PSTATE_FPREGS($16)
vldd $f2, CALLEE_F2($1)
vldd $f3, CALLEE_F3($1)
vldd $f4, CALLEE_F4($1)
vldd $f5, CALLEE_F5($1)
vldd $f6, CALLEE_F6($1)
vldd $f7, CALLEE_F7($1)
vldd $f8, CALLEE_F8($1)
vldd $f9, CALLEE_F9($1)
ldi $1, PSTATE_PCB($16)
ldl sp, PCB_KSP($1)
ldi $8, 0x3fff
bic sp, $8, $8
ldi $0, 0($31)
ret
END(restore_image)