dcr.S 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /*
  2. * (C) Copyright 2001
  3. * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. #include <config.h>
  24. #if defined(CONFIG_4xx) && defined(CFG_CMD_SETGETDCR)
  25. #include <ppc4xx.h>
  26. #define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
  27. #include <ppc_asm.tmpl>
  28. #include <ppc_defs.h>
  29. #include <asm/cache.h>
  30. #include <asm/mmu.h>
  31. #define _ASMLANGUAGE
  32. /*****************************************************************************
  33. *
  34. * XXX - DANGER
  35. * These routines make use of self modifying code. DO NOT CALL THEM
  36. * UNTIL THEY ARE RELOCATED TO RAM. Additionally, I do not
  37. * recommend them for use in anything other than an interactive
  38. * debugging environment. This is mainly due to performance reasons.
  39. *
  40. ****************************************************************************/
  41. /*
  42. * static void _create_MFDCR(unsigned short dcrn)
  43. *
  44. * Builds a 'mfdcr' instruction for get_dcr
  45. * function.
  46. */
  47. .section ".text"
  48. .align 2
  49. .type _create_MFDCR,@function
  50. _create_MFDCR:
  51. /*
  52. * Build up a 'mfdcr' instruction formatted as follows:
  53. *
  54. * OPCD | RT | DCRF | XO | CR |
  55. * ---------------|--------------|--------------|----|
  56. * 0 5 | 6 10 | 11 20 | 21 30 | 31 |
  57. * | | DCRN | | |
  58. * 31 | %r3 | (5..9|0..4) | 323 | 0 |
  59. *
  60. * Where:
  61. * OPCD = opcode - 31
  62. * RT = destination register - %r3 return register
  63. * DCRF = DCRN # with upper and lower halves swapped
  64. * XO = extended opcode - 323
  65. * CR = CR[CR0] NOT undefined - 0
  66. */
  67. rlwinm r0, r3, 27, 27, 31 /* OPCD = 31 */
  68. rlwinm r3, r3, 5, 22, 26
  69. or r3, r3, r0
  70. slwi r3, r3, 10
  71. oris r3, r3, 0x3e30 /* RT = %r3 */
  72. ori r3, r3, 323 /* XO = 323 */
  73. slwi r3, r3, 1 /* CR = 0 */
  74. mflr r4
  75. stw r3, 0(r4) /* Store instr in get_dcr() */
  76. dcbst r0, r4 /* Make sure val is written out */
  77. sync /* Wait for write to complete */
  78. icbi r0, r4 /* Make sure old instr is dumped */
  79. isync /* Wait for icbi to complete */
  80. blr
  81. .Lfe1: .size _create_MFDCR,.Lfe1-_create_MFDCR
  82. /* end _create_MFDCR() */
  83. /*
  84. * static void _create_MTDCR(unsigned short dcrn, unsigned long value)
  85. *
  86. * Builds a 'mtdcr' instruction for set_dcr
  87. * function.
  88. */
  89. .section ".text"
  90. .align 2
  91. .type _create_MTDCR,@function
  92. _create_MTDCR:
  93. /*
  94. * Build up a 'mtdcr' instruction formatted as follows:
  95. *
  96. * OPCD | RS | DCRF | XO | CR |
  97. * ---------------|--------------|--------------|----|
  98. * 0 5 | 6 10 | 11 20 | 21 30 | 31 |
  99. * | | DCRN | | |
  100. * 31 | %r3 | (5..9|0..4) | 451 | 0 |
  101. *
  102. * Where:
  103. * OPCD = opcode - 31
  104. * RS = source register - %r4
  105. * DCRF = dest. DCRN # with upper and lower halves swapped
  106. * XO = extended opcode - 451
  107. * CR = CR[CR0] NOT undefined - 0
  108. */
  109. rlwinm r0, r3, 27, 27, 31 /* OPCD = 31 */
  110. rlwinm r3, r3, 5, 22, 26
  111. or r3, r3, r0
  112. slwi r3, r3, 10
  113. oris r3, r3, 0x3e40 /* RS = %r4 */
  114. ori r3, r3, 451 /* XO = 451 */
  115. slwi r3, r3, 1 /* CR = 0 */
  116. mflr r5
  117. stw r3, 0(r5) /* Store instr in set_dcr() */
  118. dcbst r0, r5 /* Make sure val is written out */
  119. sync /* Wait for write to complete */
  120. icbi r0, r5 /* Make sure old instr is dumped */
  121. isync /* Wait for icbi to complete */
  122. blr
  123. .Lfe2: .size _create_MTDCR,.Lfe2-_create_MTDCR
  124. /* end _create_MTDCR() */
  125. /*
  126. * unsigned long get_dcr(unsigned short dcrn)
  127. *
  128. * Return a given DCR's value.
  129. */
  130. /* */
  131. /* XXX - This is self modifying code, hence */
  132. /* it is in the data section. */
  133. /* */
  134. .section ".data"
  135. .align 2
  136. .globl get_dcr
  137. .type get_dcr,@function
  138. get_dcr:
  139. mflr r0 /* Get link register */
  140. stwu r1, -32(r1) /* Save back chain and move SP */
  141. stw r0, +36(r1) /* Save link register */
  142. bl _create_MFDCR /* Build following instruction */
  143. /* XXX - we build this instuction up on the fly. */
  144. .long 0 /* Get DCR's value */
  145. lwz r0, +36(r1) /* Get saved link register */
  146. mtlr r0 /* Restore link register */
  147. addi r1, r1, +32 /* Remove frame from stack */
  148. blr /* Return to calling function */
  149. .Lfe3: .size get_dcr,.Lfe3-get_dcr
  150. /* end get_dcr() */
  151. /*
  152. * unsigned void set_dcr(unsigned short dcrn, unsigned long value)
  153. *
  154. * Return a given DCR's value.
  155. */
  156. /*
  157. * XXX - This is self modifying code, hence
  158. * it is in the data section.
  159. */
  160. .section ".data"
  161. .align 2
  162. .globl set_dcr
  163. .type set_dcr,@function
  164. set_dcr:
  165. mflr r0 /* Get link register */
  166. stwu r1, -32(r1) /* Save back chain and move SP */
  167. stw r0, +36(r1) /* Save link register */
  168. bl _create_MTDCR /* Build following instruction */
  169. /* XXX - we build this instuction up on the fly. */
  170. .long 0 /* Set DCR's value */
  171. lwz r0, +36(r1) /* Get saved link register */
  172. mtlr r0 /* Restore link register */
  173. addi r1, r1, +32 /* Remove frame from stack */
  174. blr /* Return to calling function */
  175. .Lfe4: .size set_dcr,.Lfe4-set_dcr
  176. /* end set_dcr() */
  177. #endif /* CONFIG_4xx & CFG_CMD_SETGETDCR */