interrupts.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /*
  2. * (C) Copyright 2001
  3. * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
  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. /*
  24. * interrupts.c - just enough support for the decrementer/timer
  25. */
  26. #include <common.h>
  27. #include <mpc8xx.h>
  28. #include <mpc8xx_irq.h>
  29. #include <asm/processor.h>
  30. #include <commproc.h>
  31. #include <command.h>
  32. /****************************************************************************/
  33. unsigned decrementer_count; /* count value for 1e6/HZ microseconds */
  34. /****************************************************************************/
  35. static __inline__ unsigned long
  36. get_msr(void)
  37. {
  38. unsigned long msr;
  39. asm volatile("mfmsr %0" : "=r" (msr) :);
  40. return msr;
  41. }
  42. static __inline__ void
  43. set_msr(unsigned long msr)
  44. {
  45. asm volatile("mtmsr %0" : : "r" (msr));
  46. }
  47. static __inline__ unsigned long
  48. get_dec(void)
  49. {
  50. unsigned long val;
  51. asm volatile("mfdec %0" : "=r" (val) :);
  52. return val;
  53. }
  54. static __inline__ void
  55. set_dec(unsigned long val)
  56. {
  57. asm volatile("mtdec %0" : : "r" (val));
  58. }
  59. void
  60. enable_interrupts(void)
  61. {
  62. set_msr (get_msr() | MSR_EE);
  63. }
  64. /* returns flag if MSR_EE was set before */
  65. int
  66. disable_interrupts(void)
  67. {
  68. ulong msr = get_msr();
  69. set_msr (msr & ~MSR_EE);
  70. return ((msr & MSR_EE) != 0);
  71. }
  72. /****************************************************************************/
  73. int interrupt_init(void)
  74. {
  75. #ifdef DEBUG
  76. printf("interrupt_init: GT main cause reg: %08x:%08x\n",
  77. GTREGREAD(LOW_INTERRUPT_CAUSE_REGISTER),
  78. GTREGREAD(HIGH_INTERRUPT_CAUSE_REGISTER));
  79. printf("interrupt_init: ethernet cause regs: %08x %08x %08x\n",
  80. GTREGREAD(ETHERNET0_INTERRUPT_CAUSE_REGISTER),
  81. GTREGREAD(ETHERNET1_INTERRUPT_CAUSE_REGISTER),
  82. GTREGREAD(ETHERNET2_INTERRUPT_CAUSE_REGISTER));
  83. printf("interrupt_init: ethernet mask regs: %08x %08x %08x\n",
  84. GTREGREAD(ETHERNET0_INTERRUPT_MASK_REGISTER),
  85. GTREGREAD(ETHERNET1_INTERRUPT_MASK_REGISTER),
  86. GTREGREAD(ETHERNET2_INTERRUPT_MASK_REGISTER));
  87. puts("interrupt_init: setting decrementer_count\n");
  88. #endif
  89. decrementer_count = get_tbclk() / CFG_HZ;
  90. #ifdef DEBUG
  91. puts("interrupt_init: setting actual decremter\n");
  92. #endif
  93. set_dec (get_tbclk() / CFG_HZ);
  94. #ifdef DEBUG
  95. printf("interrupt_init: enabling interrupts (msr = %08lx)\n",
  96. get_msr());
  97. #endif
  98. set_msr (get_msr() | MSR_EE);
  99. #ifdef DEBUG
  100. printf("interrupt_init: done. (msr = %08lx)\n", get_msr());
  101. #endif
  102. return (0);
  103. }
  104. /****************************************************************************/
  105. /*
  106. * Handle external interrupts
  107. */
  108. void
  109. external_interrupt(struct pt_regs *regs)
  110. {
  111. puts("external_interrupt (oops!)\n");
  112. }
  113. volatile ulong timestamp = 0;
  114. /*
  115. * timer_interrupt - gets called when the decrementer overflows,
  116. * with interrupts disabled.
  117. * Trivial implementation - no need to be really accurate.
  118. */
  119. void
  120. timer_interrupt(struct pt_regs *regs)
  121. {
  122. set_dec(decrementer_count);
  123. timestamp++;
  124. #if defined(CONFIG_WATCHDOG)
  125. if ((timestamp % (CFG_HZ / 2)) == 0) {
  126. #if defined(CONFIG_PCIPPC2)
  127. extern void pcippc2_wdt_reset (void);
  128. pcippc2_wdt_reset();
  129. #endif
  130. }
  131. #endif /* CONFIG_WATCHDOG */
  132. }
  133. /****************************************************************************/
  134. void
  135. reset_timer(void)
  136. {
  137. timestamp = 0;
  138. }
  139. ulong
  140. get_timer(ulong base)
  141. {
  142. return (timestamp - base);
  143. }
  144. void
  145. set_timer(ulong t)
  146. {
  147. timestamp = t;
  148. }
  149. /****************************************************************************/
  150. /*
  151. * Install and free a interrupt handler.
  152. */
  153. void
  154. irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
  155. {
  156. }
  157. void
  158. irq_free_handler(int vec)
  159. {
  160. }
  161. /****************************************************************************/
  162. void
  163. do_irqinfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
  164. {
  165. puts("IRQ related functions are unimplemented currently.\n");
  166. }