entry-avr32b.S 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. /*
  2. * Copyright (C) 2004-2006 Atmel Corporation
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. */
  8. /*
  9. * This file contains the low-level entry-points into the kernel, that is,
  10. * exception handlers, debug trap handlers, interrupt handlers and the
  11. * system call handler.
  12. */
  13. #include <linux/errno.h>
  14. #include <asm/asm.h>
  15. #include <asm/hardirq.h>
  16. #include <asm/irq.h>
  17. #include <asm/ocd.h>
  18. #include <asm/page.h>
  19. #include <asm/pgtable.h>
  20. #include <asm/ptrace.h>
  21. #include <asm/sysreg.h>
  22. #include <asm/thread_info.h>
  23. #include <asm/unistd.h>
  24. #ifdef CONFIG_PREEMPT
  25. # define preempt_stop mask_interrupts
  26. #else
  27. # define preempt_stop
  28. # define fault_resume_kernel fault_restore_all
  29. #endif
  30. #define __MASK(x) ((1 << (x)) - 1)
  31. #define IRQ_MASK ((__MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) | \
  32. (__MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT))
  33. .section .ex.text,"ax",@progbits
  34. .align 2
  35. exception_vectors:
  36. bral handle_critical
  37. .align 2
  38. bral handle_critical
  39. .align 2
  40. bral do_bus_error_write
  41. .align 2
  42. bral do_bus_error_read
  43. .align 2
  44. bral do_nmi_ll
  45. .align 2
  46. bral handle_address_fault
  47. .align 2
  48. bral handle_protection_fault
  49. .align 2
  50. bral handle_debug
  51. .align 2
  52. bral do_illegal_opcode_ll
  53. .align 2
  54. bral do_illegal_opcode_ll
  55. .align 2
  56. bral do_illegal_opcode_ll
  57. .align 2
  58. bral do_fpe_ll
  59. .align 2
  60. bral do_illegal_opcode_ll
  61. .align 2
  62. bral handle_address_fault
  63. .align 2
  64. bral handle_address_fault
  65. .align 2
  66. bral handle_protection_fault
  67. .align 2
  68. bral handle_protection_fault
  69. .align 2
  70. bral do_dtlb_modified
  71. /*
  72. * r0 : PGD/PT/PTE
  73. * r1 : Offending address
  74. * r2 : Scratch register
  75. * r3 : Cause (5, 12 or 13)
  76. */
  77. #define tlbmiss_save pushm r0-r3
  78. #define tlbmiss_restore popm r0-r3
  79. .section .tlbx.ex.text,"ax",@progbits
  80. .global itlb_miss
  81. itlb_miss:
  82. tlbmiss_save
  83. rjmp tlb_miss_common
  84. .section .tlbr.ex.text,"ax",@progbits
  85. dtlb_miss_read:
  86. tlbmiss_save
  87. rjmp tlb_miss_common
  88. .section .tlbw.ex.text,"ax",@progbits
  89. dtlb_miss_write:
  90. tlbmiss_save
  91. .global tlb_miss_common
  92. tlb_miss_common:
  93. mfsr r0, SYSREG_TLBEAR
  94. mfsr r1, SYSREG_PTBR
  95. /* Is it the vmalloc space? */
  96. bld r0, 31
  97. brcs handle_vmalloc_miss
  98. /* First level lookup */
  99. pgtbl_lookup:
  100. lsr r2, r0, PGDIR_SHIFT
  101. ld.w r3, r1[r2 << 2]
  102. bfextu r1, r0, PAGE_SHIFT, PGDIR_SHIFT - PAGE_SHIFT
  103. bld r3, _PAGE_BIT_PRESENT
  104. brcc page_table_not_present
  105. /* Translate to virtual address in P1. */
  106. andl r3, 0xf000
  107. sbr r3, 31
  108. /* Second level lookup */
  109. ld.w r2, r3[r1 << 2]
  110. mfsr r0, SYSREG_TLBARLO
  111. bld r2, _PAGE_BIT_PRESENT
  112. brcc page_not_present
  113. /* Mark the page as accessed */
  114. sbr r2, _PAGE_BIT_ACCESSED
  115. st.w r3[r1 << 2], r2
  116. /* Drop software flags */
  117. andl r2, _PAGE_FLAGS_HARDWARE_MASK & 0xffff
  118. mtsr SYSREG_TLBELO, r2
  119. /* Figure out which entry we want to replace */
  120. mfsr r1, SYSREG_MMUCR
  121. clz r2, r0
  122. brcc 1f
  123. mov r3, -1 /* All entries have been accessed, */
  124. mov r2, 0 /* so start at 0 */
  125. mtsr SYSREG_TLBARLO, r3 /* and reset TLBAR */
  126. 1: bfins r1, r2, SYSREG_DRP_OFFSET, SYSREG_DRP_SIZE
  127. mtsr SYSREG_MMUCR, r1
  128. tlbw
  129. tlbmiss_restore
  130. rete
  131. handle_vmalloc_miss:
  132. /* Simply do the lookup in init's page table */
  133. mov r1, lo(swapper_pg_dir)
  134. orh r1, hi(swapper_pg_dir)
  135. rjmp pgtbl_lookup
  136. /* --- System Call --- */
  137. .section .scall.text,"ax",@progbits
  138. system_call:
  139. #ifdef CONFIG_PREEMPT
  140. mask_interrupts
  141. #endif
  142. pushm r12 /* r12_orig */
  143. stmts --sp, r0-lr
  144. mfsr r0, SYSREG_RAR_SUP
  145. mfsr r1, SYSREG_RSR_SUP
  146. #ifdef CONFIG_PREEMPT
  147. unmask_interrupts
  148. #endif
  149. zero_fp
  150. stm --sp, r0-r1
  151. /* check for syscall tracing */
  152. get_thread_info r0
  153. ld.w r1, r0[TI_flags]
  154. bld r1, TIF_SYSCALL_TRACE
  155. brcs syscall_trace_enter
  156. syscall_trace_cont:
  157. cp.w r8, NR_syscalls
  158. brhs syscall_badsys
  159. lddpc lr, syscall_table_addr
  160. ld.w lr, lr[r8 << 2]
  161. mov r8, r5 /* 5th argument (6th is pushed by stub) */
  162. icall lr
  163. .global syscall_return
  164. syscall_return:
  165. get_thread_info r0
  166. mask_interrupts /* make sure we don't miss an interrupt
  167. setting need_resched or sigpending
  168. between sampling and the rets */
  169. /* Store the return value so that the correct value is loaded below */
  170. stdsp sp[REG_R12], r12
  171. ld.w r1, r0[TI_flags]
  172. andl r1, _TIF_ALLWORK_MASK, COH
  173. brne syscall_exit_work
  174. syscall_exit_cont:
  175. popm r8-r9
  176. mtsr SYSREG_RAR_SUP, r8
  177. mtsr SYSREG_RSR_SUP, r9
  178. ldmts sp++, r0-lr
  179. sub sp, -4 /* r12_orig */
  180. rets
  181. .align 2
  182. syscall_table_addr:
  183. .long sys_call_table
  184. syscall_badsys:
  185. mov r12, -ENOSYS
  186. rjmp syscall_return
  187. .global ret_from_fork
  188. ret_from_fork:
  189. rcall schedule_tail
  190. /* check for syscall tracing */
  191. get_thread_info r0
  192. ld.w r1, r0[TI_flags]
  193. andl r1, _TIF_ALLWORK_MASK, COH
  194. brne syscall_exit_work
  195. rjmp syscall_exit_cont
  196. syscall_trace_enter:
  197. pushm r8-r12
  198. rcall syscall_trace
  199. popm r8-r12
  200. rjmp syscall_trace_cont
  201. syscall_exit_work:
  202. bld r1, TIF_SYSCALL_TRACE
  203. brcc 1f
  204. unmask_interrupts
  205. rcall syscall_trace
  206. mask_interrupts
  207. ld.w r1, r0[TI_flags]
  208. 1: bld r1, TIF_NEED_RESCHED
  209. brcc 2f
  210. unmask_interrupts
  211. rcall schedule
  212. mask_interrupts
  213. ld.w r1, r0[TI_flags]
  214. rjmp 1b
  215. 2: mov r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK
  216. tst r1, r2
  217. breq 3f
  218. unmask_interrupts
  219. mov r12, sp
  220. mov r11, r0
  221. rcall do_notify_resume
  222. mask_interrupts
  223. ld.w r1, r0[TI_flags]
  224. rjmp 1b
  225. 3: bld r1, TIF_BREAKPOINT
  226. brcc syscall_exit_cont
  227. mfsr r3, SYSREG_TLBEHI
  228. lddsp r2, sp[REG_PC]
  229. andl r3, 0xff, COH
  230. lsl r3, 1
  231. sbr r3, 30
  232. sbr r3, 0
  233. mtdr DBGREG_BWA2A, r2
  234. mtdr DBGREG_BWC2A, r3
  235. rjmp syscall_exit_cont
  236. /* The slow path of the TLB miss handler */
  237. page_table_not_present:
  238. page_not_present:
  239. tlbmiss_restore
  240. sub sp, 4
  241. stmts --sp, r0-lr
  242. rcall save_full_context_ex
  243. mfsr r12, SYSREG_ECR
  244. mov r11, sp
  245. rcall do_page_fault
  246. rjmp ret_from_exception
  247. /* This function expects to find offending PC in SYSREG_RAR_EX */
  248. save_full_context_ex:
  249. mfsr r8, SYSREG_RSR_EX
  250. mov r12, r8
  251. andh r8, (MODE_MASK >> 16), COH
  252. mfsr r11, SYSREG_RAR_EX
  253. brne 2f
  254. 1: pushm r11, r12 /* PC and SR */
  255. unmask_exceptions
  256. ret r12
  257. 2: sub r10, sp, -(FRAME_SIZE_FULL - REG_LR)
  258. stdsp sp[4], r10 /* replace saved SP */
  259. rjmp 1b
  260. /* Low-level exception handlers */
  261. handle_critical:
  262. pushm r12
  263. pushm r0-r12
  264. rcall save_full_context_ex
  265. mfsr r12, SYSREG_ECR
  266. mov r11, sp
  267. rcall do_critical_exception
  268. /* We should never get here... */
  269. bad_return:
  270. sub r12, pc, (. - 1f)
  271. bral panic
  272. .align 2
  273. 1: .asciz "Return from critical exception!"
  274. .align 1
  275. do_bus_error_write:
  276. sub sp, 4
  277. stmts --sp, r0-lr
  278. rcall save_full_context_ex
  279. mov r11, 1
  280. rjmp 1f
  281. do_bus_error_read:
  282. sub sp, 4
  283. stmts --sp, r0-lr
  284. rcall save_full_context_ex
  285. mov r11, 0
  286. 1: mfsr r12, SYSREG_BEAR
  287. mov r10, sp
  288. rcall do_bus_error
  289. rjmp ret_from_exception
  290. .align 1
  291. do_nmi_ll:
  292. sub sp, 4
  293. stmts --sp, r0-lr
  294. mfsr r9, SYSREG_RSR_NMI
  295. mfsr r8, SYSREG_RAR_NMI
  296. bfextu r0, r9, MODE_SHIFT, 3
  297. brne 2f
  298. 1: pushm r8, r9 /* PC and SR */
  299. mfsr r12, SYSREG_ECR
  300. mov r11, sp
  301. rcall do_nmi
  302. popm r8-r9
  303. mtsr SYSREG_RAR_NMI, r8
  304. tst r0, r0
  305. mtsr SYSREG_RSR_NMI, r9
  306. brne 3f
  307. ldmts sp++, r0-lr
  308. sub sp, -4 /* skip r12_orig */
  309. rete
  310. 2: sub r10, sp, -(FRAME_SIZE_FULL - REG_LR)
  311. stdsp sp[4], r10 /* replace saved SP */
  312. rjmp 1b
  313. 3: popm lr
  314. sub sp, -4 /* skip sp */
  315. popm r0-r12
  316. sub sp, -4 /* skip r12_orig */
  317. rete
  318. handle_address_fault:
  319. sub sp, 4
  320. stmts --sp, r0-lr
  321. rcall save_full_context_ex
  322. mfsr r12, SYSREG_ECR
  323. mov r11, sp
  324. rcall do_address_exception
  325. rjmp ret_from_exception
  326. handle_protection_fault:
  327. sub sp, 4
  328. stmts --sp, r0-lr
  329. rcall save_full_context_ex
  330. mfsr r12, SYSREG_ECR
  331. mov r11, sp
  332. rcall do_page_fault
  333. rjmp ret_from_exception
  334. .align 1
  335. do_illegal_opcode_ll:
  336. sub sp, 4
  337. stmts --sp, r0-lr
  338. rcall save_full_context_ex
  339. mfsr r12, SYSREG_ECR
  340. mov r11, sp
  341. rcall do_illegal_opcode
  342. rjmp ret_from_exception
  343. do_dtlb_modified:
  344. pushm r0-r3
  345. mfsr r1, SYSREG_TLBEAR
  346. mfsr r0, SYSREG_PTBR
  347. lsr r2, r1, PGDIR_SHIFT
  348. ld.w r0, r0[r2 << 2]
  349. lsl r1, (32 - PGDIR_SHIFT)
  350. lsr r1, (32 - PGDIR_SHIFT) + PAGE_SHIFT
  351. /* Translate to virtual address in P1 */
  352. andl r0, 0xf000
  353. sbr r0, 31
  354. add r2, r0, r1 << 2
  355. ld.w r3, r2[0]
  356. sbr r3, _PAGE_BIT_DIRTY
  357. mov r0, r3
  358. st.w r2[0], r3
  359. /* The page table is up-to-date. Update the TLB entry as well */
  360. andl r0, lo(_PAGE_FLAGS_HARDWARE_MASK)
  361. mtsr SYSREG_TLBELO, r0
  362. /* MMUCR[DRP] is updated automatically, so let's go... */
  363. tlbw
  364. popm r0-r3
  365. rete
  366. do_fpe_ll:
  367. sub sp, 4
  368. stmts --sp, r0-lr
  369. rcall save_full_context_ex
  370. unmask_interrupts
  371. mov r12, 26
  372. mov r11, sp
  373. rcall do_fpe
  374. rjmp ret_from_exception
  375. ret_from_exception:
  376. mask_interrupts
  377. lddsp r4, sp[REG_SR]
  378. andh r4, (MODE_MASK >> 16), COH
  379. brne fault_resume_kernel
  380. get_thread_info r0
  381. ld.w r1, r0[TI_flags]
  382. andl r1, _TIF_WORK_MASK, COH
  383. brne fault_exit_work
  384. fault_resume_user:
  385. popm r8-r9
  386. mask_exceptions
  387. mtsr SYSREG_RAR_EX, r8
  388. mtsr SYSREG_RSR_EX, r9
  389. ldmts sp++, r0-lr
  390. sub sp, -4
  391. rete
  392. fault_resume_kernel:
  393. #ifdef CONFIG_PREEMPT
  394. get_thread_info r0
  395. ld.w r2, r0[TI_preempt_count]
  396. cp.w r2, 0
  397. brne 1f
  398. ld.w r1, r0[TI_flags]
  399. bld r1, TIF_NEED_RESCHED
  400. brcc 1f
  401. lddsp r4, sp[REG_SR]
  402. bld r4, SYSREG_GM_OFFSET
  403. brcs 1f
  404. rcall preempt_schedule_irq
  405. 1:
  406. #endif
  407. popm r8-r9
  408. mask_exceptions
  409. mfsr r1, SYSREG_SR
  410. mtsr SYSREG_RAR_EX, r8
  411. mtsr SYSREG_RSR_EX, r9
  412. popm lr
  413. sub sp, -4 /* ignore SP */
  414. popm r0-r12
  415. sub sp, -4 /* ignore r12_orig */
  416. rete
  417. irq_exit_work:
  418. /* Switch to exception mode so that we can share the same code. */
  419. mfsr r8, SYSREG_SR
  420. cbr r8, SYSREG_M0_OFFSET
  421. orh r8, hi(SYSREG_BIT(M1) | SYSREG_BIT(M2))
  422. mtsr SYSREG_SR, r8
  423. sub pc, -2
  424. get_thread_info r0
  425. ld.w r1, r0[TI_flags]
  426. fault_exit_work:
  427. bld r1, TIF_NEED_RESCHED
  428. brcc 1f
  429. unmask_interrupts
  430. rcall schedule
  431. mask_interrupts
  432. ld.w r1, r0[TI_flags]
  433. rjmp fault_exit_work
  434. 1: mov r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK
  435. tst r1, r2
  436. breq 2f
  437. unmask_interrupts
  438. mov r12, sp
  439. mov r11, r0
  440. rcall do_notify_resume
  441. mask_interrupts
  442. ld.w r1, r0[TI_flags]
  443. rjmp fault_exit_work
  444. 2: bld r1, TIF_BREAKPOINT
  445. brcc fault_resume_user
  446. mfsr r3, SYSREG_TLBEHI
  447. lddsp r2, sp[REG_PC]
  448. andl r3, 0xff, COH
  449. lsl r3, 1
  450. sbr r3, 30
  451. sbr r3, 0
  452. mtdr DBGREG_BWA2A, r2
  453. mtdr DBGREG_BWC2A, r3
  454. rjmp fault_resume_user
  455. /* If we get a debug trap from privileged context we end up here */
  456. handle_debug_priv:
  457. /* Fix up LR and SP in regs. r11 contains the mode we came from */
  458. mfsr r8, SYSREG_SR
  459. mov r9, r8
  460. andh r8, hi(~MODE_MASK)
  461. or r8, r11
  462. mtsr SYSREG_SR, r8
  463. sub pc, -2
  464. stdsp sp[REG_LR], lr
  465. mtsr SYSREG_SR, r9
  466. sub pc, -2
  467. sub r10, sp, -FRAME_SIZE_FULL
  468. stdsp sp[REG_SP], r10
  469. mov r12, sp
  470. rcall do_debug_priv
  471. /* Now, put everything back */
  472. ssrf SR_EM_BIT
  473. popm r10, r11
  474. mtsr SYSREG_RAR_DBG, r10
  475. mtsr SYSREG_RSR_DBG, r11
  476. mfsr r8, SYSREG_SR
  477. mov r9, r8
  478. andh r8, hi(~MODE_MASK)
  479. andh r11, hi(MODE_MASK)
  480. or r8, r11
  481. mtsr SYSREG_SR, r8
  482. sub pc, -2
  483. popm lr
  484. mtsr SYSREG_SR, r9
  485. sub pc, -2
  486. sub sp, -4 /* skip SP */
  487. popm r0-r12
  488. sub sp, -4
  489. retd
  490. /*
  491. * At this point, everything is masked, that is, interrupts,
  492. * exceptions and debugging traps. We might get called from
  493. * interrupt or exception context in some rare cases, but this
  494. * will be taken care of by do_debug(), so we're not going to
  495. * do a 100% correct context save here.
  496. */
  497. handle_debug:
  498. sub sp, 4 /* r12_orig */
  499. stmts --sp, r0-lr
  500. mfsr r10, SYSREG_RAR_DBG
  501. mfsr r11, SYSREG_RSR_DBG
  502. unmask_exceptions
  503. pushm r10,r11
  504. andh r11, (MODE_MASK >> 16), COH
  505. brne handle_debug_priv
  506. mov r12, sp
  507. rcall do_debug
  508. lddsp r10, sp[REG_SR]
  509. andh r10, (MODE_MASK >> 16), COH
  510. breq debug_resume_user
  511. debug_restore_all:
  512. popm r10,r11
  513. mask_exceptions
  514. mtsr SYSREG_RSR_DBG, r11
  515. mtsr SYSREG_RAR_DBG, r10
  516. ldmts sp++, r0-lr
  517. sub sp, -4
  518. retd
  519. debug_resume_user:
  520. get_thread_info r0
  521. mask_interrupts
  522. ld.w r1, r0[TI_flags]
  523. andl r1, _TIF_DBGWORK_MASK, COH
  524. breq debug_restore_all
  525. 1: bld r1, TIF_NEED_RESCHED
  526. brcc 2f
  527. unmask_interrupts
  528. rcall schedule
  529. mask_interrupts
  530. ld.w r1, r0[TI_flags]
  531. rjmp 1b
  532. 2: mov r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK
  533. tst r1, r2
  534. breq 3f
  535. unmask_interrupts
  536. mov r12, sp
  537. mov r11, r0
  538. rcall do_notify_resume
  539. mask_interrupts
  540. ld.w r1, r0[TI_flags]
  541. rjmp 1b
  542. 3: bld r1, TIF_SINGLE_STEP
  543. brcc debug_restore_all
  544. mfdr r2, DBGREG_DC
  545. sbr r2, DC_SS_BIT
  546. mtdr DBGREG_DC, r2
  547. rjmp debug_restore_all
  548. .set rsr_int0, SYSREG_RSR_INT0
  549. .set rsr_int1, SYSREG_RSR_INT1
  550. .set rsr_int2, SYSREG_RSR_INT2
  551. .set rsr_int3, SYSREG_RSR_INT3
  552. .set rar_int0, SYSREG_RAR_INT0
  553. .set rar_int1, SYSREG_RAR_INT1
  554. .set rar_int2, SYSREG_RAR_INT2
  555. .set rar_int3, SYSREG_RAR_INT3
  556. .macro IRQ_LEVEL level
  557. .type irq_level\level, @function
  558. irq_level\level:
  559. sub sp, 4 /* r12_orig */
  560. stmts --sp,r0-lr
  561. mfsr r8, rar_int\level
  562. mfsr r9, rsr_int\level
  563. #ifdef CONFIG_PREEMPT
  564. sub r11, pc, (. - system_call)
  565. cp.w r11, r8
  566. breq 4f
  567. #endif
  568. pushm r8-r9
  569. mov r11, sp
  570. mov r12, \level
  571. rcall do_IRQ
  572. lddsp r4, sp[REG_SR]
  573. bfextu r4, r4, SYSREG_M0_OFFSET, 3
  574. cp.w r4, MODE_SUPERVISOR >> SYSREG_M0_OFFSET
  575. breq 2f
  576. cp.w r4, MODE_USER >> SYSREG_M0_OFFSET
  577. #ifdef CONFIG_PREEMPT
  578. brne 3f
  579. #else
  580. brne 1f
  581. #endif
  582. get_thread_info r0
  583. ld.w r1, r0[TI_flags]
  584. andl r1, _TIF_WORK_MASK, COH
  585. brne irq_exit_work
  586. 1: popm r8-r9
  587. mtsr rar_int\level, r8
  588. mtsr rsr_int\level, r9
  589. ldmts sp++,r0-lr
  590. sub sp, -4 /* ignore r12_orig */
  591. rete
  592. #ifdef CONFIG_PREEMPT
  593. 4: mask_interrupts
  594. mfsr r8, rsr_int\level
  595. sbr r8, 16
  596. mtsr rsr_int\level, r8
  597. ldmts sp++, r0-lr
  598. sub sp, -4 /* ignore r12_orig */
  599. rete
  600. #endif
  601. 2: get_thread_info r0
  602. ld.w r1, r0[TI_flags]
  603. bld r1, TIF_CPU_GOING_TO_SLEEP
  604. #ifdef CONFIG_PREEMPT
  605. brcc 3f
  606. #else
  607. brcc 1b
  608. #endif
  609. sub r1, pc, . - cpu_idle_skip_sleep
  610. stdsp sp[REG_PC], r1
  611. #ifdef CONFIG_PREEMPT
  612. 3: get_thread_info r0
  613. ld.w r2, r0[TI_preempt_count]
  614. cp.w r2, 0
  615. brne 1b
  616. ld.w r1, r0[TI_flags]
  617. bld r1, TIF_NEED_RESCHED
  618. brcc 1b
  619. lddsp r4, sp[REG_SR]
  620. bld r4, SYSREG_GM_OFFSET
  621. brcs 1b
  622. rcall preempt_schedule_irq
  623. #endif
  624. rjmp 1b
  625. .endm
  626. .section .irq.text,"ax",@progbits
  627. .global cpu_idle_sleep
  628. cpu_idle_sleep:
  629. mask_interrupts
  630. get_thread_info r8
  631. ld.w r9, r8[TI_flags]
  632. bld r9, TIF_NEED_RESCHED
  633. brcs cpu_idle_enable_int_and_exit
  634. sbr r9, TIF_CPU_GOING_TO_SLEEP
  635. st.w r8[TI_flags], r9
  636. unmask_interrupts
  637. sleep 0
  638. cpu_idle_skip_sleep:
  639. mask_interrupts
  640. ld.w r9, r8[TI_flags]
  641. cbr r9, TIF_CPU_GOING_TO_SLEEP
  642. st.w r8[TI_flags], r9
  643. cpu_idle_enable_int_and_exit:
  644. unmask_interrupts
  645. retal r12
  646. .global irq_level0
  647. .global irq_level1
  648. .global irq_level2
  649. .global irq_level3
  650. IRQ_LEVEL 0
  651. IRQ_LEVEL 1
  652. IRQ_LEVEL 2
  653. IRQ_LEVEL 3