swsusp.S 2.9 KB

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