Timer driven interrupts on the PowerPC processor |
In order to see the effect that the PowerPC RISC architecture has on interrupt handling, we shall use exactly the same format in this section as for the 68K CISC timer routine.
The main task is essentially a loop that increments a counter. However, the loop is set up in such a way that can never exit without some external agency. The pseudo code for both the 68K and the PowerPC obviously must be identical as the processors are performing the same task.
global variables counter, semaphore; main() { long inc = 1; counter = 0; semaphore = 0; while (semaphore == 0) counter += inc; }
The solution to this task can be found in the file ppcmain.s. Try to develop your own code before looking.
Note how on a RISC processor you will load an address into a register and then use that register to access a memory location. However, as there are many RISC registers available, it is possible to leave the address in the register for later reuse when storing the modified value to memory. This address register indirect approach is very efficient when multi accesses to memory are necessary.
The interrupt task is to check whether the counter value is even. If it is even then set the semaphore variable to 1 and cause the main task to exit. Again try and develop your own solution before looking at the answer in file ppcisr.s.
Note that the "return-from-interrupt" on the PowerPC processor is actually a RFI instruction and not the "RTI" instruction found on many other processors.
Note that there is a possibility that the interrupt service routine will change the semaphore variable, only to have the new value over written by the main task writing the semaphore variable.
Although it is not obvious, the PowerPC return address and the various other pieces of status information are stored in "special registers" SRR0 and SRR1. See HVZ and the PowerPC user manual for details.
As with the 68K processor, the status register on the PowerPC is automatically saved when the interrupt starts. However, unlike the 68K processor, the status register does not include information about the flags. This information is stored in the special register CR. If any compare operations are performed during the ISR, this register must be saved on entry into the ISR and recovered on exit.
The startup code for enabling PowerPC interrupts has the following format
Set-up the stack De-activate interrupts to avoid problems while initing Clear the semaphore variables Set the timer reload variable (how often interrupts occur) Set the processor to vector via the low end of memory (0x900) when handling timer interrupts FIX BECAUSE OF DEMO KIT LIMITATIONS Place the start of the ISR routine at the vector address Clear the old timer interrupt that occurred since the processor resets with the Decrementer register as zero and decrementing. Activate the interrupts Call the main code
Look up any necessary operations and memory locations in the processor's User Manual now you know the format of what is required. Try and develop your own start-up routine before examining my version of the code in file ppcinit.s.
There is one problem that must be overcome when programming the initialization routine. On the 68K processor only the starting address of the ISR is placed at the vector location. On the PowerPC, with fewer interrupt types to handle, all of the ISR, not just its starting address is placed into the interrupt vector memory. Thus we should program on the PowerPC one of the following sets of code
section ISRspecial // Place at 0x900 ActualISR: All the ISR routine lives here
.text All the other code
or the approach taken by HVZ in their PowerPC interrupt explanation
section ISRspecial // Place at 0x900 ActualISR: b ISR // Branch to actual ISR
.text All the other code including the ISR lives here
The second approach is only strictly necessary if the ISR is longer than 64 instructions, the amount of memory between the timer interrupt start (0x900) and the start of the next interrupt space (0xA00).
How, with the crippled DIAB DATA PowerPC assembler/linker, can you get the ISR code to be placed at memory location 0x900 and the rest of the code else where? With the full PowerPC kit, you could set up several memory sections as with the 68K demo kit. With the PowerPC demo kit you can't.
Two choices are possible
As you can see from the initialization code ppcinit.s I made use of the second approach. Several interrupts need to be handled at the same time when handling the "virtual device" and the timer in Task 3b.
This self-modifying code approach is not to be taken lightly as it is "highly inadvisable" except under special circumstances. Since the DIAB DATA PowerPC assembler/linker has been crippled in the demo kit, and we don't have to self-modify very much code, this will have to be considered a suitable"special circumstance". With a real embedded processor system, the approach would not work as the program code is placed into "un-self-modificable" ROM.
There are a number of pieces of magic to get the SDS simulator to recognize the timer and correctly respond to the timer interrupts
NOTE:- I have found no documentation to whether this problem does or does not occur in real life, meaning is it an SDS simulator artifact? The manuals read as if the decrementer will be reset to zero, so the interrupt problem should occur. However, nobody explains what to do then, just as if there is no problem, so perhaps it does not occur! Alternately, perhaps the books' authors reckon that if you are coding in assembly code at this level, you would have the experience to be aware of this "obvious" problem so that there is no need to discuss it!
You might want to investigate the following
![]() |
Last modified: July 22, 1996 01:44 PM by M. Smith.
Copyright -- M. R. Smith