NAME | SYNOPSIS | API RESTRICTIONS | FEATURES | DESCRIPTION | ALLOWED CALLING CONTEXTS | ATTRIBUTES | SEE ALSO
#include <dki/f_dki.h>KnError svIntrAttach(unsigned int intrNumb, unsigned int intrLevel, CpuIntrHandler intrHandler, void * intrCookie, CpuIntrOps ** intrOps, CpuIntrId * intrIdp);
The function or functions documented here may not be used safely in all application contexts with all APIs provided in the ChorusOS 5.0 product.
See API(5FEA) for details.
DKI
Provides interrupts management services.
An processor is an implementation of the SPARC-V9 CPU architecture. As specified by the SPARC-V9 architecture, there are fifteen CPU interrupt sources assigned to the fifteen CPU interrupt levels from 1 up to 15. However, the processor uses these fifteen interrupt levels only for software generated interrupts. The hardware interrupts are delivered to the processor using the Mondo interrupt transfer mechanism. The hardware interrupt source is designated by the interrupt number. Typically, the interrupt number is 11-bit width and composed of the interrupt group number (5 MSB) and the interrupt offset number (6 LSB).
The Mondo interrupt dispatch handler is built into the microkernel. The microkernel handles a mapping between the hardware interrupt numbers and software interrupt levels. When a Mondo interrupt packet is received by the microkernel, the interrupt request descriptor is queued and an associated software interrupt is triggered. The microkernel software interrupt handler then removes the interrupt request descriptor from the queue and invokes a handler associated to the given interrupt number. In this way, a driver interrupt handler is always invoked in the software interrupt context. This provides the interrupt handler with an environment analogous to the SPARC-V8 one (interrupt levels).
The microkernel provides services that allow device drivers to manage interrupts, mainly to attach or detach handlers to the CPU interrupts.
typedef void (*CpuIntrHandler)(void*);
svIntrAttach() attaches a given handler to a given interrupt number at a given processor interrupt level.
The intrNumb argument specifies the interrupt number to which to attach.
The intrLevel argument specifies the interrupt level to which to attach.
The intrHandler argument specifies the handler to call back when the given interrupt occurs.
The intrCookie argument specifies a parameter to pass back to the handler when called. It is opaque to the microkernel.
On success, K_OK is returned and the services defined on the attached interrupt are returned in the intrOps parameter. An identifier for the attached interrupt is also returned in intrId . This identifier must be used as first argument to subsequent calls to intrOps services.
On failure, an error code is returned as follows:
The specified interrupt number or interrupt level are invalid.
Another handler is already attached to the given intrNumb .
The system is out of memory.
Services available on an attached interrupt are defined by the CpuIntrOps structure as follows:
typedef struct CpuIntrOps { void (*mask) (CpuIntrId intrId); void (*unmask) (CpuIntrId intrId); void (*enable) (CpuIntrId intrId); void (*disable) (CpuIntrId intrId); void (*trigger) (CpuIntrId intrId); } CpuIntrOps;
The CpuIntrOps.mask routine disables the interrupt at CPU level identified by intrId . In other words, the PIL register is set to the level corresponding to intrId .
The original value of the PIL register is saved by DKI in order to be restored later by the CpuIntrOps.unmask routine.
The CpuIntrOps.unmask routine enables the interrupt at CPU level identified by intrId .
In other words, the PIL register is restored to the original value saved by the previously called CpuIntrOps.mask routine.
The mask/unmask pair may be called from base level only and must not be nested. The mask/unmask pair is typically used to implement a critical section of code which needs to be protected against the interrupt.
With respect to the SPARC-V9 architecture, when an interrupt level N is masked, all interrupts with a level less than N are also masked. Thus, there is no way to mask only one CPU interrupt level except the lowest one.
The enable/disable pair may only be called from the attached interrupt handler. When an interrupt occurs, the attached CpuIntrHandler is invoked with the interrupt masked at processor level. This behaves in exactly the same way as if CpuIntrOps.disable was called just prior to the handler invocation. In other words, the PIL register is set to the interrupt level and the original interrupt processor level (which was when the interrupt occurred) is saved by DKI .
The interrupt handler must return to DKI in the same context as it was called, that is, with the interrupt disabled at processor level.
On the other hand, the called interrupt handler may use the enable/disable pair to allow the interrupt to be nested. This feature is typically used by a host bus driver when the bus interrupts are multiplexed, that is, multiple bus interrupts are reported at the same CPU interrupt level. Typically, an interrupt handler of this type of host bus driver would take the following actions:
Identify the bus interrupt source (through a PIC or special cycle).
Disable the bus interrupt source at bus level (through PIC ).
Enable interrupt at processor level ( CpuIntrOps.enable ).
Call handlers attached to the identified bus interrupt source.
Disable interrupt at processor level, that is, \\\\command{disable} .
Acknowledge (if needed) and enable the bus interrupt source at bus level (through PIC ).
Return to the DKI .
The CpuIntrOps.trigger routine allows the interrupt to be triggered by software. Basically, this routine acts like the Mondo interrupt dispatcher except the interrupt number is obtained from intrId rather than from the Mondo interrupt packet. The CpuIntrOps.trigger routine is mainly dedicated to the software interrupts attached by svSoftIntrAttach() . However, it may be also used for hardware interrupts, for instance, for debugging or diagnostic purposes.
svIntrDetach() detaches an interrupt handler previously connected by svIntrAttach() .
The intrId argument identifies the attached interrupt handler, previously returned by svIntrAttach() .
svSoftIntrAttach() attaches a given software interrupt handler to a given processor interrupt level.
The intrLevel argument specifies the interrupt level to which to attach.
The intrHandler argument specifies the handler to call back when the given interrupt is triggered.
The intrCookie argument specifies a parameter to pass back to the handler when called. It is opaque to the microkernel.
On success, K_OK is returned and the services defined on the attached interrupt are returned in the intrOps parameter.
An identifier for the attached interrupt is also returned in intrId . This identifier must be used as the first argument to subsequent calls to intrOps services.
On failure, an error code is returned as follows:
The specified interrupt level is invalid.
The system is out of memory.
Services available on an attached interrupt are defined by the CpuIntrOps structure described above.
svSoftIntrDetach() detaches a software interrupt handler previously connected by svSoftIntrAttach() .
The intrId argument identifies the attached interrupt handler previously returned by svSoftIntrAttach() .
svTimerIntrAttach() attaches a given interrupt handler to the tick-counter interrupt.
The intrHandler argument specifies the handler to call back when the given interrupt is triggered.
The intrCookie argument specifies a parameter to pass back to the handler when called. It is opaque the microkernel.
On success, K_OK() is returned and the services defined on the attached interrupt are returned in the intrOps parameter. An identifier for the attached interrupt is also returned in intrId . This identifier must be used as the first argument to subsequent calls to intrOps services.
On failure, an error code is returned as follows:
Another handler is already attached to the tick-counter interrupt.
The system is out of memory.
Services available on an attached interrupt are defined by the CpuIntrOps structure described above.
svTimerIntrDetach() detaches the interrupt handler previously connected by svTimerIntrAttach() .
The intrId argument identifies the attached interrupt handler previously returned by svTimerIntrAttach() .
svIntrCtxGet() retrieves the current level interrupt context. It is typically used for profiling purposes.
On success, K_OK is returned and a pointer to the recently saved interrupt context is returned in the intrCtx argument. The CPU context saved on interrupt has the same structure as the thread context saved on exception or trap. It contains the global registers %g1-%g7 , the output registers of the interrupted window %o0-%o7 and the following processor registers: %tstate , %pc , %npc , %tt , %y . In addition, if the number of windows is greater than zero, the thread context contains the number of outstanding windows and the pointer to the outstanding windows buffer.
On failure, an error code is returned as follows:
Interrupt level is zero (not called from an interrupt handler).
There is no context available for currently handled interrupt.
The following table specifies the contexts in which a caller is allowed to invoke each interrupt management service.
Services | Base level | DKI thread | Interrupt | Blocking |
svIntrAttach() | + | + | - | + |
svIntrDetach() | + | + | - | + |
svIntrSoftAttach() | + | + | - | + |
svIntrSoftDetach() | + | + | - | + |
svTimerIntrAttach() | + | + | - | + |
svTimerIntrDetach() | + | + | - | + |
svIntrCtxGet() | - | - | + | - |
CpuIntrOps.mask | + | + | - | - |
CpuIntrOps.unmask | + | + | - | - |
CpuIntrOps.enable | - | - | + | - |
CpuIntrOps.disable | - | - | + | - |
CpuIntrOps.trigger | + | + | + | - |
See attributes(5) for descriptions of the following attributes:
ATTRIBUTE TYPE | ATTRIBUTE VALUE |
---|---|
Interface Stability | Evolving |
NAME | SYNOPSIS | API RESTRICTIONS | FEATURES | DESCRIPTION | ALLOWED CALLING CONTEXTS | ATTRIBUTES | SEE ALSO