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