blob: 5d2c13d97f88ec51aa9a37f079e2219705a27887 [file] [log] [blame]
wdenk074cff02004-02-24 00:16:43 +00001/*
2 * (C) Copyright 2004
3 * DAVE Srl
4 * http://www.dave-tech.it
5 * http://www.wawnet.biz
6 * mailto:info@wawnet.biz
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/hardware.h>
29
30#include <asm/proc-armv/ptrace.h>
31
wdenk074cff02004-02-24 00:16:43 +000032/* we always count down the max. */
33#define TIMER_LOAD_VAL 0xffff
34
35/* macro to read the 16 bit timer */
36#define READ_TIMER (TCNTO1 & 0xffff)
37
38#ifdef CONFIG_USE_IRQ
39#error CONFIG_USE_IRQ NOT supported
40#else
41void enable_interrupts (void)
42{
43 return;
44}
45int disable_interrupts (void)
46{
47 return 0;
48}
49#endif
50
51
52void bad_mode (void)
53{
54 panic ("Resetting CPU ...\n");
55 reset_cpu (0);
56}
57
58void show_regs (struct pt_regs *regs)
59{
60 unsigned long flags;
61 const char *processor_modes[] =
62 { "USER_26", "FIQ_26", "IRQ_26", "SVC_26", "UK4_26", "UK5_26",
63 "UK6_26", "UK7_26",
64 "UK8_26", "UK9_26", "UK10_26", "UK11_26", "UK12_26", "UK13_26",
65 "UK14_26", "UK15_26",
66 "USER_32", "FIQ_32", "IRQ_32", "SVC_32", "UK4_32", "UK5_32",
67 "UK6_32", "ABT_32",
68 "UK8_32", "UK9_32", "UK10_32", "UND_32", "UK12_32", "UK13_32",
69 "UK14_32", "SYS_32"
70 };
71
72 flags = condition_codes (regs);
73
74 printf ("pc : [<%08lx>] lr : [<%08lx>]\n"
75 "sp : %08lx ip : %08lx fp : %08lx\n",
76 instruction_pointer (regs),
77 regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
78 printf ("r10: %08lx r9 : %08lx r8 : %08lx\n",
79 regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
80 printf ("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
81 regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
82 printf ("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
83 regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
84 printf ("Flags: %c%c%c%c",
85 flags & CC_N_BIT ? 'N' : 'n',
86 flags & CC_Z_BIT ? 'Z' : 'z',
87 flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v');
88 printf (" IRQs %s FIQs %s Mode %s%s\n",
89 interrupts_enabled (regs) ? "on" : "off",
90 fast_interrupts_enabled (regs) ? "on" : "off",
91 processor_modes[processor_mode (regs)],
92 thumb_mode (regs) ? " (T)" : "");
93}
94
95void do_undefined_instruction (struct pt_regs *pt_regs)
96{
97 printf ("undefined instruction\n");
98 show_regs (pt_regs);
99 bad_mode ();
100}
101
102void do_software_interrupt (struct pt_regs *pt_regs)
103{
104 printf ("software interrupt\n");
105 show_regs (pt_regs);
106 bad_mode ();
107}
108
109void do_prefetch_abort (struct pt_regs *pt_regs)
110{
111 printf ("prefetch abort\n");
112 show_regs (pt_regs);
113 bad_mode ();
114}
115
116void do_data_abort (struct pt_regs *pt_regs)
117{
118 printf ("data abort\n");
119 show_regs (pt_regs);
120 bad_mode ();
121}
122
123void do_not_used (struct pt_regs *pt_regs)
124{
125 printf ("not used\n");
126 show_regs (pt_regs);
127 bad_mode ();
128}
129
130void do_fiq (struct pt_regs *pt_regs)
131{
132 printf ("fast interrupt request\n");
133 show_regs (pt_regs);
134 bad_mode ();
135}
136
137void do_irq (struct pt_regs *pt_regs)
138{
139 printf ("interrupt request\n");
140 show_regs (pt_regs);
141 bad_mode ();
142}
143
144static ulong timestamp;
145static ulong lastdec;
146
147int interrupt_init (void)
148{
149 TCFG0 = 0x000000E9;
150 TCFG1 = 0x00000004;
151 TCON = 0x00000900;
152 TCNTB1 = TIMER_LOAD_VAL;
153 TCMPB1 = 0;
154 TCON = 0x00000B00;
155 TCON = 0x00000900;
156
157
158 lastdec = TCNTB1 = TIMER_LOAD_VAL;
159 timestamp = 0;
160 return 0;
161}
162
163/*
164 * timer without interrupts
165 */
166
167void reset_timer (void)
168{
169 reset_timer_masked ();
170}
171
172ulong get_timer (ulong base)
173{
174 return get_timer_masked () - base;
175}
176
177void set_timer (ulong t)
178{
179 timestamp = t;
180}
181
182void udelay (unsigned long usec)
183{
184 ulong tmo;
185
186 tmo = usec / 1000;
187 tmo *= CFG_HZ;
188 tmo /= 8;
189
190 tmo += get_timer (0);
191
192 while (get_timer_masked () < tmo)
193 /*NOP*/;
194}
195
196void reset_timer_masked (void)
197{
198 /* reset time */
199 lastdec = READ_TIMER;
200 timestamp = 0;
201}
202
203ulong get_timer_masked (void)
204{
205 ulong now = READ_TIMER;
206
207 if (lastdec >= now) {
208 /* normal mode */
209 timestamp += lastdec - now;
210 } else {
211 /* we have an overflow ... */
212 timestamp += lastdec + TIMER_LOAD_VAL - now;
213 }
214 lastdec = now;
215
216 return timestamp;
217}
218
219void udelay_masked (unsigned long usec)
220{
221 ulong tmo;
wdenk101e8df2005-04-04 12:08:28 +0000222 ulong endtime;
223 signed long diff;
wdenk074cff02004-02-24 00:16:43 +0000224
wdenk101e8df2005-04-04 12:08:28 +0000225 if (usec >= 1000) {
226 tmo = usec / 1000;
227 tmo *= CFG_HZ;
228 tmo /= 8;
229 } else {
230 tmo = usec * CFG_HZ;
231 tmo /= (1000*8);
232 }
wdenk074cff02004-02-24 00:16:43 +0000233
wdenk101e8df2005-04-04 12:08:28 +0000234 endtime = get_timer(0) + tmo;
wdenk074cff02004-02-24 00:16:43 +0000235
wdenk101e8df2005-04-04 12:08:28 +0000236 do {
237 ulong now = get_timer_masked ();
238 diff = endtime - now;
239 } while (diff >= 0);
wdenk074cff02004-02-24 00:16:43 +0000240}