vmx_asm.S 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * Copyright 2015, Cyril Bur, IBM Corp.
  4. */
  5. #include "basic_asm.h"
  6. #include "vmx_asm.h"
  7. # Should be safe from C, only touches r4, r5 and v0,v1,v2
  8. FUNC_START(check_vmx)
  9. PUSH_BASIC_STACK(32)
  10. mr r4,r3
  11. li r3,1 # assume a bad result
  12. li r5,0
  13. lvx v0,r5,r4
  14. vcmpequd. v1,v0,v20
  15. vmr v2,v1
  16. addi r5,r5,16
  17. lvx v0,r5,r4
  18. vcmpequd. v1,v0,v21
  19. vand v2,v2,v1
  20. addi r5,r5,16
  21. lvx v0,r5,r4
  22. vcmpequd. v1,v0,v22
  23. vand v2,v2,v1
  24. addi r5,r5,16
  25. lvx v0,r5,r4
  26. vcmpequd. v1,v0,v23
  27. vand v2,v2,v1
  28. addi r5,r5,16
  29. lvx v0,r5,r4
  30. vcmpequd. v1,v0,v24
  31. vand v2,v2,v1
  32. addi r5,r5,16
  33. lvx v0,r5,r4
  34. vcmpequd. v1,v0,v25
  35. vand v2,v2,v1
  36. addi r5,r5,16
  37. lvx v0,r5,r4
  38. vcmpequd. v1,v0,v26
  39. vand v2,v2,v1
  40. addi r5,r5,16
  41. lvx v0,r5,r4
  42. vcmpequd. v1,v0,v27
  43. vand v2,v2,v1
  44. addi r5,r5,16
  45. lvx v0,r5,r4
  46. vcmpequd. v1,v0,v28
  47. vand v2,v2,v1
  48. addi r5,r5,16
  49. lvx v0,r5,r4
  50. vcmpequd. v1,v0,v29
  51. vand v2,v2,v1
  52. addi r5,r5,16
  53. lvx v0,r5,r4
  54. vcmpequd. v1,v0,v30
  55. vand v2,v2,v1
  56. addi r5,r5,16
  57. lvx v0,r5,r4
  58. vcmpequd. v1,v0,v31
  59. vand v2,v2,v1
  60. li r5,STACK_FRAME_LOCAL(0,0)
  61. stvx v2,r5,sp
  62. ldx r0,r5,sp
  63. cmpdi r0,0xffffffffffffffff
  64. bne 1f
  65. li r3,0
  66. 1: POP_BASIC_STACK(32)
  67. blr
  68. FUNC_END(check_vmx)
  69. # Safe from C
  70. FUNC_START(test_vmx)
  71. # r3 holds pointer to where to put the result of fork
  72. # r4 holds pointer to the pid
  73. # v20-v31 are non-volatile
  74. PUSH_BASIC_STACK(512)
  75. std r3,STACK_FRAME_PARAM(0)(sp) # Address of varray
  76. std r4,STACK_FRAME_PARAM(1)(sp) # address of pid
  77. PUSH_VMX(STACK_FRAME_LOCAL(2,0),r4)
  78. bl load_vmx
  79. nop
  80. li r0,__NR_fork
  81. sc
  82. # Pass the result of fork back to the caller
  83. ld r9,STACK_FRAME_PARAM(1)(sp)
  84. std r3,0(r9)
  85. ld r3,STACK_FRAME_PARAM(0)(sp)
  86. bl check_vmx
  87. nop
  88. POP_VMX(STACK_FRAME_LOCAL(2,0),r4)
  89. POP_BASIC_STACK(512)
  90. blr
  91. FUNC_END(test_vmx)
  92. # int preempt_vmx(vector int *varray, int *threads_starting, int *running)
  93. # On starting will (atomically) decrement threads_starting as a signal that
  94. # the VMX have been loaded with varray. Will proceed to check the validity of
  95. # the VMX registers while running is not zero.
  96. FUNC_START(preempt_vmx)
  97. PUSH_BASIC_STACK(512)
  98. std r3,STACK_FRAME_PARAM(0)(sp) # vector int *varray
  99. std r4,STACK_FRAME_PARAM(1)(sp) # int *threads_starting
  100. std r5,STACK_FRAME_PARAM(2)(sp) # int *running
  101. # VMX need to write to 16 byte aligned addresses, skip STACK_FRAME_LOCAL(3,0)
  102. PUSH_VMX(STACK_FRAME_LOCAL(4,0),r4)
  103. bl load_vmx
  104. nop
  105. sync
  106. # Atomic DEC
  107. ld r3,STACK_FRAME_PARAM(1)(sp)
  108. 1: lwarx r4,0,r3
  109. addi r4,r4,-1
  110. stwcx. r4,0,r3
  111. bne- 1b
  112. 2: ld r3,STACK_FRAME_PARAM(0)(sp)
  113. bl check_vmx
  114. nop
  115. cmpdi r3,0
  116. bne 3f
  117. ld r4,STACK_FRAME_PARAM(2)(sp)
  118. ld r5,0(r4)
  119. cmpwi r5,0
  120. bne 2b
  121. 3: POP_VMX(STACK_FRAME_LOCAL(4,0),r4)
  122. POP_BASIC_STACK(512)
  123. blr
  124. FUNC_END(preempt_vmx)