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