interrupts.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2000-2002
  4. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  5. *
  6. * (C) Copyright 2003
  7. * Gleb Natapov <gnatapov@mrv.com>
  8. */
  9. #include <common.h>
  10. #include <asm/processor.h>
  11. #include <watchdog.h>
  12. #ifdef CONFIG_LED_STATUS
  13. #include <status_led.h>
  14. #endif
  15. #ifndef CONFIG_MPC83XX_TIMER
  16. #ifndef CONFIG_SYS_WATCHDOG_FREQ
  17. #define CONFIG_SYS_WATCHDOG_FREQ (CONFIG_SYS_HZ / 2)
  18. #endif
  19. static unsigned decrementer_count; /* count value for 1e6/HZ microseconds */
  20. static __inline__ unsigned long get_dec (void)
  21. {
  22. unsigned long val;
  23. asm volatile ("mfdec %0":"=r" (val):);
  24. return val;
  25. }
  26. static __inline__ void set_dec (unsigned long val)
  27. {
  28. if (val)
  29. asm volatile ("mtdec %0"::"r" (val));
  30. }
  31. #endif /* !CONFIG_MPC83XX_TIMER */
  32. void enable_interrupts (void)
  33. {
  34. set_msr (get_msr () | MSR_EE);
  35. }
  36. /* returns flag if MSR_EE was set before */
  37. int disable_interrupts (void)
  38. {
  39. ulong msr = get_msr ();
  40. set_msr (msr & ~MSR_EE);
  41. return ((msr & MSR_EE) != 0);
  42. }
  43. #ifndef CONFIG_MPC83XX_TIMER
  44. int interrupt_init (void)
  45. {
  46. /* call cpu specific function from $(CPU)/interrupts.c */
  47. interrupt_init_cpu (&decrementer_count);
  48. set_dec (decrementer_count);
  49. set_msr (get_msr () | MSR_EE);
  50. return (0);
  51. }
  52. static volatile ulong timestamp = 0;
  53. void timer_interrupt (struct pt_regs *regs)
  54. {
  55. /* call cpu specific function from $(CPU)/interrupts.c */
  56. timer_interrupt_cpu (regs);
  57. /* Restore Decrementer Count */
  58. set_dec (decrementer_count);
  59. timestamp++;
  60. #if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG)
  61. if ((timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0)
  62. WATCHDOG_RESET ();
  63. #endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
  64. #ifdef CONFIG_LED_STATUS
  65. status_led_tick(timestamp);
  66. #endif /* CONFIG_LED_STATUS */
  67. }
  68. ulong get_timer (ulong base)
  69. {
  70. return (timestamp - base);
  71. }
  72. #endif /* !CONFIG_MPC83XX_TIMER */