sleep.S 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. /*
  2. * This file contains sleep low-level functions for PowerBook G3.
  3. * Copyright (C) 1999 Benjamin Herrenschmidt (benh@kernel.crashing.org)
  4. * and Paul Mackerras (paulus@samba.org).
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the License, or (at your option) any later version.
  10. *
  11. */
  12. #include <asm/processor.h>
  13. #include <asm/page.h>
  14. #include <asm/ppc_asm.h>
  15. #include <asm/cputable.h>
  16. #include <asm/cache.h>
  17. #include <asm/thread_info.h>
  18. #include <asm/asm-offsets.h>
  19. #define MAGIC 0x4c617273 /* 'Lars' */
  20. /*
  21. * Structure for storing CPU registers on the stack.
  22. */
  23. #define SL_SP 0
  24. #define SL_PC 4
  25. #define SL_MSR 8
  26. #define SL_SDR1 0xc
  27. #define SL_SPRG0 0x10 /* 4 sprg's */
  28. #define SL_DBAT0 0x20
  29. #define SL_IBAT0 0x28
  30. #define SL_DBAT1 0x30
  31. #define SL_IBAT1 0x38
  32. #define SL_DBAT2 0x40
  33. #define SL_IBAT2 0x48
  34. #define SL_DBAT3 0x50
  35. #define SL_IBAT3 0x58
  36. #define SL_TB 0x60
  37. #define SL_R2 0x68
  38. #define SL_CR 0x6c
  39. #define SL_R12 0x70 /* r12 to r31 */
  40. #define SL_SIZE (SL_R12 + 80)
  41. .section .text
  42. .align 5
  43. #if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC)
  44. /* This gets called by via-pmu.c late during the sleep process.
  45. * The PMU was already send the sleep command and will shut us down
  46. * soon. We need to save all that is needed and setup the wakeup
  47. * vector that will be called by the ROM on wakeup
  48. */
  49. _GLOBAL(low_sleep_handler)
  50. #ifndef CONFIG_6xx
  51. blr
  52. #else
  53. mflr r0
  54. stw r0,4(r1)
  55. stwu r1,-SL_SIZE(r1)
  56. mfcr r0
  57. stw r0,SL_CR(r1)
  58. stw r2,SL_R2(r1)
  59. stmw r12,SL_R12(r1)
  60. /* Save MSR & SDR1 */
  61. mfmsr r4
  62. stw r4,SL_MSR(r1)
  63. mfsdr1 r4
  64. stw r4,SL_SDR1(r1)
  65. /* Get a stable timebase and save it */
  66. 1: mftbu r4
  67. stw r4,SL_TB(r1)
  68. mftb r5
  69. stw r5,SL_TB+4(r1)
  70. mftbu r3
  71. cmpw r3,r4
  72. bne 1b
  73. /* Save SPRGs */
  74. mfsprg r4,0
  75. stw r4,SL_SPRG0(r1)
  76. mfsprg r4,1
  77. stw r4,SL_SPRG0+4(r1)
  78. mfsprg r4,2
  79. stw r4,SL_SPRG0+8(r1)
  80. mfsprg r4,3
  81. stw r4,SL_SPRG0+12(r1)
  82. /* Save BATs */
  83. mfdbatu r4,0
  84. stw r4,SL_DBAT0(r1)
  85. mfdbatl r4,0
  86. stw r4,SL_DBAT0+4(r1)
  87. mfdbatu r4,1
  88. stw r4,SL_DBAT1(r1)
  89. mfdbatl r4,1
  90. stw r4,SL_DBAT1+4(r1)
  91. mfdbatu r4,2
  92. stw r4,SL_DBAT2(r1)
  93. mfdbatl r4,2
  94. stw r4,SL_DBAT2+4(r1)
  95. mfdbatu r4,3
  96. stw r4,SL_DBAT3(r1)
  97. mfdbatl r4,3
  98. stw r4,SL_DBAT3+4(r1)
  99. mfibatu r4,0
  100. stw r4,SL_IBAT0(r1)
  101. mfibatl r4,0
  102. stw r4,SL_IBAT0+4(r1)
  103. mfibatu r4,1
  104. stw r4,SL_IBAT1(r1)
  105. mfibatl r4,1
  106. stw r4,SL_IBAT1+4(r1)
  107. mfibatu r4,2
  108. stw r4,SL_IBAT2(r1)
  109. mfibatl r4,2
  110. stw r4,SL_IBAT2+4(r1)
  111. mfibatu r4,3
  112. stw r4,SL_IBAT3(r1)
  113. mfibatl r4,3
  114. stw r4,SL_IBAT3+4(r1)
  115. /* Backup various CPU config stuffs */
  116. bl __save_cpu_setup
  117. /* The ROM can wake us up via 2 different vectors:
  118. * - On wallstreet & lombard, we must write a magic
  119. * value 'Lars' at address 4 and a pointer to a
  120. * memory location containing the PC to resume from
  121. * at address 0.
  122. * - On Core99, we must store the wakeup vector at
  123. * address 0x80 and eventually it's parameters
  124. * at address 0x84. I've have some trouble with those
  125. * parameters however and I no longer use them.
  126. */
  127. lis r5,grackle_wake_up@ha
  128. addi r5,r5,grackle_wake_up@l
  129. tophys(r5,r5)
  130. stw r5,SL_PC(r1)
  131. lis r4,KERNELBASE@h
  132. tophys(r5,r1)
  133. addi r5,r5,SL_PC
  134. lis r6,MAGIC@ha
  135. addi r6,r6,MAGIC@l
  136. stw r5,0(r4)
  137. stw r6,4(r4)
  138. /* Setup stuffs at 0x80-0x84 for Core99 */
  139. lis r3,core99_wake_up@ha
  140. addi r3,r3,core99_wake_up@l
  141. tophys(r3,r3)
  142. stw r3,0x80(r4)
  143. stw r5,0x84(r4)
  144. /* Store a pointer to our backup storage into
  145. * a kernel global
  146. */
  147. lis r3,sleep_storage@ha
  148. addi r3,r3,sleep_storage@l
  149. stw r5,0(r3)
  150. .globl low_cpu_die
  151. low_cpu_die:
  152. /* Flush & disable all caches */
  153. bl flush_disable_caches
  154. /* Turn off data relocation. */
  155. mfmsr r3 /* Save MSR in r7 */
  156. rlwinm r3,r3,0,28,26 /* Turn off DR bit */
  157. sync
  158. mtmsr r3
  159. isync
  160. BEGIN_FTR_SECTION
  161. /* Flush any pending L2 data prefetches to work around HW bug */
  162. sync
  163. lis r3,0xfff0
  164. lwz r0,0(r3) /* perform cache-inhibited load to ROM */
  165. sync /* (caches are disabled at this point) */
  166. END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
  167. /*
  168. * Set the HID0 and MSR for sleep.
  169. */
  170. mfspr r2,SPRN_HID0
  171. rlwinm r2,r2,0,10,7 /* clear doze, nap */
  172. oris r2,r2,HID0_SLEEP@h
  173. sync
  174. isync
  175. mtspr SPRN_HID0,r2
  176. sync
  177. /* This loop puts us back to sleep in case we have a spurrious
  178. * wakeup so that the host bridge properly stays asleep. The
  179. * CPU will be turned off, either after a known time (about 1
  180. * second) on wallstreet & lombard, or as soon as the CPU enters
  181. * SLEEP mode on core99
  182. */
  183. mfmsr r2
  184. oris r2,r2,MSR_POW@h
  185. 1: sync
  186. mtmsr r2
  187. isync
  188. b 1b
  189. /*
  190. * Here is the resume code.
  191. */
  192. /*
  193. * Core99 machines resume here
  194. * r4 has the physical address of SL_PC(sp) (unused)
  195. */
  196. _GLOBAL(core99_wake_up)
  197. /* Make sure HID0 no longer contains any sleep bit and that data cache
  198. * is disabled
  199. */
  200. mfspr r3,SPRN_HID0
  201. rlwinm r3,r3,0,11,7 /* clear SLEEP, NAP, DOZE bits */
  202. rlwinm 3,r3,0,18,15 /* clear DCE, ICE */
  203. mtspr SPRN_HID0,r3
  204. sync
  205. isync
  206. /* sanitize MSR */
  207. mfmsr r3
  208. ori r3,r3,MSR_EE|MSR_IP
  209. xori r3,r3,MSR_EE|MSR_IP
  210. sync
  211. isync
  212. mtmsr r3
  213. sync
  214. isync
  215. /* Recover sleep storage */
  216. lis r3,sleep_storage@ha
  217. addi r3,r3,sleep_storage@l
  218. tophys(r3,r3)
  219. lwz r1,0(r3)
  220. /* Pass thru to older resume code ... */
  221. /*
  222. * Here is the resume code for older machines.
  223. * r1 has the physical address of SL_PC(sp).
  224. */
  225. grackle_wake_up:
  226. /* Restore the kernel's segment registers before
  227. * we do any r1 memory access as we are not sure they
  228. * are in a sane state above the first 256Mb region
  229. */
  230. li r0,16 /* load up segment register values */
  231. mtctr r0 /* for context 0 */
  232. lis r3,0x2000 /* Ku = 1, VSID = 0 */
  233. li r4,0
  234. 3: mtsrin r3,r4
  235. addi r3,r3,0x111 /* increment VSID */
  236. addis r4,r4,0x1000 /* address of next segment */
  237. bdnz 3b
  238. sync
  239. isync
  240. subi r1,r1,SL_PC
  241. /* Restore various CPU config stuffs */
  242. bl __restore_cpu_setup
  243. /* Make sure all FPRs have been initialized */
  244. bl reloc_offset
  245. bl __init_fpu_registers
  246. /* Invalidate & enable L1 cache, we don't care about
  247. * whatever the ROM may have tried to write to memory
  248. */
  249. bl __inval_enable_L1
  250. /* Restore the BATs, and SDR1. Then we can turn on the MMU. */
  251. lwz r4,SL_SDR1(r1)
  252. mtsdr1 r4
  253. lwz r4,SL_SPRG0(r1)
  254. mtsprg 0,r4
  255. lwz r4,SL_SPRG0+4(r1)
  256. mtsprg 1,r4
  257. lwz r4,SL_SPRG0+8(r1)
  258. mtsprg 2,r4
  259. lwz r4,SL_SPRG0+12(r1)
  260. mtsprg 3,r4
  261. lwz r4,SL_DBAT0(r1)
  262. mtdbatu 0,r4
  263. lwz r4,SL_DBAT0+4(r1)
  264. mtdbatl 0,r4
  265. lwz r4,SL_DBAT1(r1)
  266. mtdbatu 1,r4
  267. lwz r4,SL_DBAT1+4(r1)
  268. mtdbatl 1,r4
  269. lwz r4,SL_DBAT2(r1)
  270. mtdbatu 2,r4
  271. lwz r4,SL_DBAT2+4(r1)
  272. mtdbatl 2,r4
  273. lwz r4,SL_DBAT3(r1)
  274. mtdbatu 3,r4
  275. lwz r4,SL_DBAT3+4(r1)
  276. mtdbatl 3,r4
  277. lwz r4,SL_IBAT0(r1)
  278. mtibatu 0,r4
  279. lwz r4,SL_IBAT0+4(r1)
  280. mtibatl 0,r4
  281. lwz r4,SL_IBAT1(r1)
  282. mtibatu 1,r4
  283. lwz r4,SL_IBAT1+4(r1)
  284. mtibatl 1,r4
  285. lwz r4,SL_IBAT2(r1)
  286. mtibatu 2,r4
  287. lwz r4,SL_IBAT2+4(r1)
  288. mtibatl 2,r4
  289. lwz r4,SL_IBAT3(r1)
  290. mtibatu 3,r4
  291. lwz r4,SL_IBAT3+4(r1)
  292. mtibatl 3,r4
  293. BEGIN_FTR_SECTION
  294. li r4,0
  295. mtspr SPRN_DBAT4U,r4
  296. mtspr SPRN_DBAT4L,r4
  297. mtspr SPRN_DBAT5U,r4
  298. mtspr SPRN_DBAT5L,r4
  299. mtspr SPRN_DBAT6U,r4
  300. mtspr SPRN_DBAT6L,r4
  301. mtspr SPRN_DBAT7U,r4
  302. mtspr SPRN_DBAT7L,r4
  303. mtspr SPRN_IBAT4U,r4
  304. mtspr SPRN_IBAT4L,r4
  305. mtspr SPRN_IBAT5U,r4
  306. mtspr SPRN_IBAT5L,r4
  307. mtspr SPRN_IBAT6U,r4
  308. mtspr SPRN_IBAT6L,r4
  309. mtspr SPRN_IBAT7U,r4
  310. mtspr SPRN_IBAT7L,r4
  311. END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS)
  312. /* Flush all TLBs */
  313. lis r4,0x1000
  314. 1: addic. r4,r4,-0x1000
  315. tlbie r4
  316. blt 1b
  317. sync
  318. /* restore the MSR and turn on the MMU */
  319. lwz r3,SL_MSR(r1)
  320. bl turn_on_mmu
  321. /* get back the stack pointer */
  322. tovirt(r1,r1)
  323. /* Restore TB */
  324. li r3,0
  325. mttbl r3
  326. lwz r3,SL_TB(r1)
  327. lwz r4,SL_TB+4(r1)
  328. mttbu r3
  329. mttbl r4
  330. /* Restore the callee-saved registers and return */
  331. lwz r0,SL_CR(r1)
  332. mtcr r0
  333. lwz r2,SL_R2(r1)
  334. lmw r12,SL_R12(r1)
  335. addi r1,r1,SL_SIZE
  336. lwz r0,4(r1)
  337. mtlr r0
  338. blr
  339. turn_on_mmu:
  340. mflr r4
  341. tovirt(r4,r4)
  342. mtsrr0 r4
  343. mtsrr1 r3
  344. sync
  345. isync
  346. rfi
  347. #endif /* defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ) */
  348. .section .data
  349. .balign L1_CACHE_BYTES
  350. sleep_storage:
  351. .long 0
  352. .balign L1_CACHE_BYTES, 0
  353. #endif /* CONFIG_6xx */
  354. .section .text