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