1/* SPDX-License-Identifier: GPL-2.0 2 * 3 * arch/sh/kernel/cpu/sh3/swsusp.S 4 * 5 * Copyright (C) 2009 Magnus Damm 6 */ 7#include <linux/sys.h> 8#include <linux/errno.h> 9#include <linux/linkage.h> 10#include <asm/asm-offsets.h> 11#include <asm/page.h> 12 13#define k0 r0 14#define k1 r1 15#define k2 r2 16#define k3 r3 17#define k4 r4 18 19! swsusp_arch_resume() 20! - copy restore_pblist pages 21! - restore registers from swsusp_arch_regs_cpu0 22 23ENTRY(swsusp_arch_resume) 24 mov.l 1f, r15 25 mov.l 2f, r4 26 mov.l @r4, r4 27 28swsusp_copy_loop: 29 mov r4, r0 30 cmp/eq #0, r0 31 bt swsusp_restore_regs 32 33 mov.l @(PBE_ADDRESS, r4), r2 34 mov.l @(PBE_ORIG_ADDRESS, r4), r5 35 36 mov #(PAGE_SIZE >> 10), r3 37 shll8 r3 38 shlr2 r3 /* PAGE_SIZE / 16 */ 39swsusp_copy_page: 40 dt r3 41 mov.l @r2+,r1 /* 16n+0 */ 42 mov.l r1,@r5 43 add #4,r5 44 mov.l @r2+,r1 /* 16n+4 */ 45 mov.l r1,@r5 46 add #4,r5 47 mov.l @r2+,r1 /* 16n+8 */ 48 mov.l r1,@r5 49 add #4,r5 50 mov.l @r2+,r1 /* 16n+12 */ 51 mov.l r1,@r5 52 bf/s swsusp_copy_page 53 add #4,r5 54 55 bra swsusp_copy_loop 56 mov.l @(PBE_NEXT, r4), r4 57 58swsusp_restore_regs: 59 ! BL=0: R7->R0 is bank0 60 mov.l 3f, r8 61 mov.l 4f, r5 62 jsr @r5 63 nop 64 65 ! BL=1: R7->R0 is bank1 66 lds k2, pr 67 ldc k3, ssr 68 69 mov.l @r15+, r0 70 mov.l @r15+, r1 71 mov.l @r15+, r2 72 mov.l @r15+, r3 73 mov.l @r15+, r4 74 mov.l @r15+, r5 75 mov.l @r15+, r6 76 mov.l @r15+, r7 77 78 rte 79 nop 80 ! BL=0: R7->R0 is bank0 81 82 .align 2 831: .long swsusp_arch_regs_cpu0 842: .long restore_pblist 853: .long 0x20000000 ! RB=1 864: .long restore_regs 87 88! swsusp_arch_suspend() 89! - prepare pc for resume, return from function without swsusp_save on resume 90! - save registers in swsusp_arch_regs_cpu0 91! - call swsusp_save write suspend image 92 93ENTRY(swsusp_arch_suspend) 94 sts pr, r0 ! save pr in r0 95 mov r15, r2 ! save sp in r2 96 mov r8, r5 ! save r8 in r5 97 stc sr, r1 98 ldc r1, ssr ! save sr in ssr 99 mov.l 1f, r1 100 ldc r1, spc ! setup pc value for resuming 101 mov.l 5f, r15 ! use swsusp_arch_regs_cpu0 as stack 102 mov.l 6f, r3 103 add r3, r15 ! save from top of structure 104 105 ! BL=0: R7->R0 is bank0 106 mov.l 2f, r3 ! get new SR value for bank1 107 mov #0, r4 108 mov.l 7f, r1 109 jsr @r1 ! switch to bank1 and save bank1 r7->r0 110 not r4, r4 111 112 ! BL=1: R7->R0 is bank1 113 stc r2_bank, k0 ! fetch old sp from r2_bank0 114 mov.l 3f, k4 ! SR bits to clear in k4 115 mov.l 8f, k1 116 jsr @k1 ! switch to bank0 and save all regs 117 stc r0_bank, k3 ! fetch old pr from r0_bank0 118 119 ! BL=0: R7->R0 is bank0 120 mov r2, r15 ! restore old sp 121 mov r5, r8 ! restore old r8 122 stc ssr, r1 123 ldc r1, sr ! restore old sr 124 lds r0, pr ! restore old pr 125 mov.l 4f, r0 126 jmp @r0 127 nop 128 129swsusp_call_save: 130 mov r2, r15 ! restore old sp 131 mov r5, r8 ! restore old r8 132 lds r0, pr ! restore old pr 133 rts 134 mov #0, r0 135 136 .align 2 1371: .long swsusp_call_save 1382: .long 0x20000000 ! RB=1 1393: .long 0xdfffffff ! RB=0 1404: .long swsusp_save 1415: .long swsusp_arch_regs_cpu0 1426: .long SWSUSP_ARCH_REGS_SIZE 1437: .long save_low_regs 1448: .long save_regs 145