xref: /linux/arch/nios2/kernel/head.S (revision e2683c8868d03382da7e1ce8453b543a043066d1)
1/*
2 * Copyright (C) 2009 Wind River Systems Inc
3 *   Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
4 * Copyright (C) 2004 Microtronix Datacom Ltd
5 * Copyright (C) 2001 Vic Phillips, Microtronix Datacom Ltd.
6 *
7 * Based on head.S for Altera's Excalibur development board with nios processor
8 *
9 * Based on the following from the Excalibur sdk distribution:
10 *	NA_MemoryMap.s, NR_JumpToStart.s, NR_Setup.s, NR_CWPManager.s
11 *
12 * This file is subject to the terms and conditions of the GNU General Public
13 * License. See the file "COPYING" in the main directory of this archive
14 * for more details.
15 */
16
17#include <linux/init.h>
18#include <linux/linkage.h>
19#include <asm/thread_info.h>
20#include <asm/processor.h>
21#include <asm/cache.h>
22#include <asm/page.h>
23#include <asm/asm-offsets.h>
24#include <asm/asm-macros.h>
25
26/*
27 * This global variable is used as an extension to the nios'
28 * STATUS register to emulate a user/supervisor mode.
29 */
30	.data
31	.align	2
32	.set noat
33
34	.global _current_thread
35_current_thread:
36	.long	0
37/*
38 * Input(s): passed from u-boot
39 *   r4 - Optional pointer to a board information structure.
40 *   r5 - Optional pointer to the physical starting address of the init RAM
41 *        disk.
42 *   r6 - Optional pointer to the physical ending address of the init RAM
43 *        disk.
44 *   r7 - Optional pointer to the physical starting address of any kernel
45 *        command-line parameters.
46 */
47
48/*
49 * First executable code - detected and jumped to by the ROM bootstrap
50 * if the code resides in flash (looks for "Nios" at offset 0x0c from
51 * the potential executable image).
52 */
53	__HEAD
54ENTRY(_start)
55	wrctl	status, r0		/* Disable interrupts */
56
57	/* Initialize all cache lines within the instruction cache */
58	movia	r1, NIOS2_ICACHE_SIZE
59	movui	r2, NIOS2_ICACHE_LINE_SIZE
60
61icache_init:
62	initi	r1
63	sub	r1, r1, r2
64	bgt	r1, r0, icache_init
65	br	1f
66
67	/*
68	 * This is the default location for the exception handler. Code in jump
69	 * to our handler
70	 */
71ENTRY(exception_handler_hook)
72	movia	r24, inthandler
73	jmp	r24
74
75ENTRY(fast_handler)
76	nextpc et
77helper:
78	stw	r3, r3save - helper(et)
79
80	rdctl	r3 , pteaddr
81	srli	r3, r3, 12
82	slli	r3, r3, 2
83	movia	et, pgd_current
84
85	ldw	et, 0(et)
86	add	r3, et, r3
87	ldw	et, 0(r3)
88
89	rdctl	r3, pteaddr
90	andi	r3, r3, 0xfff
91	add	et, r3, et
92	ldw	et, 0(et)
93	wrctl	tlbacc, et
94	nextpc	et
95helper2:
96	ldw	r3, r3save - helper2(et)
97	subi	ea, ea, 4
98	eret
99r3save:
100	.word 0x0
101ENTRY(fast_handler_end)
102
1031:
104	/*
105	 * After the instruction cache is initialized, the data cache must
106	 * also be initialized.
107	 */
108	movia	r1, NIOS2_DCACHE_SIZE
109	movui	r2, NIOS2_DCACHE_LINE_SIZE
110
111dcache_init:
112	initd	0(r1)
113	sub	r1, r1, r2
114	bgt	r1, r0, dcache_init
115
116	nextpc	r1			/* Find out where we are */
117chkadr:
118	movia	r2, chkadr
119	beq	r1, r2,finish_move	/* We are running in RAM done */
120	addi	r1, r1,(_start - chkadr)	/* Source */
121	movia	r2, _start		/* Destination */
122	movia	r3, __bss_start		/* End of copy */
123
124loop_move:				/* r1: src, r2: dest, r3: last dest */
125	ldw	r8, 0(r1)		/* load a word from [r1] */
126	stw	r8, 0(r2)		/* store a word to dest [r2] */
127	flushd	0(r2)			/* Flush cache for safety */
128	addi 	r1, r1, 4		/* inc the src addr */
129	addi	r2, r2, 4		/* inc the dest addr */
130	blt	r2, r3, loop_move
131
132	movia	r1, finish_move		/* VMA(_start)->l1 */
133	jmp	r1			/* jmp to _start */
134
135finish_move:
136
137	/* Mask off all possible interrupts */
138	wrctl	ienable, r0
139
140	/* Clear .bss */
141	movia	r2, __bss_start
142	movia	r1, __bss_stop
1431:
144	stb	r0, 0(r2)
145	addi	r2, r2, 1
146	bne	r1, r2, 1b
147
148	movia	r1, init_thread_union	/* set stack at top of the task union */
149	addi	sp, r1, THREAD_SIZE
150	movia	r2, _current_thread	/* Remember current thread */
151	stw	r1, 0(r2)
152
153	movia	r1, nios2_boot_init	/* save args r4-r7 passed from u-boot */
154	callr	r1
155
156	movia	r1, start_kernel	/* call start_kernel as a subroutine */
157	callr	r1
158
159	/* If we return from start_kernel, break to the oci debugger and
160	 * buggered we are.
161	 */
162	break
163
164	/* End of startup code */
165.set at
166