mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	This patch adds the kernel booting and the initial setup code. Signed-off-by: Ley Foon Tan <lftan@altera.com>
		
			
				
	
	
		
			175 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			175 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
/*
 | 
						|
 * Copyright (C) 2009 Wind River Systems Inc
 | 
						|
 *   Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
 | 
						|
 * Copyright (C) 2004 Microtronix Datacom Ltd
 | 
						|
 * Copyright (C) 2001 Vic Phillips, Microtronix Datacom Ltd.
 | 
						|
 *
 | 
						|
 * Based on head.S for Altera's Excalibur development board with nios processor
 | 
						|
 *
 | 
						|
 * Based on the following from the Excalibur sdk distribution:
 | 
						|
 *	NA_MemoryMap.s, NR_JumpToStart.s, NR_Setup.s, NR_CWPManager.s
 | 
						|
 *
 | 
						|
 * This file is subject to the terms and conditions of the GNU General Public
 | 
						|
 * License. See the file "COPYING" in the main directory of this archive
 | 
						|
 * for more details.
 | 
						|
 */
 | 
						|
 | 
						|
#include <linux/init.h>
 | 
						|
#include <linux/linkage.h>
 | 
						|
#include <asm/thread_info.h>
 | 
						|
#include <asm/processor.h>
 | 
						|
#include <asm/cache.h>
 | 
						|
#include <asm/page.h>
 | 
						|
#include <asm/asm-offsets.h>
 | 
						|
#include <asm/asm-macros.h>
 | 
						|
 | 
						|
/*
 | 
						|
 * ZERO_PAGE is a special page that is used for zero-initialized
 | 
						|
 * data and COW.
 | 
						|
 */
 | 
						|
.data
 | 
						|
.global empty_zero_page
 | 
						|
.align 12
 | 
						|
empty_zero_page:
 | 
						|
	.space	PAGE_SIZE
 | 
						|
 | 
						|
/*
 | 
						|
 * This global variable is used as an extension to the nios'
 | 
						|
 * STATUS register to emulate a user/supervisor mode.
 | 
						|
 */
 | 
						|
	.data
 | 
						|
	.align	2
 | 
						|
	.set noat
 | 
						|
 | 
						|
	.global _current_thread
 | 
						|
_current_thread:
 | 
						|
	.long	0
 | 
						|
/*
 | 
						|
 * Input(s): passed from u-boot
 | 
						|
 *   r4 - Optional pointer to a board information structure.
 | 
						|
 *   r5 - Optional pointer to the physical starting address of the init RAM
 | 
						|
 *        disk.
 | 
						|
 *   r6 - Optional pointer to the physical ending address of the init RAM
 | 
						|
 *        disk.
 | 
						|
 *   r7 - Optional pointer to the physical starting address of any kernel
 | 
						|
 *        command-line parameters.
 | 
						|
 */
 | 
						|
 | 
						|
/*
 | 
						|
 * First executable code - detected and jumped to by the ROM bootstrap
 | 
						|
 * if the code resides in flash (looks for "Nios" at offset 0x0c from
 | 
						|
 * the potential executable image).
 | 
						|
 */
 | 
						|
	__HEAD
 | 
						|
ENTRY(_start)
 | 
						|
	wrctl	status, r0		/* Disable interrupts */
 | 
						|
 | 
						|
	/* Initialize all cache lines within the instruction cache */
 | 
						|
	movia	r1, NIOS2_ICACHE_SIZE
 | 
						|
	movui	r2, NIOS2_ICACHE_LINE_SIZE
 | 
						|
 | 
						|
icache_init:
 | 
						|
	initi	r1
 | 
						|
	sub	r1, r1, r2
 | 
						|
	bgt	r1, r0, icache_init
 | 
						|
	br	1f
 | 
						|
 | 
						|
	/*
 | 
						|
	 * This is the default location for the exception handler. Code in jump
 | 
						|
	 * to our handler
 | 
						|
	 */
 | 
						|
ENTRY(exception_handler_hook)
 | 
						|
	movia	r24, inthandler
 | 
						|
	jmp	r24
 | 
						|
 | 
						|
ENTRY(fast_handler)
 | 
						|
	nextpc et
 | 
						|
