1/* 2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7#include "pico.h" 8#include "pico/asm_helper.S" 9 10#include "hardware/regs/m0plus.h" 11#include "hardware/regs/addressmap.h" 12#include "hardware/regs/sio.h" 13#include "pico/binary_info/defs.h" 14 15#ifdef NDEBUG 16#ifndef COLLAPSE_IRQS 17#define COLLAPSE_IRQS 18#endif 19#endif 20 21pico_default_asm_setup 22 23.section .vectors, "ax" 24.align 2 25 26.global __vectors, __VECTOR_TABLE 27__VECTOR_TABLE: 28__vectors: 29.word __StackTop 30.word _reset_handler 31.word isr_nmi 32.word isr_hardfault 33.word isr_invalid // Reserved, should never fire 34.word isr_invalid // Reserved, should never fire 35.word isr_invalid // Reserved, should never fire 36.word isr_invalid // Reserved, should never fire 37.word isr_invalid // Reserved, should never fire 38.word isr_invalid // Reserved, should never fire 39.word isr_invalid // Reserved, should never fire 40.word isr_svcall 41.word isr_invalid // Reserved, should never fire 42.word isr_invalid // Reserved, should never fire 43.word isr_pendsv 44.word isr_systick 45.word isr_irq0 46.word isr_irq1 47.word isr_irq2 48.word isr_irq3 49.word isr_irq4 50.word isr_irq5 51.word isr_irq6 52.word isr_irq7 53.word isr_irq8 54.word isr_irq9 55.word isr_irq10 56.word isr_irq11 57.word isr_irq12 58.word isr_irq13 59.word isr_irq14 60.word isr_irq15 61.word isr_irq16 62.word isr_irq17 63.word isr_irq18 64.word isr_irq19 65.word isr_irq20 66.word isr_irq21 67.word isr_irq22 68.word isr_irq23 69.word isr_irq24 70.word isr_irq25 71.word isr_irq26 72.word isr_irq27 73.word isr_irq28 74.word isr_irq29 75.word isr_irq30 76.word isr_irq31 77 78// all default exception handlers do nothing, and we can check for them being set to our 79// default values by seeing if they point to somewhere between __defaults_isrs_start and __default_isrs_end 80.global __default_isrs_start 81__default_isrs_start: 82 83// Declare a weak symbol for each ISR. 84// By default, they will fall through to the undefined IRQ handler below (breakpoint), 85// but can be overridden by C functions with correct name. 86 87.macro decl_isr_bkpt name 88.weak \name 89.type \name,%function 90.thumb_func 91\name: 92 bkpt #0 93.endm 94 95// these are separated out for clarity 96decl_isr_bkpt isr_invalid 97decl_isr_bkpt isr_nmi 98decl_isr_bkpt isr_hardfault 99decl_isr_bkpt isr_svcall 100decl_isr_bkpt isr_pendsv 101decl_isr_bkpt isr_systick 102 103.global __default_isrs_end 104__default_isrs_end: 105 106.macro decl_isr name 107.weak \name 108.type \name,%function 109.thumb_func 110\name: 111.endm 112 113decl_isr isr_irq0 114decl_isr isr_irq1 115decl_isr isr_irq2 116decl_isr isr_irq3 117decl_isr isr_irq4 118decl_isr isr_irq5 119decl_isr isr_irq6 120decl_isr isr_irq7 121decl_isr isr_irq8 122decl_isr isr_irq9 123decl_isr isr_irq10 124decl_isr isr_irq11 125decl_isr isr_irq12 126decl_isr isr_irq13 127decl_isr isr_irq14 128decl_isr isr_irq15 129decl_isr isr_irq16 130decl_isr isr_irq17 131decl_isr isr_irq18 132decl_isr isr_irq19 133decl_isr isr_irq20 134decl_isr isr_irq21 135decl_isr isr_irq22 136decl_isr isr_irq23 137decl_isr isr_irq24 138decl_isr isr_irq25 139decl_isr isr_irq26 140decl_isr isr_irq27 141decl_isr isr_irq28 142decl_isr isr_irq29 143decl_isr isr_irq30 144decl_isr isr_irq31 145 146// All unhandled USER IRQs fall through to here 147.global __unhandled_user_irq 148.thumb_func 149__unhandled_user_irq: 150 mrs r0, ipsr 151 subs r0, #16 152.global unhandled_user_irq_num_in_r0 153unhandled_user_irq_num_in_r0: 154 bkpt #0 155 156// ---------------------------------------------------------------------------- 157 158.section .binary_info_header, "a" 159 160// Header must be in first 256 bytes of main image (i.e. excluding flash boot2). 161// For flash builds we put it immediately after vector table; for NO_FLASH the 162// vectors are at a +0x100 offset because the bootrom enters RAM images directly 163// at their lowest address, so we put the header in the VTOR alignment hole. 164 165#if !PICO_NO_BINARY_INFO 166binary_info_header: 167.word BINARY_INFO_MARKER_START 168.word __binary_info_start 169.word __binary_info_end 170.word data_cpy_table // we may need to decode pointers that are in RAM at runtime. 171.word BINARY_INFO_MARKER_END 172#endif 173 174// ---------------------------------------------------------------------------- 175 176.section .reset, "ax" 177 178// On flash builds, the vector table comes first in the image (conventional). 179// On NO_FLASH builds, the reset handler section comes first, as the entry 180// point is at offset 0 (fixed due to bootrom), and VTOR is highly-aligned. 181// Image is entered in various ways: 182// 183// - NO_FLASH builds are entered from beginning by UF2 bootloader 184// 185// - Flash builds vector through the table into _reset_handler from boot2 186// 187// - Either type can be entered via _entry_point by the debugger, and flash builds 188// must then be sent back round the boot sequence to properly initialise flash 189 190// ELF entry point: 191.type _entry_point,%function 192.thumb_func 193.global _entry_point 194_entry_point: 195 196#if PICO_NO_FLASH 197 // Vector through our own table (SP, VTOR will not have been set up at 198 // this point). Same path for debugger entry and bootloader entry. 199 ldr r0, =__vectors 200#else 201 // Debugger tried to run code after loading, so SSI is in 03h-only mode. 202 // Go back through bootrom + boot2 to properly initialise flash. 203 movs r0, #0 204#endif 205 ldr r1, =(PPB_BASE + M0PLUS_VTOR_OFFSET) 206 str r0, [r1] 207 ldmia r0!, {r1, r2} 208 msr msp, r1 209 bx r2 210 211// Reset handler: 212// - initialises .data 213// - clears .bss 214// - calls runtime_init 215// - calls main 216// - calls exit (which should eventually hang the processor via _exit) 217 218.type _reset_handler,%function 219.thumb_func 220_reset_handler: 221 // Only core 0 should run the C runtime startup code; core 1 is normally 222 // sleeping in the bootrom at this point but check to be sure 223 ldr r0, =(SIO_BASE + SIO_CPUID_OFFSET) 224 ldr r0, [r0] 225 cmp r0, #0 226 bne hold_non_core0_in_bootrom 227 228 // In a NO_FLASH binary, don't perform .data copy, since it's loaded 229 // in-place by the SRAM load. Still need to clear .bss 230#if !PICO_NO_FLASH 231 adr r4, data_cpy_table 232 233 // assume there is at least one entry 2341: 235 ldmia r4!, {r1-r3} 236 cmp r1, #0 237 beq 2f 238 bl data_cpy 239 b 1b 2402: 241#endif 242 243 // Zero out the BSS 244 ldr r1, =__bss_start__ 245 ldr r2, =__bss_end__ 246 movs r0, #0 247 b bss_fill_test 248bss_fill_loop: 249 stm r1!, {r0} 250bss_fill_test: 251 cmp r1, r2 252 bne bss_fill_loop 253 254platform_entry: // symbol for stack traces 255 // Use 32-bit jumps, in case these symbols are moved out of branch range 256 // (e.g. if main is in SRAM and crt0 in flash) 257 ldr r1, =runtime_init 258 blx r1 259 ldr r1, =main 260 blx r1 261 ldr r1, =exit 262 blx r1 263 // exit should not return. If it does, hang the core. 264 // (fall thru into our hang _exit impl 2651: // separate label because _exit can be moved out of branch range 266 bkpt #0 267 b 1b 268 269#if !PICO_NO_FLASH 270data_cpy_loop: 271 ldm r1!, {r0} 272 stm r2!, {r0} 273data_cpy: 274 cmp r2, r3 275 blo data_cpy_loop 276 bx lr 277#endif 278 279// Note the data copy table is still included for NO_FLASH builds, even though 280// we skip the copy, because it is listed in binary info 281 282.align 2 283data_cpy_table: 284#if PICO_COPY_TO_RAM 285.word __ram_text_source__ 286.word __ram_text_start__ 287.word __ram_text_end__ 288#endif 289.word __etext 290.word __data_start__ 291.word __data_end__ 292 293.word __scratch_x_source__ 294.word __scratch_x_start__ 295.word __scratch_x_end__ 296 297.word __scratch_y_source__ 298.word __scratch_y_start__ 299.word __scratch_y_end__ 300 301.word 0 // null terminator 302 303// ---------------------------------------------------------------------------- 304// Provide safe defaults for _exit and runtime_init 305// Full implementations usually provided by platform.c 306 307.weak runtime_init 308.type runtime_init,%function 309.thumb_func 310runtime_init: 311 bx lr 312 313// ---------------------------------------------------------------------------- 314// If core 1 somehow gets into crt0 due to a spectacular VTOR mishap, we need to 315// catch it and send back to the sleep-and-launch code in the bootrom. Shouldn't 316// happen (it should sleep in the ROM until given an entry point via the 317// cross-core FIFOs) but it's good to be defensive. 318 319hold_non_core0_in_bootrom: 320 ldr r0, = 'W' | ('V' << 8) 321 bl rom_func_lookup 322 bx r0 323 324// ---------------------------------------------------------------------------- 325// Stack/heap dummies to set size 326 327// Prior to SDK 1.5.1 these were `.section .stack` without the `, "a"`... Clang linker gives a warning about this, 328// however setting it explicitly to `, "a"` makes GCC *now* discard the section unless it is also KEEP. This 329// seems like very surprising behavior! 330// 331// Strictly the most correct thing to do (as .stack and .heap are unreferenced) is to mark them as "a", and also KEEP, which 332// works correctly for both GCC and Clang, however doing so may break anyone who already has custom linker scripts without 333// the KEEP. Therefore we will only add the "a" on Clang, but will also use KEEP to our own linker scripts. 334 335.macro spacer_section name 336#if PICO_ASSEMBLER_IS_CLANG 337.section \name, "a" 338#else 339.section \name 340#endif 341.endm 342 343spacer_section .stack 344// align to allow for memory protection (although this alignment is pretty much ignored by linker script) 345.p2align 5 346 .equ StackSize, PICO_STACK_SIZE 347.space StackSize 348 349spacer_section .heap 350.p2align 2 351 .equ HeapSize, PICO_HEAP_SIZE 352.space HeapSize 353