C28x Context Save and Restore
This wiki article describes the automatic context save/restore for the C28x CPU. This also applies to devices with the FPU and VCU extensions.
- The context save and restore is documented in the C28x TMS320C28x CPU and Instruction Set Reference Guide.
First a few facts regarding the C28x stack pointer:
- The C28x stack pointer (SP) always points to the first empty address within the stack.
- The C28x stack grows from low address to high address.
- The context save performs 32-bit PUSH operations (not 16-bit).
- The context restore performs 32-bit POP operations (not 16-bit).
- The stack pointer itself is 16 bits. Therefore the stack must always be in low memory not to exceed address 0xFFFF.
32-bit Writes and Reads
32-bit writes and reads are always even aligned on the C28x. That is, a 32-bit value uses an even address and the next odd no matter which address the write was to. This is true for all 32-bit reads/writes on the C28x. You will never see a 32-bit value use a odd location and the next even.
The following image shows a 32-bit PUSH to an even address:
The following image shows a 32-bit PUSH to an odd address. Notice that the write is even aligned and is the same as if the stack pointer pointed to the previous even address.
Note: if there had been data in location 0xC140 before the push, it would have been overwritten!! We will use this knowledge in the next section.
Automatic Context Save
When an interrupt is taken by the CPU, there is no way to know if the stack pointer (SP) is even or odd. As we saw in the previous section, if the SP is odd then the context save has the potential to overwrite a previous value already on the stack.
In order to account for this, the automatic context save will first increment the stack by 1. This guarantees the data saved will not overwrite something already on the stack.
After the stack pointer is incremented by 1, a number of registers will automatically be pushed onto the stack. These registers are documented in the TMS320C28x CPU and Instruction Set Reference Guide. Each push is a 32-bit write to memory. This is always even aligned on the C28x; a 32-bit word always takes up an even and the next odd.
The following image shows the save if the stack pointer is odd when the interrupt is taken. Note that adding 1 to SP keeps the first PUSH from overwriting any data in address 0xC140.
The first instruction within an ISR should always be the ASP instruction. If you are writing in C, then the compiler will automatically add ASP for you. If the SP is odd aligned, the ASP instruction will increment it by one so that it is even aligned. In the case shown below the ASP instruction within the ISR has no effect. It should still be used, however, since there is no way to control whether the SP will be even or odd when an interrupt is taken.
The following image shows the context save if the stack pointer is even when the interrupt is taken. In this case, adding 1 to SP before the save could have been skipped, but there is no way to know if the interrupt was taken when the SP is even or odd. Adding 1 to SP has no ill effect. Notice in this case the ASP instruction within the ISR will force re-alignment of the stack. This is done so that any values placed on the stack within the ISR will not overwrite part of the context save. Having an even aligned stack is important for the C compiler. Also following this convention can make things easier when programming in assembly.
Notice in both cases, each 32-bit push is even aligned. That is it takes up an even address and the next odd no matter which address the SP points to. This is true for all 32-bit reads/writes on the C28x. You will never see a 32-bit value use a odd location and the next even.
Automatic Context Restore
When an IRET instruction executes, an automatic context restore will be done before the code returns to the point where the interrupt was taken. The automatic context restore is simply the reverse of the automatic context save.
Before the IRET instruction, the ISR must execute the NASP instruction. This will un-do any alignment that was performed by the ASP instruction. If you are writing in C, then the compiler will automatically add the ASP and NASP instructions to your interrupt service routine.
As a last step, the the SP is automatically decremented by 1 and, therefore, ends up back to where it was before the interrupt was taken.