1;/*************************************************************************** 2; * Copyright (c) 2024 Microsoft Corporation 3; * 4; * This program and the accompanying materials are made available under the 5; * terms of the MIT License which is available at 6; * https://opensource.org/licenses/MIT. 7; * 8; * SPDX-License-Identifier: MIT 9; **************************************************************************/ 10; 11; 12;/**************************************************************************/ 13;/**************************************************************************/ 14;/** */ 15;/** ThreadX Component */ 16;/** */ 17;/** Initialize */ 18;/** */ 19;/**************************************************************************/ 20;/**************************************************************************/ 21; 22; 23;#define TX_SOURCE_CODE 24; 25; 26;/* Include necessary system files. */ 27; 28;#include "tx_api.h" 29;#include "tx_initialize.h" 30;#include "tx_thread.h" 31;#include "tx_timer.h" 32; 33; 34SVC_MODE DEFINE 0xD3 ; Disable irq,fiq SVC mode 35IRQ_MODE DEFINE 0xD2 ; Disable irq,fiq IRQ mode 36FIQ_MODE DEFINE 0xD1 ; Disable irq,fiq FIQ mode 37SYS_MODE DEFINE 0xDF ; Disable irq,fiq SYS mode 38; 39; 40 41 EXTERN _tx_thread_system_stack_ptr 42 EXTERN _tx_initialize_unused_memory 43 EXTERN _tx_thread_context_save 44; EXTERN _tx_thread_vectored_context_save 45 EXTERN _tx_thread_context_restore 46#ifdef TX_ENABLE_FIQ_SUPPORT 47 EXTERN _tx_thread_fiq_context_save 48 EXTERN _tx_thread_fiq_context_restore 49#endif 50#ifdef TX_ENABLE_IRQ_NESTING 51 EXTERN _tx_thread_irq_nesting_start 52 EXTERN _tx_thread_irq_nesting_end 53#endif 54#ifdef TX_ENABLE_FIQ_NESTING 55 EXTERN _tx_thread_fiq_nesting_start 56 EXTERN _tx_thread_fiq_nesting_end 57#endif 58 EXTERN _tx_timer_interrupt 59 EXTERN ?cstartup 60 EXTERN _tx_build_options 61 EXTERN _tx_version_id 62; 63; 64; 65;/* Define the FREE_MEM segment that will specify where free memory is 66; defined. This must also be located in at the end of other RAM segments 67; in the linker control file. The value of this segment is what is passed 68; to tx_application_define. */ 69; 70 RSEG FREE_MEM:DATA 71 PUBLIC __tx_free_memory_start 72__tx_free_memory_start 73 DS32 4 74; 75; 76; 77; 78;/**************************************************************************/ 79;/* */ 80;/* FUNCTION RELEASE */ 81;/* */ 82;/* _tx_initialize_low_level ARM11/IAR */ 83;/* 6.1 */ 84;/* AUTHOR */ 85;/* */ 86;/* William E. Lamie, Microsoft Corporation */ 87;/* */ 88;/* DESCRIPTION */ 89;/* */ 90;/* This function is responsible for any low-level processor */ 91;/* initialization, including setting up interrupt vectors, setting */ 92;/* up a periodic timer interrupt source, saving the system stack */ 93;/* pointer for use in ISR processing later, and finding the first */ 94;/* available RAM memory address for tx_application_define. */ 95;/* */ 96;/* INPUT */ 97;/* */ 98;/* None */ 99;/* */ 100;/* OUTPUT */ 101;/* */ 102;/* None */ 103;/* */ 104;/* CALLS */ 105;/* */ 106;/* None */ 107;/* */ 108;/* CALLED BY */ 109;/* */ 110;/* _tx_initialize_kernel_enter ThreadX entry function */ 111;/* */ 112;/* RELEASE HISTORY */ 113;/* */ 114;/* DATE NAME DESCRIPTION */ 115;/* */ 116;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ 117;/* */ 118;/**************************************************************************/ 119;VOID _tx_initialize_low_level(VOID) 120;{ 121 RSEG .text:CODE:NOROOT(2) 122 CODE32 123 PUBLIC _tx_initialize_low_level 124_tx_initialize_low_level 125; 126; /****** NOTE ****** The IAR 4.11a and above releases call main in SYS mode. */ 127; 128; /* Remember the stack pointer, link register, and switch to SVC mode. */ 129; 130 MOV r0, sp ; Remember the SP 131 MOV r1, lr ; Remember the LR 132 MOV r3, #SVC_MODE ; Build SVC mode CPSR 133 MSR CPSR_cxsf, r3 ; Switch to SVC mode 134 MOV sp, r0 ; Inherit the stack pointer setup by cstartup 135 MOV lr, r1 ; Inherit the link register 136; 137; /* Pickup the start of free memory. */ 138; 139 LDR r0, =__tx_free_memory_start ; Get end of non-initialized RAM area 140; 141; /* Save the system stack pointer. */ 142; _tx_thread_system_stack_ptr = (VOID_PTR) (sp); 143; 144; /* Save the first available memory address. */ 145; _tx_initialize_unused_memory = (VOID_PTR) FREE_MEM; 146; 147 LDR r2, =_tx_initialize_unused_memory ; Pickup unused memory ptr address 148 STR r0, [r2, #0] ; Save first free memory address 149; 150; /* Setup Timer for periodic interrupts. */ 151; 152; /* Done, return to caller. */ 153; 154#ifdef TX_THUMB 155 BX lr ; Return to caller 156#else 157 MOV pc, lr ; Return to caller 158#endif 159;} 160; 161;/* Define shells for each of the interrupt vectors. */ 162; 163 RSEG .text:CODE:NOROOT(2) 164 PUBLIC __tx_undefined 165__tx_undefined 166 B __tx_undefined ; Undefined handler 167; 168 RSEG .text:CODE:NOROOT(2) 169 PUBLIC __tx_swi_interrupt 170__tx_swi_interrupt 171 B __tx_swi_interrupt ; Software interrupt handler 172; 173 RSEG .text:CODE:NOROOT(2) 174 PUBLIC __tx_prefetch_handler 175__tx_prefetch_handler 176 B __tx_prefetch_handler ; Prefetch exception handler 177; 178 RSEG .text:CODE:NOROOT(2) 179 PUBLIC __tx_abort_handler 180__tx_abort_handler 181 B __tx_abort_handler ; Abort exception handler 182; 183 RSEG .text:CODE:NOROOT(2) 184 PUBLIC __tx_reserved_handler 185__tx_reserved_handler 186 B __tx_reserved_handler ; Reserved exception handler 187; 188 RSEG .text:CODE:NOROOT(2) 189 PUBLIC __tx_irq_handler 190 RSEG .text:CODE:NOROOT(2) 191 PUBLIC __tx_irq_processing_return 192__tx_irq_handler 193; 194; /* Jump to context save to save system context. */ 195 B _tx_thread_context_save 196__tx_irq_processing_return 197; 198; /* At this point execution is still in the IRQ mode. The CPSR, point of 199; interrupt, and all C scratch registers are available for use. In 200; addition, IRQ interrupts may be re-enabled - with certain restrictions - 201; if nested IRQ interrupts are desired. Interrupts may be re-enabled over 202; small code sequences where lr is saved before enabling interrupts and 203; restored after interrupts are again disabled. */ 204; 205; /* Interrupt nesting is allowed after calling _tx_thread_irq_nesting_start 206; from IRQ mode with interrupts disabled. This routine switches to the 207; system mode and returns with IRQ interrupts enabled. 208; 209; NOTE: It is very important to ensure all IRQ interrupts are cleared 210; prior to enabling nested IRQ interrupts. */ 211#ifdef TX_ENABLE_IRQ_NESTING 212 BL _tx_thread_irq_nesting_start 213#endif 214; 215; /* For debug purpose, execute the timer interrupt processing here. In 216; a real system, some kind of status indication would have to be checked 217; before the timer interrupt handler could be called. */ 218; 219 BL _tx_timer_interrupt ; Timer interrupt handler 220; 221; /* Application IRQ handlers can be called here! */ 222; 223; /* If interrupt nesting was started earlier, the end of interrupt nesting 224; service must be called before returning to _tx_thread_context_restore. 225; This routine returns in processing in IRQ mode with interrupts disabled. */ 226#ifdef TX_ENABLE_IRQ_NESTING 227 BL _tx_thread_irq_nesting_end 228#endif 229; 230; /* Jump to context restore to restore system context. */ 231 B _tx_thread_context_restore 232; 233; 234; /* This is an example of a vectored IRQ handler. */ 235; 236; RSEG .text:CODE:NOROOT(2) 237; PUBLIC __tx_example_vectored_irq_handler 238;__tx_example_vectored_irq_handler 239; 240; /* Jump to context save to save system context. */ 241; STMDB sp!, {r0-r3} ; Save some scratch registers 242; MRS r0, SPSR ; Pickup saved SPSR 243; SUB lr, lr, #4 ; Adjust point of interrupt 244; STMDB sp!, {r0, r10, r12, lr} ; Store other registers 245; BL _tx_thread_vectored_context_save 246; 247; /* At this point execution is still in the IRQ mode. The CPSR, point of 248; interrupt, and all C scratch registers are available for use. In 249; addition, IRQ interrupts may be re-enabled - with certain restrictions - 250; if nested IRQ interrupts are desired. Interrupts may be re-enabled over 251; small code sequences where lr is saved before enabling interrupts and 252; restored after interrupts are again disabled. */ 253; 254; /* Interrupt nesting is allowed after calling _tx_thread_irq_nesting_start 255; from IRQ mode with interrupts disabled. This routine switches to the 256; system mode and returns with IRQ interrupts enabled. 257; 258; NOTE: It is very important to ensure all IRQ interrupts are cleared 259; prior to enabling nested IRQ interrupts. */ 260;#ifdef TX_ENABLE_IRQ_NESTING 261; BL _tx_thread_irq_nesting_start 262;#endif 263; 264; /* Application IRQ handler is called here! */ 265; 266; /* If interrupt nesting was started earlier, the end of interrupt nesting 267; service must be called before returning to _tx_thread_context_restore. 268; This routine returns in processing in IRQ mode with interrupts disabled. */ 269;#ifdef TX_ENABLE_IRQ_NESTING 270; BL _tx_thread_irq_nesting_end 271;#endif 272; 273; /* Jump to context restore to restore system context. */ 274; B _tx_thread_context_restore 275; 276; 277#ifdef TX_ENABLE_FIQ_SUPPORT 278 RSEG .text:CODE:NOROOT(2) 279 PUBLIC __tx_fiq_handler 280 RSEG .text:CODE:NOROOT(2) 281 PUBLIC __tx_fiq_processing_return 282__tx_fiq_handler 283; 284; /* Jump to fiq context save to save system context. */ 285 B _tx_thread_fiq_context_save 286__tx_fiq_processing_return 287; 288; /* At this point execution is still in the FIQ mode. The CPSR, point of 289; interrupt, and all C scratch registers are available for use. */ 290; 291; /* Interrupt nesting is allowed after calling _tx_thread_fiq_nesting_start 292; from FIQ mode with interrupts disabled. This routine switches to the 293; system mode and returns with FIQ interrupts enabled. 294; 295; NOTE: It is very important to ensure all FIQ interrupts are cleared 296; prior to enabling nested FIQ interrupts. */ 297#ifdef TX_ENABLE_FIQ_NESTING 298 BL _tx_thread_fiq_nesting_start 299#endif 300; 301; /* Application FIQ handlers can be called here! */ 302; 303; /* If interrupt nesting was started earlier, the end of interrupt nesting 304; service must be called before returning to _tx_thread_fiq_context_restore. */ 305#ifdef TX_ENABLE_FIQ_NESTING 306 BL _tx_thread_fiq_nesting_end 307#endif 308; 309; /* Jump to fiq context restore to restore system context. */ 310 B _tx_thread_fiq_context_restore 311; 312; 313#else 314 RSEG .text:CODE:NOROOT(2) 315 PUBLIC __tx_fiq_handler 316__tx_fiq_handler 317 B __tx_fiq_handler ; FIQ interrupt handler 318#endif 319; 320; 321BUILD_OPTIONS 322 DC32 _tx_build_options ; Reference to ensure it comes in 323VERSION_ID 324 DC32 _tx_version_id ; Reference to ensure it comes in 325 END 326 327