ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / v850 / kernel / sim85e2.c
1 /*
2  * arch/v850/kernel/sim85e2.c -- Machine-specific stuff for
3  *      V850E2 RTL simulator
4  *
5  *  Copyright (C) 2002,03  NEC Electronics Corporation
6  *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
7  *
8  * This file is subject to the terms and conditions of the GNU General
9  * Public License.  See the file COPYING in the main directory of this
10  * archive for more details.
11  *
12  * Written by Miles Bader <miles@gnu.org>
13  */
14
15 #include <linux/config.h>
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/init.h>
19 #include <linux/mm.h>
20 #include <linux/swap.h>
21 #include <linux/bootmem.h>
22 #include <linux/irq.h>
23
24 #include <asm/atomic.h>
25 #include <asm/page.h>
26 #include <asm/machdep.h>
27
28 #include "mach.h"
29
30
31 /* There are 4 possible areas we can use:
32
33      IRAM (1MB) is fast for instruction fetches, but slow for data
34      DRAM (1020KB) is fast for data, but slow for instructions
35      ERAM is cached, so should be fast for both insns and data
36      SDRAM is external DRAM, similar to ERAM
37 */
38
39 #define INIT_MEMC_FOR_SDRAM
40 #define USE_SDRAM_AREA
41 #define KERNEL_IN_SDRAM_AREA
42
43 #define DCACHE_MODE     V850E2_CACHE_BTSC_DCM_WT
44 /*#define DCACHE_MODE   V850E2_CACHE_BTSC_DCM_WB_ALLOC*/
45
46 #ifdef USE_SDRAM_AREA
47 #define RAM_START       SDRAM_ADDR
48 #define RAM_END         (SDRAM_ADDR + SDRAM_SIZE)
49 #else
50 /* When we use DRAM, we need to account for the fact that the end of it is
51    used for R0_RAM.  */
52 #define RAM_START       DRAM_ADDR
53 #define RAM_END         R0_RAM_ADDR
54 #endif
55
56
57 extern void memcons_setup (void);
58
59
60 #ifdef KERNEL_IN_SDRAM_AREA
61 #define EARLY_INIT_SECTION_ATTR __attribute__ ((section (".early.text")))
62 #else
63 #define EARLY_INIT_SECTION_ATTR __init
64 #endif
65
66 void EARLY_INIT_SECTION_ATTR mach_early_init (void)
67 {
68         extern int panic_timeout;
69
70         /* The sim85e2 simulator tracks `undefined' values, so to make
71            debugging easier, we begin by zeroing out all otherwise
72            undefined registers.  This is not strictly necessary.
73
74            The registers we zero are:
75                Every GPR except:
76                    stack-pointer (r3)
77                    task-pointer (r16)
78                    our return addr (r31)
79                Every system register (SPR) that we know about except for
80                the PSW (SPR 5), which we zero except for the
81                disable-interrupts bit.
82         */
83
84         /* GPRs */
85         asm volatile ("             mov r0, r1 ; mov r0, r2              ");
86         asm volatile ("mov r0, r4 ; mov r0, r5 ; mov r0, r6 ; mov r0, r7 ");
87         asm volatile ("mov r0, r8 ; mov r0, r9 ; mov r0, r10; mov r0, r11");
88         asm volatile ("mov r0, r12; mov r0, r13; mov r0, r14; mov r0, r15");
89         asm volatile ("             mov r0, r17; mov r0, r18; mov r0, r19");
90         asm volatile ("mov r0, r20; mov r0, r21; mov r0, r22; mov r0, r23");
91         asm volatile ("mov r0, r24; mov r0, r25; mov r0, r26; mov r0, r27");
92         asm volatile ("mov r0, r28; mov r0, r29; mov r0, r30");
93
94         /* SPRs */
95         asm volatile ("ldsr r0, 0;  ldsr r0, 1;  ldsr r0, 2;  ldsr r0, 3");
96         asm volatile ("ldsr r0, 4");
97         asm volatile ("addi 0x20, r0, r1; ldsr r1, 5"); /* PSW */
98         asm volatile ("ldsr r0, 16; ldsr r0, 17; ldsr r0, 18; ldsr r0, 19");
99         asm volatile ("ldsr r0, 20");
100
101
102 #ifdef INIT_MEMC_FOR_SDRAM
103         /* Settings for SDRAM controller.  */
104         V850E2_VSWC   = 0x0042;
105         V850E2_BSC    = 0x9286;
106         V850E2_BCT(0) = 0xb000; /* was: 0 */
107         V850E2_BCT(1) = 0x000b;
108         V850E2_ASC    = 0;
109         V850E2_LBS    = 0xa9aa; /* was: 0xaaaa */
110         V850E2_LBC(0) = 0;
111         V850E2_LBC(1) = 0;      /* was: 0x3 */
112         V850E2_BCC    = 0;
113         V850E2_RFS(4) = 0x800a; /* was: 0xf109 */
114         V850E2_SCR(4) = 0x2091; /* was: 0x20a1 */
115         V850E2_RFS(3) = 0x800c;
116         V850E2_SCR(3) = 0x20a1;
117         V850E2_DWC(0) = 0;
118         V850E2_DWC(1) = 0;
119 #endif
120
121 #if 0
122 #ifdef CONFIG_V850E2_SIM85E2S
123         /* Turn on the caches.  */
124         V850E2_CACHE_BTSC = V850E2_CACHE_BTSC_ICM | DCACHE_MODE;
125         V850E2_BHC  = 0x1010;
126 #elif CONFIG_V850E2_SIM85E2C
127         V850E2_CACHE_BTSC |= (V850E2_CACHE_BTSC_ICM | V850E2_CACHE_BTSC_DCM0);
128         V850E2_BUSM_BHC = 0xFFFF;
129 #endif
130 #else
131         V850E2_BHC  = 0;
132 #endif
133
134         /* Don't stop the simulator at `halt' instructions.  */
135         SIM85E2_NOTHAL = 1;
136
137         /* Ensure that the simulator halts on a panic, instead of going
138            into an infinite loop inside the panic function.  */
139         panic_timeout = -1;
140 }
141
142 void __init mach_setup (char **cmdline)
143 {
144         memcons_setup ();
145 }
146
147 void mach_get_physical_ram (unsigned long *ram_start, unsigned long *ram_len)
148 {
149         *ram_start = RAM_START;
150         *ram_len = RAM_END - RAM_START;
151 }
152
153 void __init mach_sched_init (struct irqaction *timer_action)
154 {
155         /* The simulator actually cycles through all interrupts
156            periodically.  We just pay attention to IRQ0, which gives us
157            1/64 the rate of the periodic interrupts.  */
158         setup_irq (0, timer_action);
159 }
160
161 void mach_gettimeofday (struct timespec *tv)
162 {
163         tv->tv_sec = 0;
164         tv->tv_nsec = 0;
165 }
166 \f
167 /* Interrupts */
168
169 struct v850e_intc_irq_init irq_inits[] = {
170         { "IRQ", 0, NUM_MACH_IRQS, 1, 7 },
171         { 0 }
172 };
173 struct hw_interrupt_type hw_itypes[1];
174
175 /* Initialize interrupts.  */
176 void __init mach_init_irqs (void)
177 {
178         v850e_intc_init_irq_types (irq_inits, hw_itypes);
179 }
180 \f
181
182 void machine_halt (void) __attribute__ ((noreturn));
183 void machine_halt (void)
184 {
185         SIM85E2_SIMFIN = 0;     /* Halt immediately.  */
186         for (;;) {}
187 }
188
189 EXPORT_SYMBOL(machine_halt);
190
191 void machine_restart (char *__unused)
192 {
193         machine_halt ();
194 }
195
196 EXPORT_SYMBOL(machine_restart);
197
198 void machine_power_off (void)
199 {
200         machine_halt ();
201 }
202
203 EXPORT_SYMBOL(machine_power_off);