1/* 2 * Copyright (c) 2016 Intel Corporation 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7#include <zephyr/toolchain.h> 8#include <zephyr/linker/sections.h> 9 10/* exports */ 11GTEXT(__start) 12GTEXT(__reset) 13 14/* imports */ 15GTEXT(_PrepC) 16GTEXT(z_interrupt_stacks) 17 18 /* Allow use of r1/at (the assembler temporary register) in this 19 * code, normally reserved for internal assembler use 20 */ 21 .set noat 22 23 24#if CONFIG_INCLUDE_RESET_VECTOR 25/* 26 * Reset vector entry point into the system. Placed into special 'reset' 27 * section so that the linker puts this at ALT_CPU_RESET_ADDR defined in 28 * system.h 29 * 30 * This code can be at most 0x20 bytes, since the exception vector for Nios II 31 * is usually configured to be 0x20 past the reset vector. 32 */ 33SECTION_FUNC(reset, __reset) 34 35#if ALT_CPU_ICACHE_SIZE > 0 36 /* Aside from the instruction cache line associated with the reset 37 * vector, the contents of the cache memories are indeterminate after 38 * reset. To ensure cache coherency after reset, the reset handler 39 * located at the reset vector must immediately initialize the 40 * instruction cache. Next, either the reset handler or a subsequent 41 * routine should proceed to initialize the data cache. 42 * 43 * The cache memory sizes are *always* a power of 2. 44 */ 45#if ALT_CPU_ICACHE_SIZE > 0x8000 46 movhi r2, %hi(ALT_CPU_ICACHE_SIZE) 47#else 48 movui r2, ALT_CPU_ICACHE_SIZE 49#endif 500: 51 /* If ECC present, need to execute initd for each word address 52 * to ensure ECC parity bits in data RAM get initialized 53 */ 54#ifdef ALT_CPU_ECC_PRESENT 55 subi r2, r2, 4 56#else 57 subi r2, r2, ALT_CPU_ICACHE_LINE_SIZE 58#endif 59 initi r2 60 bgt r2, zero, 0b 61#endif /* ALT_CPU_ICACHE_SIZE > 0 */ 62 63 /* Done all we need to do here, jump to __text_start */ 64 movhi r1, %hi(__start) 65 ori r1, r1, %lo(__start) 66 jmp r1 67#endif /* CONFIG_INCLUDE_RESET_VECTOR */ 68 69/* Remainder of asm-land initialization code before we can jump into 70 * the C domain 71 */ 72SECTION_FUNC(TEXT, __start) 73 74 /* TODO if shadow register sets enabled, ensure we are in set 0 75 * GH-1821 76 */ 77 78 /* Initialize the data cache if booting from bare metal. If 79 * we're not booting from our reset vector, either by a bootloader 80 * or JTAG, assume caches already initialized. 81 */ 82#if ALT_CPU_DCACHE_SIZE > 0 && defined(CONFIG_INCLUDE_RESET_VECTOR) 83 /* Per documentation data cache size is always a power of two. */ 84#if ALT_CPU_DCACHE_SIZE > 0x8000 85 movhi r2, %hi(ALT_CPU_DCACHE_SIZE) 86#else 87 movui r2, ALT_CPU_DCACHE_SIZE 88#endif 890: 90 /* If ECC present, need to execute initd for each word address 91 * to ensure ECC parity bits in data RAM get initialized 92 */ 93#ifdef ALT_CPU_ECC_PRESENT 94 subi r2, r2, 4 95#else 96 subi r2, r2, ALT_CPU_DCACHE_LINE_SIZE 97#endif 98 initd 0(r2) 99 bgt r2, zero, 0b 100#endif /* ALT_CPU_DCACHE_SIZE && defined(CONFIG_INCLUDE_RESET_VECTOR) */ 101 102#ifdef CONFIG_INIT_STACKS 103 /* Pre-populate all bytes in z_interrupt_stacks with 0xAA 104 * init.c enforces that the z_interrupt_stacks pointer 105 * and CONFIG_ISR_STACK_SIZE are a multiple of ARCH_STACK_PTR_ALIGN (4) 106 */ 107 movhi r1, %hi(z_interrupt_stacks) 108 ori r1, r1, %lo(z_interrupt_stacks) 109 movhi r2, %hi(CONFIG_ISR_STACK_SIZE) 110 ori r2, r2, %lo(CONFIG_ISR_STACK_SIZE) 111 /* Put constant 0xaaaaaaaa in r3 */ 112 movhi r3, 0xaaaa 113 ori r3, r3, 0xaaaa 1141: 115 /* Loop through the z_interrupt_stacks treating it as an array of 116 * uint32_t, setting each element to r3 */ 117 stw r3, (r1) 118 subi r2, r2, 4 119 addi r1, r1, 4 120 blt r0, r2, 1b 121#endif 122 123 /* Set up the initial stack pointer to the interrupt stack, safe 124 * to use this as the CPU boots up with interrupts disabled and we 125 * don't turn them on until much later, when the kernel is on 126 * the main stack */ 127 movhi sp, %hi(z_interrupt_stacks) 128 ori sp, sp, %lo(z_interrupt_stacks) 129 addi sp, sp, CONFIG_ISR_STACK_SIZE 130 131#if defined(CONFIG_GP_LOCAL) || defined(CONFIG_GP_GLOBAL) || \ 132 defined(CONFIG_GP_ALL_DATA) 133 /* Initialize global pointer with the linker variable we set */ 134 movhi gp, %hi(_gp) 135 ori gp, gp, %lo(_gp) 136#endif 137 138 /* TODO if shadow register sets enabled, interate through them to set 139 * up. Need to clear r0, write gp, set the exception stack pointer 140 * GH-1821 141 */ 142 143 /* Jump into C domain. _PrepC zeroes BSS, copies rw data into RAM, 144 * and then enters z_cstart */ 145 call _PrepC 146 147