switch_dsp56k.c

Go to the documentation of this file.
00001 
00040 /*#*
00041  *#* $Log$
00042  *#* Revision 1.7  2006/07/19 12:56:27  bernie
00043  *#* Convert to new Doxygen style.
00044  *#*
00045  *#* Revision 1.6  2006/02/24 01:17:05  bernie
00046  *#* Update for new emulator.
00047  *#*
00048  *#* Revision 1.5  2005/11/04 16:20:02  bernie
00049  *#* Fix reference to README.devlib in header.
00050  *#*
00051  *#* Revision 1.4  2004/08/25 14:12:09  rasky
00052  *#* Aggiornato il comment block dei log RCS
00053  *#*
00054  *#* Revision 1.3  2004/07/30 14:24:16  rasky
00055  *#* Task switching con salvataggio perfetto stato di interrupt (SR)
00056  *#* Kernel monitor per dump informazioni su stack dei processi
00057  *#*
00058  *#* Revision 1.2  2004/06/03 11:27:09  bernie
00059  *#* Add dual-license information.
00060  *#*
00061  *#* Revision 1.1  2004/05/23 17:27:00  bernie
00062  *#* Import kern/ subdirectory.
00063  *#*
00064  *#*/
00065 
00066 void asm_switch_context(void ** new_sp/*R2*/, void ** save_sp/*R3*/);
00067 asm void asm_switch_context(void ** new_sp, void ** save_sp)
00068 {
00069     lea   (SP)+
00070 
00071     ; From the manual:
00072     ; The compiler uses page 0 address locations X: 0x0030 - 0x003F as register
00073     ; variables. Frequently accessed local variables are assigned to the page 0
00074     ; registers instead of to stack locations so that load and store instructions
00075     ; are shortened. Addresses X: 0x0030 - 0x0037 (page 0 registers MR0-MR7) are
00076     ; volatile registers and can be overwritten. The remaining registers (page 0
00077     ; registers MR8-MR15) are treated as non-volatile and, if used by a routine,
00078     ; must be saved on entry and restored on exit.
00079     ;
00080     ; So, register 0x30-0x37 are caller-save, while 0x38-0x3F are callee-save.
00081     move  x:<$38,y1
00082     move  y1,x:(SP)+
00083     move  x:<$39,y1
00084     move  y1,x:(SP)+
00085     move  x:<$3A,y1
00086     move  y1,x:(SP)+
00087     move  x:<$3B,y1
00088     move  y1,x:(SP)+
00089     move  x:<$3C,y1
00090     move  y1,x:(SP)+
00091     move  x:<$3D,y1
00092     move  y1,x:(SP)+
00093     move  x:<$3E,y1
00094     move  y1,x:(SP)+
00095     move  x:<$3F,y1
00096     move  y1,x:(SP)
00097 
00098     ;
00099     ; Switch stacks
00100     nop
00101     move SP, x:(R3)
00102     nop
00103     move x:(R2), SP
00104     nop
00105 
00106     ;
00107     ; restore all saved registers
00108     ;
00109     pop   y1
00110     move  y1,x:<$3F
00111     pop   y1
00112     move  y1,x:<$3E
00113     pop   y1
00114     move  y1,x:<$3D
00115     pop   y1
00116     move  y1,x:<$3C
00117     pop   y1
00118     move  y1,x:<$3B
00119     pop   y1
00120     move  y1,x:<$3A
00121     pop   y1
00122     move  y1,x:<$39
00123     pop   y1
00124     move  y1,x:<$38
00125 
00126     ; SR is already pushed on the stack (normal call context). Use RTI to restore
00127     ; it, so that interrupt status is preserved across the tasks.
00128     rti
00129 }
00130 
00131 int asm_switch_version(void);
00132 int asm_switch_version(void)
00133 {
00134     return 1;
00135 }