forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
2.2 KiB
131 lines
2.2 KiB
/* 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
|
|
|