// This file contains the interrupt table for the ADSP-2136x // When the C program exits either by returning from main() or by an // explicit or implicit call to exit(), control will transfer to the // label ___lib_prog_term. Currently, the ___lib_prog_term label is // defined at the end of the reset vector as an IDLE instruction. // If your application needs to perform some operation AFTER the C // program has finished executing, remove the ___lib_prog_term label // from the runtime header, and place it at the beginning of your // code. /************************************************************************** Changes made January 2001. The run-time model states that i0 can't be used in the run-time libs. Use i2 for interrupt handling instead. **************************************************************************/ .file_attr libGroup="crt"; .file_attr libName="libc"; .file_attr libFunc="___lib_prog_term"; .file_attr FuncName="___lib_prog_term"; #if defined(_ADI_THREADS) .file_attr libFunc="___lib_start"; .file_attr FuncName="___lib_start"; #endif .file_attr prefersMem="any"; .file_attr prefersMemNum="50"; #include "sig_glob.h" #include "lib_glob.h" .extern ___lib_int_table; .extern _main; #ifdef ARGV_SUPPORT .extern __getargv; .extern __Argv; #endif #ifdef __cplusplus .EXTERN _atexit; .EXTERN ___process_needed_destructions__Fv; .EXTERN __ctors; // CPP: this id is defined in ldf file // which points to start of seg_ctdm section .EXTERN __ctorsize; .SEGMENT/DM .gdt; .GLOBAL ___eh_gdt; .VAR ___eh_gdt[1]; .SEGMENT/DM .frt; .GLOBAL ___eh_frt; .VAR ___eh_frt[1]; #endif .GLOBAL ___lib_prog_term; // Termination address .GLOBAL __done_execution; .EXTERN ___lib_setup_c; #if defined(_ADI_THREADS) .GLOBAL ___lib_start; #endif #if !defined(_ADI_THREADS) #define INT(irp) \ push sts; /* Disable interrupts */ \ JUMP ___z3_int_determiner(DB); /* jmp to finish setting up */ \ DM(I7,M7)=R2; /* Save r2 (scratch dreg) */ \ R2=SIGMASK(SIG_##irp); /* Base of int table */ #define RESERVED_INTERRUPT NOP;NOP;NOP;NOP .SEGMENT/PM seg_rth; // Runtime header segment RESERVED_INTERRUPT; ___lib_RSTI: NOP; // Not really executed JUMP ___lib_start; NOP; NOP; ___lib_IICDI: INT(IICDI); // Access to illegal IOP space ___lib_SOVFI: INT(SOVF); // status/loop/PC stack overflow ___lib_TMZHI: INT(TMZ0); // high priority timer RESERVED_INTERRUPT; ___lib_BKPI: INT(BKP); // Hardware breakpoint interrupt RESERVED_INTERRUPT; ___lib_IRQ2I: INT(IRQ2); ___lib_IRQ1I: INT(IRQ1); ___lib_IRQ0I: INT(IRQ0); ___lib_P0I: INT(P0); // Peripheral interrupt 0 ___lib_P1I: INT(P1); // Peripheral interrupt 1 ___lib_P2I: INT(P2); // Peripheral interrupt 2 ___lib_P3I: INT(P3); // Peripheral interrupt 3 ___lib_P4I: INT(P4); // Peripheral interrupt 4 ___lib_P5I: INT(P5); // Peripheral interrupt 5 ___lib_P6I: INT(P6); // Peripheral interrupt 6 ___lib_P7I: INT(P7); // Peripheral interrupt 7 ___lib_P8I: INT(P8); // Peripheral interrupt 8 ___lib_P9I: INT(P9); // Peripheral interrupt 9 ___lib_P10I: INT(P10); // Peripheral interrupt 10 RESERVED_INTERRUPT; ___lib_P12I: INT(P12); // Peripheral interrupt 12 ___lib_P13I: INT(P13); // Peripheral interrupt 13 RESERVED_INTERRUPT; ___lib_P15I: INT(P15); // Peripheral interrupt 15 RESERVED_INTERRUPT; ___lib_P17I: INT(P17); // Peripheral interrupt 17 ___lib_P18I: INT(P18); // Peripheral interrupt 18 ___lib_CB7I: INT(CB7); // circular buffer #7 overflow ___lib_CB15I: INT(CB15); // circular buffer #15 overflow ___lib_TMZLI: INT(TMZ); // low priority timer ___lib_FIXI: INT(FIX); // fixed point overflow ___lib_FLTOI: INT(FLTO); // floating point overflow ___lib_FLTUI: INT(FLTU); // floating point underflow ___lib_FLTII: INT(FLTI); // floating point invalid ___lib_EMULI: INT(EMUL); // Emulator low priority interrupt ___lib_SFT0I: INT(USR0); // user interrupts 0..3 ___lib_SFT1I: INT(USR1); ___lib_SFT2I: INT(USR2); ___lib_SFT3I: INT(USR3); RESERVED_INTERRUPT; ___z3_int_determiner: DM(I7,M7)=R1; R1=I2; DM(I7,M7)=R1; // Save I2 (scratch reg I2=R2; DM(I7,M7)=I13; // Save I13 (scratch reg) I13=DM(5,I2); // get disp to jump to JUMP (M13, I13) (DB); // Jump to dispatcher NOP; // in place of freeze cache I13=DM(2,I2); // rd handler addr (base+2) #else /* _ADI_THREADS */ .section/pm seg_pmco; #endif /* _ADI_THREADS */ ___lib_start: CALL ___lib_setup_c; // Setup C runtime model #ifdef __cplusplus # ifndef ARGV_SUPPORT put(r4); put(r8); put(r12); # endif // _lib_call_ctors is the added code to support the constructor calls // before the main call. if we are using __ctorsize, then we have to change // this code. i0 = __ctors; _lib_call_ctors: r0 = dm(i0,m6); // get the address of constructor function. r0 = pass r0; if eq jump _lib_call_ctors_exit; // check if null i13=r0; // next 5 lines are for call of the constructor r2 = i6; i6 = i7; jump(m13,i13) (db); dm(i7,m7)=r2; dm(i7,m7)=pc; jump _lib_call_ctors; _lib_call_ctors_exit: // perform static c++ destructors at exit of main r4=___process_needed_destructions__Fv; r2 = i6; i6 = i7; JUMP _atexit (DB); dm(i7,m7)=r2; dm(i7,m7)=pc; # ifndef ARGV_SUPPORT get(r12,1); // Restore the param regs get(r8,2); get(r4,3); modify(i7,3); # endif #endif // __cplusplus #ifdef ARGV_SUPPORT // Initialise argc and argv for the call to main() R2=I6; I6=I7; JUMP __getargv (DB); DM(I7,M7)=R2; DM(I7,M7)=PC; R4 = R0; R8 = __Argv; #endif // **IMPORTANT** The compiler assumes that i6-2==i7 when main starts. (i.e. // the stack pointer, i7 has been decremented by two from it's first value, // NOT that the frame pointer i6 has been incremented by 2). This normally // happens in ___lib_setup_args, but if you change this startup file, // ___lib_setup_args might not be called. In this case, add a // MODIFY(i7,-2) instruction before _main is called #ifdef MAIN_RTS CJUMP _main (DB); // Begin C program DM(I7,M7)=R2; DM(I7,M7)=PC; #else JUMP _main; // Begin C program #endif .___lib_start.end: // Setting the __done_execution flag indicates that this processor is // finished executing, for the benefit of anyone who may be watching. ___lib_prog_term: PM(__done_execution)=PC; IDLE; JUMP ___lib_prog_term; // Stay put .___lib_prog_term.end: .VAR __done_execution = 0; .ENDSEG; #ifdef _ADI_SWFA .SEGMENT/PM seg_pmda; .GLOBAL __21160_anomaly_write_location; .VAR __21160_anomaly_write_location; // A memory location we can write to // to flush the FIFO. #endif .ENDSEG;