1 /* 2 * (C) Copyright 2000-2002 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * (C) Copyright 2003 6 * Gleb Natapov <gnatapov@mrv.com> 7 * 8 * See file CREDITS for list of people who contributed to this 9 * project. 10 * 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License as 13 * published by the Free Software Foundation; either version 2 of 14 * the License, or (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 24 * MA 02111-1307 USA 25 */ 26 27 #include <common.h> 28 #include <asm/processor.h> 29 #include <watchdog.h> 30 #ifdef CONFIG_STATUS_LED 31 #include <status_led.h> 32 #endif 33 34 #ifdef CONFIG_SHOW_ACTIVITY 35 void board_show_activity (ulong) __attribute__((weak, alias("__board_show_activity"))); 36 37 void __board_show_activity (ulong dummy) 38 { 39 return; 40 } 41 #endif /* CONFIG_SHOW_ACTIVITY */ 42 43 #ifndef CONFIG_SYS_WATCHDOG_FREQ 44 #define CONFIG_SYS_WATCHDOG_FREQ (CONFIG_SYS_HZ / 2) 45 #endif 46 47 extern int interrupt_init_cpu (unsigned *); 48 extern void timer_interrupt_cpu (struct pt_regs *); 49 50 static unsigned decrementer_count; /* count value for 1e6/HZ microseconds */ 51 52 static __inline__ unsigned long get_msr (void) 53 { 54 unsigned long msr; 55 56 asm volatile ("mfmsr %0":"=r" (msr):); 57 58 return msr; 59 } 60 61 static __inline__ void set_msr (unsigned long msr) 62 { 63 asm volatile ("mtmsr %0"::"r" (msr)); 64 } 65 66 static __inline__ unsigned long get_dec (void) 67 { 68 unsigned long val; 69 70 asm volatile ("mfdec %0":"=r" (val):); 71 72 return val; 73 } 74 75 76 static __inline__ void set_dec (unsigned long val) 77 { 78 if (val) 79 asm volatile ("mtdec %0"::"r" (val)); 80 } 81 82 83 void enable_interrupts (void) 84 { 85 set_msr (get_msr () | MSR_EE); 86 } 87 88 /* returns flag if MSR_EE was set before */ 89 int disable_interrupts (void) 90 { 91 ulong msr = get_msr (); 92 93 set_msr (msr & ~MSR_EE); 94 return ((msr & MSR_EE) != 0); 95 } 96 97 int interrupt_init (void) 98 { 99 int ret; 100 101 /* call cpu specific function from $(CPU)/interrupts.c */ 102 ret = interrupt_init_cpu (&decrementer_count); 103 104 if (ret) 105 return ret; 106 107 set_dec (decrementer_count); 108 109 set_msr (get_msr () | MSR_EE); 110 111 return (0); 112 } 113 114 static volatile ulong timestamp = 0; 115 116 void timer_interrupt (struct pt_regs *regs) 117 { 118 /* call cpu specific function from $(CPU)/interrupts.c */ 119 timer_interrupt_cpu (regs); 120 121 /* Restore Decrementer Count */ 122 set_dec (decrementer_count); 123 124 timestamp++; 125 126 #if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG) 127 if ((timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0) 128 WATCHDOG_RESET (); 129 #endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */ 130 131 #ifdef CONFIG_STATUS_LED 132 status_led_tick (timestamp); 133 #endif /* CONFIG_STATUS_LED */ 134 135 #ifdef CONFIG_SHOW_ACTIVITY 136 board_show_activity (timestamp); 137 #endif /* CONFIG_SHOW_ACTIVITY */ 138 } 139 140 ulong get_timer (ulong base) 141 { 142 return (timestamp - base); 143 } 144