123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- /*
- * 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
|