h6. [[OS SWI Calls]] h6(. » OS_ClaimDeviceVector h2. OS_ClaimDeviceVector h5. (SWI &4B) |_<^{width:4em}. Entry | | |<^. R0 |<^. [[System Device Numbers|Device number]] and [[OS_ClaimDeviceVector Flag|flag]] in bit 31 | |<^. 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 | |_<^{width:4em}. Exit | | |<^. R0|<^. Preserved| |<^. R1|<^. Preserved| |<^. R2|<^. Preserved| |<^. R3|<^. Preserved| |<^. R4|<^. Preserved| h4. Use The purpose of this call is to claim a device vector. h4. Notes 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 interrupt controller receives an interrupt from the appropriate device and your driver was the last to claim the vector. For IO expansion cards (device numbers 8 or 13) there may be multiple cards all sharing the same interrupt line (and therefore device number) the values in R3 and R4 will be used to determine the true owner. A byte read will be performed of the interrupt status and your driver will be called if (status AND R4) is non zero. From RISC OS 5.00, bits 8-15 of R4 can specify an EOR mask to permit active low interrupts to be supported, ie. when ((status EOR R4[15:8]) AND R4[7:0]) is non zero. Under RISC OS 5, your driver routine will be called as follows: * The ARM is in IRQ32 mode and interrupts are disabled * R0 is the device number (with no flags in the high bits) * R12 has R2's value when claiming the vector * R13 points to the IRQ stack. The word pointed to by R13 is a return address for claiming the vector. * R14 contains a return address for passing on the call to the next device driver. On exit: * Processor mode and interrupt state must be preserved * R1-R3, R12, and R14 may be corrupted by the call. * R0 must be preserved if you are passing on an unhandled shared IRQ. If you are claiming the IRQ, it can be corrupted. * For non-shared IRQs, returning via R14 is functionally equivalent to returning via the stacked return address. This also means that R0 doesn't need to be preserved when returning via R14. If the interrupt is caused by your device, your routine should: * Service the interrupt * Stop the device from generating interrupts, when necessary * Call [[HAL_IRQClear]] to ensure the IRQ controller resumes its processing * Return to the kernel by popping the pre-prepared return address from the stack If the interrupt is not caused by your device (i.e. it's a different device which is on the same shared IRQ line as your device), your routine should return to the kernel by <code>MOV PC,R14</code> or similar. The kernel will then call the next routine on the device vector chain. Note that if an interrupt is received for a device which has no drivers registered, or (for a shared IRQ line) if the end of the chain is reached without any driver handling the IRQ, the kernel will automatically disable the IRQ via [[HAL_IRQDisable]]. This behaviour is necessary so that devices which request an interrupt when no driver is loaded will not hang the system. However it does mean that a buggy device driver on a shared IRQ line may accidentally cause that IRQ line to be disabled for all drivers on that line - be aware of this when developing/debugging your drivers. 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 – e.g. disc ops. 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. h4. See also * [[HAL_IRQSource]] * [[OS_ClaimDeviceVector Flag]] * [[OS_ReleaseDeviceVector]] * [[System Device Numbers]]