helper:
 | 
						|
	stw	r3, r3save - helper(et)
 | 
						|
 | 
						|
	rdctl	r3 , pteaddr
 | 
						|
	srli	r3, r3, 12
 | 
						|
	slli	r3, r3, 2
 | 
						|
	movia	et, pgd_current
 | 
						|
 | 
						|
	ldw	et, 0(et)
 | 
						|
	add	r3, et, r3
 | 
						|
	ldw	et, 0(r3)
 | 
						|
 | 
						|
	rdctl	r3, pteaddr
 | 
						|
	andi	r3, r3, 0xfff
 | 
						|
	add	et, r3, et
 | 
						|
	ldw	et, 0(et)
 | 
						|
	wrctl	tlbacc, et
 | 
						|
	nextpc	et
 | 
						|
helper2:
 | 
						|
	ldw	r3, r3save - helper2(et)
 | 
						|
	subi	ea, ea, 4
 | 
						|
	eret
 | 
						|
r3save:
 | 
						|
	.word 0x0
 | 
						|
ENTRY(fast_handler_end)
 | 
						|
 | 
						|
1:
 | 
						|
	/*
 | 
						|
	 * After the instruction cache is initialized, the data cache must
 | 
						|
	 * also be initialized.
 | 
						|
	 */
 | 
						|
	movia	r1, NIOS2_DCACHE_SIZE
 | 
						|
	movui	r2, NIOS2_DCACHE_LINE_SIZE
 | 
						|
 | 
						|
dcache_init:
 | 
						|
	initd	0(r1)
 | 
						|
	sub	r1, r1, r2
 | 
						|
	bgt	r1, r0, dcache_init
 | 
						|
 | 
						|
	nextpc	r1			/* Find out where we are */
 | 
						|
chkadr:
 | 
						|
	movia	r2, chkadr
 | 
						|
	beq	r1, r2,finish_move	/* We are running in RAM done */
 | 
						|
	addi	r1, r1,(_start - chkadr)	/* Source */
 | 
						|
	movia	r2, _start		/* Destination */
 | 
						|
	movia	r3, __bss_start		/* End of copy */
 | 
						|
 | 
						|
loop_move:				/* r1: src, r2: dest, r3: last dest */
 | 
						|
	ldw	r8, 0(r1)		/* load a word from [r1] */
 | 
						|
	stw	r8, 0(r2)		/* store a word to dest [r2] */
 | 
						|
	flushd	0(r2)			/* Flush cache for safety */
 | 
						|
	addi 	r1, r1, 4		/* inc the src addr */
 | 
						|
	addi	r2, r2, 4		/* inc the dest addr */
 | 
						|
	blt	r2, r3, loop_move
 | 
						|
 | 
						|
	movia	r1, finish_move		/* VMA(_start)->l1 */
 | 
						|
	jmp	r1			/* jmp to _start */
 | 
						|
 | 
						|
finish_move:
 | 
						|
 | 
						|
	/* Mask off all possible interrupts */
 | 
						|
	wrctl	ienable, r0
 | 
						|
 | 
						|
	/* Clear .bss */
 | 
						|
	movia	r2, __bss_start
 | 
						|
	movia	r1, __bss_stop
 | 
						|
1:
 | 
						|
	stb	r0, 0(r2)
 | 
						|
	addi	r2, r2, 1
 | 
						|
	bne	r1, r2, 1b
 | 
						|
 | 
						|
	movia	r1, init_thread_union	/* set stack at top of the task union */
 | 
						|
	addi	sp, r1, THREAD_SIZE
 | 
						|
	movia	r2, _current_thread	/* Remember current thread */
 | 
						|
	stw	r1, 0(r2)
 | 
						|
 | 
						|
	movia	r1, nios2_boot_init	/* save args r4-r7 passed from u-boot */
 | 
						|
	callr	r1
 | 
						|
 | 
						|
	movia	r1, start_kernel	/* call start_kernel as a subroutine */
 | 
						|
	callr	r1
 | 
						|
 | 
						|
	/* If we return from start_kernel, break to the oci debugger and
 | 
						|
	 * buggered we are.
 | 
						|
	 */
 | 
						|
	break
 | 
						|
 | 
						|
	/* End of startup code */
 | 
						|
.set at
 |