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