aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68knommu/platform/5307
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/m68knommu/platform/5307
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'arch/m68knommu/platform/5307')
-rw-r--r--arch/m68knommu/platform/5307/Makefile29
-rw-r--r--arch/m68knommu/platform/5307/config.c148
-rw-r--r--arch/m68knommu/platform/5307/entry.S268
-rw-r--r--arch/m68knommu/platform/5307/head.S253
-rw-r--r--arch/m68knommu/platform/5307/ints.c280
-rw-r--r--arch/m68knommu/platform/5307/pit.c88
-rw-r--r--arch/m68knommu/platform/5307/timers.c138
-rw-r--r--arch/m68knommu/platform/5307/vectors.c95
8 files changed, 1299 insertions, 0 deletions
diff --git a/arch/m68knommu/platform/5307/Makefile b/arch/m68knommu/platform/5307/Makefile
new file mode 100644
index 000000000000..84b6b70641e1
--- /dev/null
+++ b/arch/m68knommu/platform/5307/Makefile
@@ -0,0 +1,29 @@
1#
2# Makefile for the m68knommu kernel.
3#
4
5#
6# If you want to play with the HW breakpoints then you will
7# need to add define this, which will give you a stack backtrace
8# on the console port whenever a DBG interrupt occurs. You have to
9# set up you HW breakpoints to trigger a DBG interrupt:
10#
11# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
12# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
13#
14
15ifdef CONFIG_FULLDEBUG
16AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
17endif
18
19obj-$(CONFIG_COLDFIRE) += entry.o vectors.o ints.o
20obj-$(CONFIG_M5206) += timers.o
21obj-$(CONFIG_M5206e) += timers.o
22obj-$(CONFIG_M5249) += timers.o
23obj-$(CONFIG_M527x) += pit.o
24obj-$(CONFIG_M5272) += timers.o
25obj-$(CONFIG_M5307) += config.o timers.o
26obj-$(CONFIG_M528x) += pit.o
27obj-$(CONFIG_M5407) += timers.o
28
29extra-y := head.o
diff --git a/arch/m68knommu/platform/5307/config.c b/arch/m68knommu/platform/5307/config.c
new file mode 100644
index 000000000000..7ed5782e9236
--- /dev/null
+++ b/arch/m68knommu/platform/5307/config.c
@@ -0,0 +1,148 @@
1/***************************************************************************/
2
3/*
4 * linux/arch/m68knommu/platform/5307/config.c
5 *
6 * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
7 * Copyright (C) 2000, Lineo (www.lineo.com)
8 */
9
10/***************************************************************************/
11
12#include <linux/config.h>
13#include <linux/kernel.h>
14#include <linux/sched.h>
15#include <linux/param.h>
16#include <linux/init.h>
17#include <linux/interrupt.h>
18#include <asm/irq.h>
19#include <asm/dma.h>
20#include <asm/traps.h>
21#include <asm/machdep.h>
22#include <asm/coldfire.h>
23#include <asm/mcftimer.h>
24#include <asm/mcfsim.h>
25#include <asm/mcfdma.h>
26#include <asm/mcfwdebug.h>
27
28/***************************************************************************/
29
30void coldfire_tick(void);
31void coldfire_timer_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
32unsigned long coldfire_timer_offset(void);
33void coldfire_trap_init(void);
34void coldfire_reset(void);
35
36extern unsigned int mcf_timervector;
37extern unsigned int mcf_profilevector;
38extern unsigned int mcf_timerlevel;
39
40/***************************************************************************/
41
42/*
43 * Some platforms need software versions of the GPIO data registers.
44 */
45unsigned short ppdata;
46unsigned char ledbank = 0xff;
47
48/***************************************************************************/
49
50/*
51 * DMA channel base address table.
52 */
53unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = {
54 MCF_MBAR + MCFDMA_BASE0,
55 MCF_MBAR + MCFDMA_BASE1,
56 MCF_MBAR + MCFDMA_BASE2,
57 MCF_MBAR + MCFDMA_BASE3,
58};
59
60unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
61
62/***************************************************************************/
63
64void mcf_autovector(unsigned int vec)
65{
66 volatile unsigned char *mbar;
67
68 if ((vec >= 25) && (vec <= 31)) {
69 mbar = (volatile unsigned char *) MCF_MBAR;
70 vec = 0x1 << (vec - 24);
71 *(mbar + MCFSIM_AVR) |= vec;
72 mcf_setimr(mcf_getimr() & ~vec);
73 }
74}
75
76/***************************************************************************/
77
78void mcf_settimericr(unsigned int timer, unsigned int level)
79{
80 volatile unsigned char *icrp;
81 unsigned int icr, imr;
82
83 if (timer <= 2) {
84 switch (timer) {
85 case 2: icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break;
86 default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break;
87 }
88
89 icrp = (volatile unsigned char *) (MCF_MBAR + icr);
90 *icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3;
91 mcf_setimr(mcf_getimr() & ~imr);
92 }
93}
94
95/***************************************************************************/
96
97int mcf_timerirqpending(int timer)
98{
99 unsigned int imr = 0;
100
101 switch (timer) {
102 case 1: imr = MCFSIM_IMR_TIMER1; break;
103 case 2: imr = MCFSIM_IMR_TIMER2; break;
104 default: break;
105 }
106 return (mcf_getipr() & imr);
107}
108
109/***************************************************************************/
110
111void config_BSP(char *commandp, int size)
112{
113 mcf_setimr(MCFSIM_IMR_MASKALL);
114
115#if defined(CONFIG_BOOTPARAM)
116 strncpy(commandp, CONFIG_BOOTPARAM_STRING, size);
117 commandp[size-1] = 0;
118#elif defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \
119 defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || \
120 defined(CONFIG_CLEOPATRA)
121 /* Copy command line from FLASH to local buffer... */
122 memcpy(commandp, (char *) 0xf0004000, size);
123 commandp[size-1] = 0;
124 /* Different timer setup - to prevent device clash */
125 mcf_timervector = 30;
126 mcf_profilevector = 31;
127 mcf_timerlevel = 6;
128#else
129 memset(commandp, 0, size);
130#endif
131
132 mach_sched_init = coldfire_timer_init;
133 mach_tick = coldfire_tick;
134 mach_gettimeoffset = coldfire_timer_offset;
135 mach_trap_init = coldfire_trap_init;
136 mach_reset = coldfire_reset;
137
138#ifdef MCF_BDM_DISABLE
139 /*
140 * Disable the BDM clocking. This also turns off most of the rest of
141 * the BDM device. This is good for EMC reasons. This option is not
142 * incompatible with the memory protection option.
143 */
144 wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
145#endif
146}
147
148/***************************************************************************/
diff --git a/arch/m68knommu/platform/5307/entry.S b/arch/m68knommu/platform/5307/entry.S
new file mode 100644
index 000000000000..89b180d4ed6a
--- /dev/null
+++ b/arch/m68knommu/platform/5307/entry.S
@@ -0,0 +1,268 @@
1/*
2 * linux/arch/m68knommu/platform/5307/entry.S
3 *
4 * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
5 * Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>,
6 * Kenneth Albanowski <kjahds@kjahds.com>,
7 * Copyright (C) 2000 Lineo Inc. (www.lineo.com)
8 * Copyright (C) 2004 Macq Electronique SA. (www.macqel.com)
9 *
10 * Based on:
11 *
12 * linux/arch/m68k/kernel/entry.S
13 *
14 * Copyright (C) 1991, 1992 Linus Torvalds
15 *
16 * This file is subject to the terms and conditions of the GNU General Public
17 * License. See the file README.legal in the main directory of this archive
18 * for more details.
19 *
20 * Linux/m68k support by Hamish Macdonald
21 *
22 * 68060 fixes by Jesper Skov
23 * ColdFire support by Greg Ungerer (gerg@snapgear.com)
24 * 5307 fixes by David W. Miller
25 * linux 2.4 support David McCullough <davidm@snapgear.com>
26 * Bug, speed and maintainability fixes by Philippe De Muyter <phdm@macqel.be>
27 */
28
29#include <linux/config.h>
30#include <linux/sys.h>
31#include <linux/linkage.h>
32#include <asm/unistd.h>
33#include <asm/thread_info.h>
34#include <asm/errno.h>
35#include <asm/setup.h>
36#include <asm/segment.h>
37#include <asm/asm-offsets.h>
38#include <asm/entry.h>
39
40.bss
41
42sw_ksp:
43.long 0
44
45sw_usp:
46.long 0
47
48.text
49
50.globl system_call
51.globl resume
52.globl ret_from_exception
53.globl ret_from_signal
54.globl sys_call_table
55.globl ret_from_interrupt
56.globl inthandler
57.globl fasthandler
58
59ENTRY(system_call)
60 SAVE_ALL
61 move #0x2000,%sr /* enable intrs again */
62
63 movel #-LENOSYS,%d2
64 movel %d2,PT_D0(%sp) /* default return value in d0 */
65 /* original D0 is in orig_d0 */
66 movel %d0,%d2
67
68 /* save top of frame */
69 pea %sp@
70 jbsr set_esp0
71 addql #4,%sp
72
73 cmpl #NR_syscalls,%d2
74 jcc ret_from_exception
75 lea sys_call_table,%a0
76 lsll #2,%d2 /* movel %a0@(%d2:l:4),%d3 */
77 movel %a0@(%d2),%d3
78 jeq ret_from_exception
79 lsrl #2,%d2
80
81 movel %sp,%d2 /* get thread_info pointer */
82 andl #-THREAD_SIZE,%d2 /* at start of kernel stack */
83 movel %d2,%a0
84 btst #TIF_SYSCALL_TRACE,%a0@(TI_FLAGS)
85 bnes 1f
86
87 movel %d3,%a0
88 jbsr %a0@
89 movel %d0,%sp@(PT_D0) /* save the return value */
90 jra ret_from_exception
911:
92 subql #4,%sp
93 SAVE_SWITCH_STACK
94 jbsr syscall_trace
95 RESTORE_SWITCH_STACK
96 addql #4,%sp
97 movel %d3,%a0
98 jbsr %a0@
99 movel %d0,%sp@(PT_D0) /* save the return value */
100 subql #4,%sp /* dummy return address */
101 SAVE_SWITCH_STACK
102 jbsr syscall_trace
103
104ret_from_signal:
105 RESTORE_SWITCH_STACK
106 addql #4,%sp
107
108ret_from_exception:
109 btst #5,%sp@(PT_SR) /* check if returning to kernel */
110 jeq Luser_return /* if so, skip resched, signals */
111
112Lkernel_return:
113 moveml %sp@,%d1-%d5/%a0-%a2
114 lea %sp@(32),%sp /* space for 8 regs */
115 movel %sp@+,%d0
116 addql #4,%sp /* orig d0 */
117 addl %sp@+,%sp /* stk adj */
118 rte
119
120Luser_return:
121 movel %sp,%d1 /* get thread_info pointer */
122 andl #-THREAD_SIZE,%d1 /* at base of kernel stack */
123 movel %d1,%a0
124 movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */
125 andl #_TIF_WORK_MASK,%d1
126 jne Lwork_to_do /* still work to do */
127
128Lreturn:
129 move #0x2700,%sr /* disable intrs */
130 movel sw_usp,%a0 /* get usp */
131 movel %sp@(PT_PC),%a0@- /* copy exception program counter */
132 movel %sp@(PT_FORMATVEC),%a0@-/* copy exception format/vector/sr */
133 moveml %sp@,%d1-%d5/%a0-%a2
134 lea %sp@(32),%sp /* space for 8 regs */
135 movel %sp@+,%d0
136 addql #4,%sp /* orig d0 */
137 addl %sp@+,%sp /* stk adj */
138 addql #8,%sp /* remove exception */
139 movel %sp,sw_ksp /* save ksp */
140 subql #8,sw_usp /* set exception */
141 movel sw_usp,%sp /* restore usp */
142 rte
143
144Lwork_to_do:
145 movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */
146 btst #TIF_NEED_RESCHED,%d1
147 jne reschedule
148
149 /* GERG: do we need something here for TRACEing?? */
150
151Lsignal_return:
152 subql #4,%sp /* dummy return address */
153 SAVE_SWITCH_STACK
154 pea %sp@(SWITCH_STACK_SIZE)
155 clrl %sp@-
156 jsr do_signal
157 addql #8,%sp
158 RESTORE_SWITCH_STACK
159 addql #4,%sp
160 jmp Lreturn
161
162/*
163 * This is the generic interrupt handler (for all hardware interrupt
164 * sources). It figures out the vector number and calls the appropriate
165 * interrupt service routine directly.
166 */
167ENTRY(inthandler)
168 SAVE_ALL
169 moveq #-1,%d0
170 movel %d0,%sp@(PT_ORIG_D0)
171 addql #1,local_irq_count
172
173 movew %sp@(PT_FORMATVEC),%d0 /* put exception # in d0 */
174 andl #0x03fc,%d0 /* mask out vector only */
175
176 leal per_cpu__kstat+STAT_IRQ,%a0
177 addql #1,%a0@(%d0)
178
179 lsrl #2,%d0 /* calculate real vector # */
180 movel %d0,%d1 /* calculate array offset */
181 lsll #4,%d1
182 lea irq_list,%a0
183 addl %d1,%a0 /* pointer to array struct */
184
185 movel %sp,%sp@- /* push regs arg onto stack */
186 movel %a0@(8),%sp@- /* push devid arg */
187 movel %d0,%sp@- /* push vector # on stack */
188
189 movel %a0@,%a0 /* get function to call */
190 jbsr %a0@ /* call vector handler */
191 lea %sp@(12),%sp /* pop parameters off stack */
192
193 bra ret_from_interrupt /* this was fallthrough */
194
195/*
196 * This is the fast interrupt handler (for certain hardware interrupt
197 * sources). Unlike the normal interrupt handler it just uses the
198 * current stack (doesn't care if it is user or kernel). It also
199 * doesn't bother doing the bottom half handlers.
200 */
201ENTRY(fasthandler)
202 SAVE_LOCAL
203
204 movew %sp@(PT_FORMATVEC),%d0
205 andl #0x03fc,%d0 /* mask out vector only */
206
207 leal per_cpu__kstat+STAT_IRQ,%a0
208 addql #1,%a0@(%d0)
209
210 movel %sp,%sp@- /* push regs arg onto stack */
211 clrl %sp@- /* push devid arg */
212 lsrl #2,%d0 /* calculate real vector # */
213 movel %d0,%sp@- /* push vector # on stack */
214
215 lsll #4,%d0 /* adjust for array offset */
216 lea irq_list,%a0
217 movel %a0@(%d0),%a0 /* get function to call */
218 jbsr %a0@ /* call vector handler */
219 lea %sp@(12),%sp /* pop parameters off stack */
220
221 RESTORE_LOCAL
222
223ENTRY(ret_from_interrupt)
224 subql #1,local_irq_count
225 jeq 2f
2261:
227 RESTORE_ALL
2282:
229 moveb %sp@(PT_SR),%d0
230 andl #0x7,%d0
231 jhi 1b
232
233 /* check if we need to do software interrupts */
234 movel irq_stat+CPUSTAT_SOFTIRQ_PENDING,%d0
235 jeq ret_from_exception
236
237 pea ret_from_exception
238 jmp do_softirq
239
240/*
241 * Beware - when entering resume, prev (the current task) is
242 * in a0, next (the new task) is in a1,so don't change these
243 * registers until their contents are no longer needed.
244 */
245ENTRY(resume)
246 movel %a0, %d1 /* get prev thread in d1 */
247
248 movew %sr,%d0 /* save thread status reg */
249 movew %d0,%a0@(TASK_THREAD+THREAD_SR)
250
251 oril #0x700,%d0 /* disable interrupts */
252 move %d0,%sr
253
254 movel sw_usp,%d0 /* save usp */
255 movel %d0,%a0@(TASK_THREAD+THREAD_USP)
256
257 SAVE_SWITCH_STACK
258 movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack pointer */
259 movel %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */
260 RESTORE_SWITCH_STACK
261
262 movel %a1@(TASK_THREAD+THREAD_USP),%a0 /* restore thread user stack */
263 movel %a0, sw_usp
264
265 movew %a1@(TASK_THREAD+THREAD_SR),%d0 /* restore thread status reg */
266 movew %d0, %sr
267 rts
268
diff --git a/arch/m68knommu/platform/5307/head.S b/arch/m68knommu/platform/5307/head.S
new file mode 100644
index 000000000000..c7d7a395c4cc
--- /dev/null
+++ b/arch/m68knommu/platform/5307/head.S
@@ -0,0 +1,253 @@
1/*****************************************************************************/
2
3/*
4 * head.S -- common startup code for ColdFire CPUs.
5 *
6 * (C) Copyright 1999-2004, Greg Ungerer (gerg@snapgear.com).
7 */
8
9/*****************************************************************************/
10
11#include <linux/config.h>
12#include <linux/sys.h>
13#include <linux/linkage.h>
14#include <asm/asm-offsets.h>
15#include <asm/coldfire.h>
16#include <asm/mcfcache.h>
17#include <asm/mcfsim.h>
18
19/*****************************************************************************/
20
21/*
22 * Define fixed memory sizes. Configuration of a fixed memory size
23 * overrides everything else. If the user defined a size we just
24 * blindly use it (they know what they are doing right :-)
25 */
26#if defined(CONFIG_RAM32MB)
27#define MEM_SIZE 0x02000000 /* memory size 32Mb */
28#elif defined(CONFIG_RAM16MB)
29#define MEM_SIZE 0x01000000 /* memory size 16Mb */
30#elif defined(CONFIG_RAM8MB)
31#define MEM_SIZE 0x00800000 /* memory size 8Mb */
32#elif defined(CONFIG_RAM4MB)
33#define MEM_SIZE 0x00400000 /* memory size 4Mb */
34#elif defined(CONFIG_RAM1MB)
35#define MEM_SIZE 0x00100000 /* memory size 1Mb */
36#endif
37
38/*
39 * Memory size exceptions for special cases. Some boards may be set
40 * for auto memory sizing, but we can't do it that way for some reason.
41 * For example the 5206eLITE board has static RAM, and auto-detecting
42 * the SDRAM will do you no good at all.
43 */
44#ifdef CONFIG_RAMAUTO
45#if defined(CONFIG_M5206eLITE)
46#define MEM_SIZE 0x00100000 /* 1MiB default memory */
47#endif
48#endif /* CONFIG_RAMAUTO */
49
50/*
51 * If we don't have a fixed memory size now, then lets build in code
52 * to auto detect the DRAM size. Obviously this is the prefered
53 * method, and should work for most boards (it won't work for those
54 * that do not have their RAM starting at address 0).
55 */
56#if defined(MEM_SIZE)
57.macro GET_MEM_SIZE
58 movel #MEM_SIZE,%d0 /* hard coded memory size */
59.endm
60
61#elif defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
62 defined(CONFIG_M5249) || defined(CONFIG_M527x) || \
63 defined(CONFIG_M528x) || defined(CONFIG_M5307) || \
64 defined(CONFIG_M5407)
65/*
66 * Not all these devices have exactly the same DRAM controller,
67 * but the DCMR register is virtually identical - give or take
68 * a couple of bits. The only exception is the 5272 devices, their
69 * DRAM controller is quite different.
70 */
71.macro GET_MEM_SIZE
72 movel MCF_MBAR+MCFSIM_DMR0,%d0 /* get mask for 1st bank */
73 btst #0,%d0 /* check if region enabled */
74 beq 1f
75 andl #0xfffc0000,%d0
76 beq 1f
77 addl #0x00040000,%d0 /* convert mask to size */
781:
79 movel MCF_MBAR+MCFSIM_DMR1,%d1 /* get mask for 2nd bank */
80 btst #0,%d1 /* check if region enabled */
81 beq 2f
82 andl #0xfffc0000, %d1
83 beq 2f
84 addl #0x00040000,%d1
85 addl %d1,%d0 /* total mem size in d0 */
862:
87.endm
88
89#elif defined(CONFIG_M5272)
90.macro GET_MEM_SIZE
91 movel MCF_MBAR+MCFSIM_CSOR7,%d0 /* get SDRAM address mask */
92 andil #0xfffff000,%d0 /* mask out chip select options */
93 negl %d0 /* negate bits */
94.endm
95
96#else
97#error "ERROR: I don't know how to determine your boards memory size?"
98#endif
99
100
101/*
102 * Most ColdFire boards have their DRAM starting at address 0.
103 * Notable exception is the 5206eLITE board.
104 */
105#if defined(CONFIG_M5206eLITE)
106#define MEM_BASE 0x30000000
107#endif
108
109#ifndef MEM_BASE
110#define MEM_BASE 0x00000000 /* memory base at address 0 */
111#endif
112
113/*
114 * The default location for the vectors is at the base of RAM.
115 * Some boards might like to use internal SRAM or something like
116 * that. If no board specific header defines an alternative then
117 * use the base of RAM.
118 */
119#ifndef VBR_BASE
120#define VBR_BASE MEM_BASE /* vector address */
121#endif
122
123/*****************************************************************************/
124
125/*
126 * Boards and platforms can do specific early hardware setup if
127 * they need to. Most don't need this, define away if not required.
128 */
129#ifndef PLATFORM_SETUP
130#define PLATFORM_SETUP
131#endif
132
133/*****************************************************************************/
134
135.global _start
136.global _rambase
137.global _ramvec
138.global _ramstart
139.global _ramend
140
141/*****************************************************************************/
142
143.data
144
145/*
146 * During startup we store away the RAM setup. These are not in the
147 * bss, since their values are determined and written before the bss
148 * has been cleared.
149 */
150_rambase:
151.long 0
152_ramvec:
153.long 0
154_ramstart:
155.long 0
156_ramend:
157.long 0
158
159/*****************************************************************************/
160
161.text
162
163/*
164 * This is the codes first entry point. This is where it all
165 * begins...
166 */
167
168_start:
169 nop /* filler */
170 movew #0x2700, %sr /* no interrupts */
171
172 /*
173 * Do any platform or board specific setup now. Most boards
174 * don't need anything. Those exceptions are define this in
175 * their board specific includes.
176 */
177 PLATFORM_SETUP
178
179 /*
180 * Create basic memory configuration. Set VBR accordingly,
181 * and size memory.
182 */
183 movel #VBR_BASE,%a7
184 movec %a7,%VBR /* set vectors addr */
185 movel %a7,_ramvec
186
187 movel #MEM_BASE,%a7 /* mark the base of RAM */
188 movel %a7,_rambase
189
190 GET_MEM_SIZE /* macro code determines size */
191 movel %d0,_ramend /* set end ram addr */
192
193 /*
194 * Now that we know what the memory is, lets enable cache
195 * and get things moving. This is Coldfire CPU specific.
196 */
197 CACHE_ENABLE /* enable CPU cache */
198
199
200#ifdef CONFIG_ROMFS_FS
201 /*
202 * Move ROM filesystem above bss :-)
203 */
204 lea _sbss,%a0 /* get start of bss */
205 lea _ebss,%a1 /* set up destination */
206 movel %a0,%a2 /* copy of bss start */
207
208 movel 8(%a0),%d0 /* get size of ROMFS */
209 addql #8,%d0 /* allow for rounding */
210 andl #0xfffffffc, %d0 /* whole words */
211
212 addl %d0,%a0 /* copy from end */
213 addl %d0,%a1 /* copy from end */
214 movel %a1,_ramstart /* set start of ram */
215
216_copy_romfs:
217 movel -(%a0),%d0 /* copy dword */
218 movel %d0,-(%a1)
219 cmpl %a0,%a2 /* check if at end */
220 bne _copy_romfs
221
222#else /* CONFIG_ROMFS_FS */
223 lea _ebss,%a1
224 movel %a1,_ramstart
225#endif /* CONFIG_ROMFS_FS */
226
227
228 /*
229 * Zero out the bss region.
230 */
231 lea _sbss,%a0 /* get start of bss */
232 lea _ebss,%a1 /* get end of bss */
233 clrl %d0 /* set value */
234_clear_bss:
235 movel %d0,(%a0)+ /* clear each word */
236 cmpl %a0,%a1 /* check if at end */
237 bne _clear_bss
238
239 /*
240 * Load the current task pointer and stack.
241 */
242 lea init_thread_union,%a0
243 lea THREAD_SIZE(%a0),%sp
244
245 /*
246 * Assember start up done, start code proper.
247 */
248 jsr start_kernel /* start Linux kernel */
249
250_exit:
251 jmp _exit /* should never get here */
252
253/*****************************************************************************/
diff --git a/arch/m68knommu/platform/5307/ints.c b/arch/m68knommu/platform/5307/ints.c
new file mode 100644
index 000000000000..0117754d44f3
--- /dev/null
+++ b/arch/m68knommu/platform/5307/ints.c
@@ -0,0 +1,280 @@
1/*
2 * linux/arch/m68knommu/kernel/ints.c -- General interrupt handling code
3 *
4 * Copyright (C) 1999-2002 Greg Ungerer (gerg@snapgear.com)
5 * Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>,
6 * Kenneth Albanowski <kjahds@kjahds.com>,
7 * Copyright (C) 2000 Lineo Inc. (www.lineo.com)
8 *
9 * Based on:
10 *
11 * linux/arch/m68k/kernel/ints.c -- Linux/m68k general interrupt handling code
12 *
13 * This file is subject to the terms and conditions of the GNU General Public
14 * License. See the file COPYING in the main directory of this archive
15 * for more details.
16 */
17
18#include <linux/module.h>
19#include <linux/types.h>
20#include <linux/init.h>
21#include <linux/sched.h>
22#include <linux/kernel_stat.h>
23#include <linux/errno.h>
24#include <linux/config.h>
25#include <linux/seq_file.h>
26
27#include <asm/system.h>
28#include <asm/irq.h>
29#include <asm/traps.h>
30#include <asm/page.h>
31#include <asm/machdep.h>
32
33/*
34 * This table stores the address info for each vector handler.
35 */
36irq_handler_t irq_list[SYS_IRQS];
37
38#define NUM_IRQ_NODES 16
39static irq_node_t nodes[NUM_IRQ_NODES];
40
41/* The number of spurious interrupts */
42volatile unsigned int num_spurious;
43
44unsigned int local_bh_count[NR_CPUS];
45unsigned int local_irq_count[NR_CPUS];
46
47static irqreturn_t default_irq_handler(int irq, void *ptr, struct pt_regs *regs)
48{
49#if 1
50 printk(KERN_INFO "%s(%d): default irq handler vec=%d [0x%x]\n",
51 __FILE__, __LINE__, irq, irq);
52#endif
53 return(IRQ_HANDLED);
54}
55
56/*
57 * void init_IRQ(void)
58 *
59 * Parameters: None
60 *
61 * Returns: Nothing
62 *
63 * This function should be called during kernel startup to initialize
64 * the IRQ handling routines.
65 */
66
67void __init init_IRQ(void)
68{
69 int i;
70
71 for (i = 0; i < SYS_IRQS; i++) {
72 if (mach_default_handler)
73 irq_list[i].handler = (*mach_default_handler)[i];
74 else
75 irq_list[i].handler = default_irq_handler;
76 irq_list[i].flags = IRQ_FLG_STD;
77 irq_list[i].dev_id = NULL;
78 irq_list[i].devname = NULL;
79 }
80
81 for (i = 0; i < NUM_IRQ_NODES; i++)
82 nodes[i].handler = NULL;
83
84 if (mach_init_IRQ)
85 mach_init_IRQ();
86}
87
88irq_node_t *new_irq_node(void)
89{
90 irq_node_t *node;
91 short i;
92
93 for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--)
94 if (!node->handler)
95 return node;
96
97 printk(KERN_INFO "new_irq_node: out of nodes\n");
98 return NULL;
99}
100
101int request_irq(
102 unsigned int irq,
103 irqreturn_t (*handler)(int, void *, struct pt_regs *),
104 unsigned long flags,
105 const char *devname,
106 void *dev_id)
107{
108 if (irq < 0 || irq >= NR_IRQS) {
109 printk(KERN_WARNING "%s: Incorrect IRQ %d from %s\n", __FUNCTION__,
110 irq, devname);
111 return -ENXIO;
112 }
113
114 if (!(irq_list[irq].flags & IRQ_FLG_STD)) {
115 if (irq_list[irq].flags & IRQ_FLG_LOCK) {
116 printk(KERN_WARNING "%s: IRQ %d from %s is not replaceable\n",
117 __FUNCTION__, irq, irq_list[irq].devname);
118 return -EBUSY;
119 }
120 if (flags & IRQ_FLG_REPLACE) {
121 printk(KERN_WARNING "%s: %s can't replace IRQ %d from %s\n",
122 __FUNCTION__, devname, irq, irq_list[irq].devname);
123 return -EBUSY;
124 }
125 }
126
127 if (flags & IRQ_FLG_FAST) {
128 extern asmlinkage void fasthandler(void);
129 extern void set_evector(int vecnum, void (*handler)(void));
130 set_evector(irq, fasthandler);
131 }
132
133 irq_list[irq].handler = handler;
134 irq_list[irq].flags = flags;
135 irq_list[irq].dev_id = dev_id;
136 irq_list[irq].devname = devname;
137 return 0;
138}
139
140EXPORT_SYMBOL(request_irq);
141
142void free_irq(unsigned int irq, void *dev_id)
143{
144 if (irq >= NR_IRQS) {
145 printk(KERN_WARNING "%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
146 return;
147 }
148
149 if (irq_list[irq].dev_id != dev_id)
150 printk(KERN_WARNING "%s: Removing probably wrong IRQ %d from %s\n",
151 __FUNCTION__, irq, irq_list[irq].devname);
152
153 if (irq_list[irq].flags & IRQ_FLG_FAST) {
154 extern asmlinkage void inthandler(void);
155 extern void set_evector(int vecnum, void (*handler)(void));
156 set_evector(irq, inthandler);
157 }
158
159 if (mach_default_handler)
160 irq_list[irq].handler = (*mach_default_handler)[irq];
161 else
162 irq_list[irq].handler = default_irq_handler;
163 irq_list[irq].flags = IRQ_FLG_STD;
164 irq_list[irq].dev_id = NULL;
165 irq_list[irq].devname = NULL;
166}
167
168EXPORT_SYMBOL(free_irq);
169
170
171int sys_request_irq(unsigned int irq,
172 irqreturn_t (*handler)(int, void *, struct pt_regs *),
173 unsigned long flags, const char *devname, void *dev_id)
174{
175 if (irq > IRQ7) {
176 printk(KERN_WARNING "%s: Incorrect IRQ %d from %s\n",
177 __FUNCTION__, irq, devname);
178 return -ENXIO;
179 }
180
181#if 0
182 if (!(irq_list[irq].flags & IRQ_FLG_STD)) {
183 if (irq_list[irq].flags & IRQ_FLG_LOCK) {
184 printk(KERN_WARNING "%s: IRQ %d from %s is not replaceable\n",
185 __FUNCTION__, irq, irq_list[irq].devname);
186 return -EBUSY;
187 }
188 if (!(flags & IRQ_FLG_REPLACE)) {
189 printk(KERN_WARNING "%s: %s can't replace IRQ %d from %s\n",
190 __FUNCTION__, devname, irq, irq_list[irq].devname);
191 return -EBUSY;
192 }
193 }
194#endif
195
196 irq_list[irq].handler = handler;
197 irq_list[irq].flags = flags;
198 irq_list[irq].dev_id = dev_id;
199 irq_list[irq].devname = devname;
200 return 0;
201}
202
203void sys_free_irq(unsigned int irq, void *dev_id)
204{
205 if (irq > IRQ7) {
206 printk(KERN_WARNING "%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
207 return;
208 }
209
210 if (irq_list[irq].dev_id != dev_id)
211 printk(KERN_WARNING "%s: Removing probably wrong IRQ %d from %s\n",
212 __FUNCTION__, irq, irq_list[irq].devname);
213
214 irq_list[irq].handler = (*mach_default_handler)[irq];
215 irq_list[irq].flags = 0;
216 irq_list[irq].dev_id = NULL;
217 irq_list[irq].devname = NULL;
218}
219
220/*
221 * Do we need these probe functions on the m68k?
222 *
223 * ... may be useful with ISA devices
224 */
225unsigned long probe_irq_on (void)
226{
227 return 0;
228}
229
230EXPORT_SYMBOL(probe_irq_on);
231
232int probe_irq_off (unsigned long irqs)
233{
234 return 0;
235}
236
237EXPORT_SYMBOL(probe_irq_off);
238
239asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
240{
241 if (vec >= VEC_INT1 && vec <= VEC_INT7) {
242 vec -= VEC_SPUR;
243 kstat_cpu(0).irqs[vec]++;
244 irq_list[vec].handler(vec, irq_list[vec].dev_id, fp);
245 } else {
246 if (mach_process_int)
247 mach_process_int(vec, fp);
248 else
249 panic("Can't process interrupt vector %ld\n", vec);
250 return;
251 }
252}
253
254
255int show_interrupts(struct seq_file *p, void *v)
256{
257 int i = *(loff_t *) v;
258
259 if (i < NR_IRQS) {
260 if (! (irq_list[i].flags & IRQ_FLG_STD)) {
261 seq_printf(p, "%3d: %10u ", i,
262 (i ? kstat_cpu(0).irqs[i] : num_spurious));
263 if (irq_list[i].flags & IRQ_FLG_LOCK)
264 seq_printf(p, "L ");
265 else
266 seq_printf(p, " ");
267 seq_printf(p, "%s\n", irq_list[i].devname);
268 }
269 }
270
271 if (i == NR_IRQS && mach_get_irq_list)
272 mach_get_irq_list(p, v);
273 return 0;
274}
275
276void init_irq_proc(void)
277{
278 /* Insert /proc/irq driver here */
279}
280
diff --git a/arch/m68knommu/platform/5307/pit.c b/arch/m68knommu/platform/5307/pit.c
new file mode 100644
index 000000000000..a9b2c2e7e280
--- /dev/null
+++ b/arch/m68knommu/platform/5307/pit.c
@@ -0,0 +1,88 @@
1/***************************************************************************/
2
3/*
4 * pit.c -- Motorola ColdFire PIT timer. Currently this type of
5 * hardware timer only exists in the Motorola ColdFire
6 * 5270/5271 and 5282 CPUs.
7 *
8 * Copyright (C) 1999-2004, Greg Ungerer (gerg@snapgear.com)
9 * Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com)
10 *
11 */
12
13/***************************************************************************/
14
15#include <linux/config.h>
16#include <linux/kernel.h>
17#include <linux/sched.h>
18#include <linux/param.h>
19#include <linux/init.h>
20#include <linux/interrupt.h>
21#include <asm/irq.h>
22#include <asm/coldfire.h>
23#include <asm/mcfpit.h>
24#include <asm/mcfsim.h>
25
26/***************************************************************************/
27
28void coldfire_pit_tick(void)
29{
30 volatile struct mcfpit *tp;
31
32 /* Reset the ColdFire timer */
33 tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
34 tp->pcsr |= MCFPIT_PCSR_PIF;
35}
36
37/***************************************************************************/
38
39void coldfire_pit_init(irqreturn_t (*handler)(int, void *, struct pt_regs *))
40{
41 volatile unsigned char *icrp;
42 volatile unsigned long *imrp;
43 volatile struct mcfpit *tp;
44
45 request_irq(MCFINT_VECBASE + MCFINT_PIT1, handler, SA_INTERRUPT,
46 "ColdFire Timer", NULL);
47
48 icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 +
49 MCFINTC_ICR0 + MCFINT_PIT1);
50 *icrp = 0x2b; /* PIT1 with level 5, priority 3 */
51
52 imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
53 *imrp &= ~(1 << (MCFINT_PIT1 - 32));
54
55 /* Set up PIT timer 1 as poll clock */
56 tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
57 tp->pcsr = MCFPIT_PCSR_DISABLE;
58
59 tp->pmr = ((MCF_CLK / 2) / 64) / HZ;
60 tp->pcsr = MCFPIT_PCSR_EN | MCFPIT_PCSR_PIE | MCFPIT_PCSR_OVW |
61 MCFPIT_PCSR_RLD | MCFPIT_PCSR_CLK64;
62}
63
64/***************************************************************************/
65
66unsigned long coldfire_pit_offset(void)
67{
68 volatile struct mcfpit *tp;
69 volatile unsigned long *ipr;
70 unsigned long pmr, pcntr, offset;
71
72 tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
73 ipr = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IPRH);
74
75 pmr = *(&tp->pmr);
76 pcntr = *(&tp->pcntr);
77
78 /*
79 * If we are still in the first half of the upcount and a
80 * timer interupt is pending, then add on a ticks worth of time.
81 */
82 offset = ((pmr - pcntr) * (1000000 / HZ)) / pmr;
83 if ((offset < (1000000 / HZ / 2)) && (*ipr & (1 << (MCFINT_PIT1 - 32))))
84 offset += 1000000 / HZ;
85 return offset;
86}
87
88/***************************************************************************/
diff --git a/arch/m68knommu/platform/5307/timers.c b/arch/m68knommu/platform/5307/timers.c
new file mode 100644
index 000000000000..ef49596aa09c
--- /dev/null
+++ b/arch/m68knommu/platform/5307/timers.c
@@ -0,0 +1,138 @@
1/***************************************************************************/
2
3/*
4 * timers.c -- generic ColdFire hardware timer support.
5 *
6 * Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com)
7 */
8
9/***************************************************************************/
10
11#include <linux/config.h>
12#include <linux/kernel.h>
13#include <linux/sched.h>
14#include <linux/param.h>
15#include <linux/interrupt.h>
16#include <linux/init.h>
17#include <asm/irq.h>
18#include <asm/traps.h>
19#include <asm/machdep.h>
20#include <asm/coldfire.h>
21#include <asm/mcftimer.h>
22#include <asm/mcfsim.h>
23
24/***************************************************************************/
25
26/*
27 * Default the timer and vector to use for ColdFire. Some ColdFire
28 * CPU's and some boards may want different. Their sub-architecture
29 * startup code (in config.c) can change these if they want.
30 */
31unsigned int mcf_timervector = 29;
32unsigned int mcf_profilevector = 31;
33unsigned int mcf_timerlevel = 5;
34
35static volatile struct mcftimer *mcf_timerp;
36
37/*
38 * These provide the underlying interrupt vector support.
39 * Unfortunately it is a little different on each ColdFire.
40 */
41extern void mcf_settimericr(int timer, int level);
42extern int mcf_timerirqpending(int timer);
43
44/***************************************************************************/
45
46void coldfire_tick(void)
47{
48 /* Reset the ColdFire timer */
49 mcf_timerp->ter = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
50}
51
52/***************************************************************************/
53
54void coldfire_timer_init(irqreturn_t (*handler)(int, void *, struct pt_regs *))
55{
56 /* Set up an internal TIMER as poll clock */
57 mcf_timerp = (volatile struct mcftimer *) (MCF_MBAR + MCFTIMER_BASE1);
58 mcf_timerp->tmr = MCFTIMER_TMR_DISABLE;
59
60 mcf_timerp->trr = (unsigned short) ((MCF_BUSCLK / 16) / HZ);
61 mcf_timerp->tmr = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
62 MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
63
64 request_irq(mcf_timervector, handler, SA_INTERRUPT, "timer", NULL);
65 mcf_settimericr(1, mcf_timerlevel);
66
67#ifdef CONFIG_HIGHPROFILE
68 coldfire_profile_init();
69#endif
70}
71
72/***************************************************************************/
73
74unsigned long coldfire_timer_offset(void)
75{
76 unsigned long trr, tcn, offset;
77
78 /*
79 * The change to pointer and de-reference is to force the compiler
80 * to read the registers with a single 16bit access. Otherwise it
81 * does some crazy 8bit read combining.
82 */
83 tcn = *(&mcf_timerp->tcn);
84 trr = *(&mcf_timerp->trr);
85 offset = (tcn * (1000000 / HZ)) / trr;
86
87 /* Check if we just wrapped the counters and maybe missed a tick */
88 if ((offset < (1000000 / HZ / 2)) && mcf_timerirqpending(1))
89 offset += 1000000 / HZ;
90 return offset;
91}
92
93/***************************************************************************/
94#ifdef CONFIG_HIGHPROFILE
95/***************************************************************************/
96
97/*
98 * Choose a reasonably fast profile timer. Make it an odd value to
99 * try and get good coverage of kernal operations.
100 */
101#define PROFILEHZ 1013
102
103static volatile struct mcftimer *mcf_proftp;
104
105/*
106 * Use the other timer to provide high accuracy profiling info.
107 */
108
109void coldfire_profile_tick(int irq, void *dummy, struct pt_regs *regs)
110{
111 /* Reset ColdFire timer2 */
112 mcf_proftp->ter = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
113 if (current->pid)
114 profile_tick(CPU_PROFILING, regs);
115}
116
117/***************************************************************************/
118
119void coldfire_profile_init(void)
120{
121 printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n", PROFILEHZ);
122
123 /* Set up TIMER 2 as high speed profile clock */
124 mcf_proftp = (volatile struct mcftimer *) (MCF_MBAR + MCFTIMER_BASE2);
125 mcf_proftp->tmr = MCFTIMER_TMR_DISABLE;
126
127 mcf_proftp->trr = (unsigned short) ((MCF_CLK / 16) / PROFILEHZ);
128 mcf_proftp->tmr = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
129 MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
130
131 request_irq(mcf_profilevector, coldfire_profile_tick,
132 (SA_INTERRUPT | IRQ_FLG_FAST), "profile timer", NULL);
133 mcf_settimericr(2, 7);
134}
135
136/***************************************************************************/
137#endif /* CONFIG_HIGHPROFILE */
138/***************************************************************************/
diff --git a/arch/m68knommu/platform/5307/vectors.c b/arch/m68knommu/platform/5307/vectors.c
new file mode 100644
index 000000000000..ac313a160d8d
--- /dev/null
+++ b/arch/m68knommu/platform/5307/vectors.c
@@ -0,0 +1,95 @@
1/***************************************************************************/
2
3/*
4 * linux/arch/m68knommu/platform/5307/vectors.c
5 *
6 * Copyright (C) 1999-2003, Greg Ungerer <gerg@snapgear.com>
7 */
8
9/***************************************************************************/
10
11#include <linux/config.h>
12#include <linux/kernel.h>
13#include <linux/sched.h>
14#include <linux/param.h>
15#include <linux/init.h>
16#include <linux/unistd.h>
17#include <linux/delay.h>
18#include <asm/irq.h>
19#include <asm/dma.h>
20#include <asm/traps.h>
21#include <asm/machdep.h>
22#include <asm/coldfire.h>
23#include <asm/mcftimer.h>
24#include <asm/mcfsim.h>
25#include <asm/mcfdma.h>
26#include <asm/mcfwdebug.h>
27
28/***************************************************************************/
29
30#ifdef TRAP_DBG_INTERRUPT
31
32asmlinkage void dbginterrupt_c(struct frame *fp)
33{
34 extern void dump(struct pt_regs *fp);
35 printk(KERN_DEBUG "%s(%d): BUS ERROR TRAP\n", __FILE__, __LINE__);
36 dump((struct pt_regs *) fp);
37 asm("halt");
38}
39
40#endif
41
42/***************************************************************************/
43
44extern e_vector *_ramvec;
45
46void set_evector(int vecnum, void (*handler)(void))
47{
48 if (vecnum >= 0 && vecnum <= 255)
49 _ramvec[vecnum] = handler;
50}
51
52/***************************************************************************/
53
54/* Assembler routines */
55asmlinkage void buserr(void);
56asmlinkage void trap(void);
57asmlinkage void system_call(void);
58asmlinkage void inthandler(void);
59
60void __init coldfire_trap_init(void)
61{
62 int i;
63
64 /*
65 * There is a common trap handler and common interrupt
66 * handler that handle almost every vector. We treat
67 * the system call and bus error special, they get their
68 * own first level handlers.
69 */
70 for (i = 3; (i <= 23); i++)
71 _ramvec[i] = trap;
72 for (i = 33; (i <= 63); i++)
73 _ramvec[i] = trap;
74 for (i = 24; (i <= 31); i++)
75 _ramvec[i] = inthandler;
76 for (i = 64; (i < 255); i++)
77 _ramvec[i] = inthandler;
78 _ramvec[255] = 0;
79
80 _ramvec[2] = buserr;
81 _ramvec[32] = system_call;
82
83#ifdef TRAP_DBG_INTERRUPT
84 _ramvec[12] = dbginterrupt;
85#endif
86}
87
88/***************************************************************************/
89
90void coldfire_reset(void)
91{
92 HARD_RESET_NOW();
93}
94
95/***************************************************************************/