Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | /* 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 |