xref: /openbmc/linux/arch/nios2/kernel/head.S (revision 27d22413)
127d22413SLey Foon Tan/*
227d22413SLey Foon Tan * Copyright (C) 2009 Wind River Systems Inc
327d22413SLey Foon Tan *   Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
427d22413SLey Foon Tan * Copyright (C) 2004 Microtronix Datacom Ltd
527d22413SLey Foon Tan * Copyright (C) 2001 Vic Phillips, Microtronix Datacom Ltd.
627d22413SLey Foon Tan *
727d22413SLey Foon Tan * Based on head.S for Altera's Excalibur development board with nios processor
827d22413SLey Foon Tan *
927d22413SLey Foon Tan * Based on the following from the Excalibur sdk distribution:
1027d22413SLey Foon Tan *	NA_MemoryMap.s, NR_JumpToStart.s, NR_Setup.s, NR_CWPManager.s
1127d22413SLey Foon Tan *
1227d22413SLey Foon Tan * This file is subject to the terms and conditions of the GNU General Public
1327d22413SLey Foon Tan * License. See the file "COPYING" in the main directory of this archive
1427d22413SLey Foon Tan * for more details.
1527d22413SLey Foon Tan */
1627d22413SLey Foon Tan
1727d22413SLey Foon Tan#include <linux/init.h>
1827d22413SLey Foon Tan#include <linux/linkage.h>
1927d22413SLey Foon Tan#include <asm/thread_info.h>
2027d22413SLey Foon Tan#include <asm/processor.h>
2127d22413SLey Foon Tan#include <asm/cache.h>
2227d22413SLey Foon Tan#include <asm/page.h>
2327d22413SLey Foon Tan#include <asm/asm-offsets.h>
2427d22413SLey Foon Tan#include <asm/asm-macros.h>
2527d22413SLey Foon Tan
2627d22413SLey Foon Tan/*
2727d22413SLey Foon Tan * ZERO_PAGE is a special page that is used for zero-initialized
2827d22413SLey Foon Tan * data and COW.
2927d22413SLey Foon Tan */
3027d22413SLey Foon Tan.data
3127d22413SLey Foon Tan.global empty_zero_page
3227d22413SLey Foon Tan.align 12
3327d22413SLey Foon Tanempty_zero_page:
3427d22413SLey Foon Tan	.space	PAGE_SIZE
3527d22413SLey Foon Tan
3627d22413SLey Foon Tan/*
3727d22413SLey Foon Tan * This global variable is used as an extension to the nios'
3827d22413SLey Foon Tan * STATUS register to emulate a user/supervisor mode.
3927d22413SLey Foon Tan */
4027d22413SLey Foon Tan	.data
4127d22413SLey Foon Tan	.align	2
4227d22413SLey Foon Tan	.set noat
4327d22413SLey Foon Tan
4427d22413SLey Foon Tan	.global _current_thread
4527d22413SLey Foon Tan_current_thread:
4627d22413SLey Foon Tan	.long	0
4727d22413SLey Foon Tan/*
4827d22413SLey Foon Tan * Input(s): passed from u-boot
4927d22413SLey Foon Tan *   r4 - Optional pointer to a board information structure.
5027d22413SLey Foon Tan *   r5 - Optional pointer to the physical starting address of the init RAM
5127d22413SLey Foon Tan *        disk.
5227d22413SLey Foon Tan *   r6 - Optional pointer to the physical ending address of the init RAM
5327d22413SLey Foon Tan *        disk.
5427d22413SLey Foon Tan *   r7 - Optional pointer to the physical starting address of any kernel
5527d22413SLey Foon Tan *        command-line parameters.
5627d22413SLey Foon Tan */
5727d22413SLey Foon Tan
5827d22413SLey Foon Tan/*
5927d22413SLey Foon Tan * First executable code - detected and jumped to by the ROM bootstrap
6027d22413SLey Foon Tan * if the code resides in flash (looks for "Nios" at offset 0x0c from
6127d22413SLey Foon Tan * the potential executable image).
6227d22413SLey Foon Tan */
6327d22413SLey Foon Tan	__HEAD
6427d22413SLey Foon TanENTRY(_start)
6527d22413SLey Foon Tan	wrctl	status, r0		/* Disable interrupts */
6627d22413SLey Foon Tan
6727d22413SLey Foon Tan	/* Initialize all cache lines within the instruction cache */
6827d22413SLey Foon Tan	movia	r1, NIOS2_ICACHE_SIZE
6927d22413SLey Foon Tan	movui	r2, NIOS2_ICACHE_LINE_SIZE
7027d22413SLey Foon Tan
7127d22413SLey Foon Tanicache_init:
7227d22413SLey Foon Tan	initi	r1
7327d22413SLey Foon Tan	sub	r1, r1, r2
7427d22413SLey Foon Tan	bgt	r1, r0, icache_init
7527d22413SLey Foon Tan	br	1f
7627d22413SLey Foon Tan
7727d22413SLey Foon Tan	/*
7827d22413SLey Foon Tan	 * This is the default location for the exception handler. Code in jump
7927d22413SLey Foon Tan	 * to our handler
8027d22413SLey Foon Tan	 */
8127d22413SLey Foon TanENTRY(exception_handler_hook)
8227d22413SLey Foon Tan	movia	r24, inthandler
8327d22413SLey Foon Tan	jmp	r24
8427d22413SLey Foon Tan
8527d22413SLey Foon TanENTRY(fast_handler)
8627d22413SLey Foon Tan	nextpc et
8727d22413SLey Foon Tanhelper:
8827d22413SLey Foon Tan	stw	r3, r3save - helper(et)
8927d22413SLey Foon Tan
9027d22413SLey Foon Tan	rdctl	r3 , pteaddr
9127d22413SLey Foon Tan	srli	r3, r3, 12
9227d22413SLey Foon Tan	slli	r3, r3, 2
9327d22413SLey Foon Tan	movia	et, pgd_current
9427d22413SLey Foon Tan
9527d22413SLey Foon Tan	ldw	et, 0(et)
9627d22413SLey Foon Tan	add	r3, et, r3
9727d22413SLey Foon Tan	ldw	et, 0(r3)
9827d22413SLey Foon Tan
9927d22413SLey Foon Tan	rdctl	r3, pteaddr
10027d22413SLey Foon Tan	andi	r3, r3, 0xfff
10127d22413SLey Foon Tan	add	et, r3, et
10227d22413SLey Foon Tan	ldw	et, 0(et)
10327d22413SLey Foon Tan	wrctl	tlbacc, et
10427d22413SLey Foon Tan	nextpc	et
10527d22413SLey Foon Tanhelper2:
10627d22413SLey Foon Tan	ldw	r3, r3save - helper2(et)
10727d22413SLey Foon Tan	subi	ea, ea, 4
10827d22413SLey Foon Tan	eret
10927d22413SLey Foon Tanr3save:
11027d22413SLey Foon Tan	.word 0x0
11127d22413SLey Foon TanENTRY(fast_handler_end)
11227d22413SLey Foon Tan
11327d22413SLey Foon Tan1:
11427d22413SLey Foon Tan	/*
11527d22413SLey Foon Tan	 * After the instruction cache is initialized, the data cache must
11627d22413SLey Foon Tan	 * also be initialized.
11727d22413SLey Foon Tan	 */
11827d22413SLey Foon Tan	movia	r1, NIOS2_DCACHE_SIZE
11927d22413SLey Foon Tan	movui	r2, NIOS2_DCACHE_LINE_SIZE
12027d22413SLey Foon Tan
12127d22413SLey Foon Tandcache_init:
12227d22413SLey Foon Tan	initd	0(r1)
12327d22413SLey Foon Tan	sub	r1, r1, r2
12427d22413SLey Foon Tan	bgt	r1, r0, dcache_init
12527d22413SLey Foon Tan
12627d22413SLey Foon Tan	nextpc	r1			/* Find out where we are */
12727d22413SLey Foon Tanchkadr:
12827d22413SLey Foon Tan	movia	r2, chkadr
12927d22413SLey Foon Tan	beq	r1, r2,finish_move	/* We are running in RAM done */
13027d22413SLey Foon Tan	addi	r1, r1,(_start - chkadr)	/* Source */
13127d22413SLey Foon Tan	movia	r2, _start		/* Destination */
13227d22413SLey Foon Tan	movia	r3, __bss_start		/* End of copy */
13327d22413SLey Foon Tan
13427d22413SLey Foon Tanloop_move:				/* r1: src, r2: dest, r3: last dest */
13527d22413SLey Foon Tan	ldw	r8, 0(r1)		/* load a word from [r1] */
13627d22413SLey Foon Tan	stw	r8, 0(r2)		/* store a word to dest [r2] */
13727d22413SLey Foon Tan	flushd	0(r2)			/* Flush cache for safety */
13827d22413SLey Foon Tan	addi 	r1, r1, 4		/* inc the src addr */
13927d22413SLey Foon Tan	addi	r2, r2, 4		/* inc the dest addr */
14027d22413SLey Foon Tan	blt	r2, r3, loop_move
14127d22413SLey Foon Tan
14227d22413SLey Foon Tan	movia	r1, finish_move		/* VMA(_start)->l1 */
14327d22413SLey Foon Tan	jmp	r1			/* jmp to _start */
14427d22413SLey Foon Tan
14527d22413SLey Foon Tanfinish_move:
14627d22413SLey Foon Tan
14727d22413SLey Foon Tan	/* Mask off all possible interrupts */
14827d22413SLey Foon Tan	wrctl	ienable, r0
14927d22413SLey Foon Tan
15027d22413SLey Foon Tan	/* Clear .bss */
15127d22413SLey Foon Tan	movia	r2, __bss_start
15227d22413SLey Foon Tan	movia	r1, __bss_stop
15327d22413SLey Foon Tan1:
15427d22413SLey Foon Tan	stb	r0, 0(r2)
15527d22413SLey Foon Tan	addi	r2, r2, 1
15627d22413SLey Foon Tan	bne	r1, r2, 1b
15727d22413SLey Foon Tan
15827d22413SLey Foon Tan	movia	r1, init_thread_union	/* set stack at top of the task union */
15927d22413SLey Foon Tan	addi	sp, r1, THREAD_SIZE
16027d22413SLey Foon Tan	movia	r2, _current_thread	/* Remember current thread */
16127d22413SLey Foon Tan	stw	r1, 0(r2)
16227d22413SLey Foon Tan
16327d22413SLey Foon Tan	movia	r1, nios2_boot_init	/* save args r4-r7 passed from u-boot */
16427d22413SLey Foon Tan	callr	r1
16527d22413SLey Foon Tan
16627d22413SLey Foon Tan	movia	r1, start_kernel	/* call start_kernel as a subroutine */
16727d22413SLey Foon Tan	callr	r1
16827d22413SLey Foon Tan
16927d22413SLey Foon Tan	/* If we return from start_kernel, break to the oci debugger and
17027d22413SLey Foon Tan	 * buggered we are.
17127d22413SLey Foon Tan	 */
17227d22413SLey Foon Tan	break
17327d22413SLey Foon Tan
17427d22413SLey Foon Tan	/* End of startup code */
17527d22413SLey Foon Tan.set at
176