nios2: Kernel booting and initialization
This patch adds the kernel booting and the initial setup code. Signed-off-by: Ley Foon Tan <lftan@altera.com>
This commit is contained in:
175
arch/nios2/kernel/head.S
Normal file
175
arch/nios2/kernel/head.S
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* 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
|
Reference in New Issue
Block a user