switch_cpu.S 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /*
  2. * 31-bit switch cpu code
  3. *
  4. * Copyright IBM Corp. 2009
  5. *
  6. */
  7. #include <linux/linkage.h>
  8. #include <asm/asm-offsets.h>
  9. #include <asm/ptrace.h>
  10. # smp_switch_to_cpu switches to destination cpu and executes the passed function
  11. # Parameter: %r2 - function to call
  12. # %r3 - function parameter
  13. # %r4 - stack poiner
  14. # %r5 - current cpu
  15. # %r6 - destination cpu
  16. .section .text
  17. ENTRY(smp_switch_to_cpu)
  18. stm %r6,%r15,__SF_GPRS(%r15)
  19. lr %r1,%r15
  20. ahi %r15,-STACK_FRAME_OVERHEAD
  21. st %r1,__SF_BACKCHAIN(%r15)
  22. basr %r13,0
  23. 0: la %r1,.gprregs_addr-0b(%r13)
  24. l %r1,0(%r1)
  25. stm %r0,%r15,0(%r1)
  26. 1: sigp %r0,%r6,__SIGP_RESTART /* start destination CPU */
  27. brc 2,1b /* busy, try again */
  28. 2: sigp %r0,%r5,__SIGP_STOP /* stop current CPU */
  29. brc 2,2b /* busy, try again */
  30. 3: j 3b
  31. ENTRY(smp_restart_cpu)
  32. basr %r13,0
  33. 0: la %r1,.gprregs_addr-0b(%r13)
  34. l %r1,0(%r1)
  35. lm %r0,%r15,0(%r1)
  36. 1: sigp %r0,%r5,__SIGP_SENSE /* Wait for calling CPU */
  37. brc 10,1b /* busy, accepted (status 0), running */
  38. tmll %r0,0x40 /* Test if calling CPU is stopped */
  39. jz 1b
  40. ltr %r4,%r4 /* New stack ? */
  41. jz 1f
  42. lr %r15,%r4
  43. 1: lr %r14,%r2 /* r14: Function to call */
  44. lr %r2,%r3 /* r2 : Parameter for function*/
  45. basr %r14,%r14 /* Call function */
  46. .gprregs_addr:
  47. .long .gprregs
  48. .section .data,"aw",@progbits
  49. .gprregs:
  50. .rept 16
  51. .long 0
  52. .endr