/arch/powerpc/platforms/cell/spufs/spu_utils.h

http://github.com/mirrors/linux · C Header · 147 lines · 68 code · 21 blank · 58 comment · 1 complexity · e2dfdc5c1721f81c84c45e6955e58217 MD5 · raw file

  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * utils.h: Utilities for SPU-side of the context switch operation.
  4. *
  5. * (C) Copyright IBM 2005
  6. */
  7. #ifndef _SPU_CONTEXT_UTILS_H_
  8. #define _SPU_CONTEXT_UTILS_H_
  9. /*
  10. * 64-bit safe EA.
  11. */
  12. typedef union {
  13. unsigned long long ull;
  14. unsigned int ui[2];
  15. } addr64;
  16. /*
  17. * 128-bit register template.
  18. */
  19. typedef union {
  20. unsigned int slot[4];
  21. vector unsigned int v;
  22. } spu_reg128v;
  23. /*
  24. * DMA list structure.
  25. */
  26. struct dma_list_elem {
  27. unsigned int size;
  28. unsigned int ea_low;
  29. };
  30. /*
  31. * Declare storage for 8-byte aligned DMA list.
  32. */
  33. struct dma_list_elem dma_list[15] __attribute__ ((aligned(8)));
  34. /*
  35. * External definition for storage
  36. * declared in crt0.
  37. */
  38. extern spu_reg128v regs_spill[NR_SPU_SPILL_REGS];
  39. /*
  40. * Compute LSCSA byte offset for a given field.
  41. */
  42. static struct spu_lscsa *dummy = (struct spu_lscsa *)0;
  43. #define LSCSA_BYTE_OFFSET(_field) \
  44. ((char *)(&(dummy->_field)) - (char *)(&(dummy->gprs[0].slot[0])))
  45. #define LSCSA_QW_OFFSET(_field) (LSCSA_BYTE_OFFSET(_field) >> 4)
  46. static inline void set_event_mask(void)
  47. {
  48. unsigned int event_mask = 0;
  49. /* Save, Step 4:
  50. * Restore, Step 1:
  51. * Set the SPU_RdEventMsk channel to zero to mask
  52. * all events.
  53. */
  54. spu_writech(SPU_WrEventMask, event_mask);
  55. }
  56. static inline void set_tag_mask(void)
  57. {
  58. unsigned int tag_mask = 1;
  59. /* Save, Step 5:
  60. * Restore, Step 2:
  61. * Set the SPU_WrTagMsk channel to '01' to unmask
  62. * only tag group 0.
  63. */
  64. spu_writech(MFC_WrTagMask, tag_mask);
  65. }
  66. static inline void build_dma_list(addr64 lscsa_ea)
  67. {
  68. unsigned int ea_low;
  69. int i;
  70. /* Save, Step 6:
  71. * Restore, Step 3:
  72. * Update the effective address for the CSA in the
  73. * pre-canned DMA-list in local storage.
  74. */
  75. ea_low = lscsa_ea.ui[1];
  76. ea_low += LSCSA_BYTE_OFFSET(ls[16384]);
  77. for (i = 0; i < 15; i++, ea_low += 16384) {
  78. dma_list[i].size = 16384;
  79. dma_list[i].ea_low = ea_low;
  80. }
  81. }
  82. static inline void enqueue_putllc(addr64 lscsa_ea)
  83. {
  84. unsigned int ls = 0;
  85. unsigned int size = 128;
  86. unsigned int tag_id = 0;
  87. unsigned int cmd = 0xB4; /* PUTLLC */
  88. /* Save, Step 12:
  89. * Restore, Step 7:
  90. * Send a PUTLLC (tag 0) command to the MFC using
  91. * an effective address in the CSA in order to
  92. * remove any possible lock-line reservation.
  93. */
  94. spu_writech(MFC_LSA, ls);
  95. spu_writech(MFC_EAH, lscsa_ea.ui[0]);
  96. spu_writech(MFC_EAL, lscsa_ea.ui[1]);
  97. spu_writech(MFC_Size, size);
  98. spu_writech(MFC_TagID, tag_id);
  99. spu_writech(MFC_Cmd, cmd);
  100. }
  101. static inline void set_tag_update(void)
  102. {
  103. unsigned int update_any = 1;
  104. /* Save, Step 15:
  105. * Restore, Step 8:
  106. * Write the MFC_TagUpdate channel with '01'.
  107. */
  108. spu_writech(MFC_WrTagUpdate, update_any);
  109. }
  110. static inline void read_tag_status(void)
  111. {
  112. /* Save, Step 16:
  113. * Restore, Step 9:
  114. * Read the MFC_TagStat channel data.
  115. */
  116. spu_readch(MFC_RdTagStat);
  117. }
  118. static inline void read_llar_status(void)
  119. {
  120. /* Save, Step 17:
  121. * Restore, Step 10:
  122. * Read the MFC_AtomicStat channel data.
  123. */
  124. spu_readch(MFC_RdAtomicStat);
  125. }
  126. #endif /* _SPU_CONTEXT_UTILS_H_ */