=> R0 = device number + flag in b31 (5.00+)
R1 = address of device driver routine
R2 = value to be passed in R12 when driver is called
R3 = address of interrupt status if R0 = podule "IRQ" or "FIQ as IRQ" on entry
R4 = interrupt mask to use, if R0 = podule "IRQ" or "FIQ as IRQ" on entry
<= R0-R4 preserved
This installs the device driver. If the same driver has already been installed on the vector then the old copy is removed from the vector. This does not enable interrupts from the device. The previous driver is added to the list of earlier claimants. Your driver is called if the IO controller receives an interrupt from the appropriate device, the corresponding interrupt mask bit is set, and your driver was the last to claim the vector.
When your code is being called, you'll find the following entry conditions:
· the ARM is in IRQ mode and interrupts are disabled
· R3 points to the base of the IO controller chip memory space
· R12 has R2's value when claiming the vector
Your routine should:
· service the interrupt
· stop the device from generating interrupts, when necessary
· return to kernel using 'MOV PC, R14'
You should ensure:
· a very high execution speed
· if your routine takes more than 100µs, you should re-enable interrupts, if previously disabled, to ensure other devices' interrupts can be serviced - eg. sound buffer fills. With interrupts enabled your routine must cope with being re-entered.
· saving R14_svc to a stack before calling SWIs and reloading it after it returns to prevent double use of R14_svc
· strictly avoiding the use of non re-entrant SWIs, because the supervisor stack would become corrupted if used
· clearing the interrupt flags when finishing
· you cope with SWI-error handling. You must use XSWIs. As there is no-one to pass the error on to, you must either handle it yourself or store an error indicator, so that the next SWI call (or the current, if already threaded) to this module will generate an error.
See PRM 1, page 121.
OS_ClaimDeviceVector flag (5.00+)
From RISC OS 5.00, if bit 31 of the device number is set when claiming a device vector, the interrupt will be passed on to earlier claimants of the vector unless your service code claims it. This is necessary on PCI systems where all interrupts can be shared.
It is up to you to determine whether it is your device that has caused the interrupt. If it has, you should service it, then claim the vector by pulling the return address off the stack. If not, pass the service along by returning to the address in R14 on entry. If no handlers claim a particular interrupt, then RISC OS will disable that line.
If you do not claim the interrupt, you must preserve R0 and R3. R1, R2 and R12 may be corrupted.
It is critical that your choice of whether to claim is purely on the basis of whether your card is interrupting, and is accurate. Not claiming when your card is interrupting, or claiming when it isn't can both cause incorrect system behaviour.
|
|
|