vmx_asm.S 2.9 KB

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