Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 1283 → Rev 1284

/kernel/trunk/generic/include/ipc/irq.h
40,6 → 40,8
CMD_MEM_WRITE_2,
CMD_MEM_WRITE_4,
CMD_MEM_WRITE_8,
CMD_PORT_READ_1,
CMD_PORT_WRITE_1,
CMD_LAST
} irq_cmd_type;
 
/kernel/trunk/generic/src/ipc/irq.c
26,16 → 26,33
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** IRQ notification framework
*
* This framework allows applications to register to receive a notification
* when interrupt is detected. The application may provide a simple 'top-half'
* handler as part of its registration, which can perform simple operations
* (read/write port/memory, add information to notification ipc message).
*
* The structure of a notification message is as follows:
* - METHOD: IPC_M_INTERRUPT
* - ARG1: interrupt number
* - ARG2: payload modified by a 'top-half' handler
* - ARG3: interrupt counter (may be needed to assure correct order
* in multithreaded drivers)
*/
 
#include <arch.h>
#include <mm/slab.h>
#include <errno.h>
#include <ipc/ipc.h>
#include <ipc/irq.h>
#include <atomic.h>
 
typedef struct {
SPINLOCK_DECLARE(lock);
answerbox_t *box;
irq_code_t *code;
atomic_t counter;
} ipc_irq_t;
 
 
77,6 → 94,14
case CMD_MEM_WRITE_8:
*((__u64 *)code->cmds[i].addr) = code->cmds[i].value;
break;
#if defined(ia32) || defined(amd64)
case CMD_PORT_READ_1:
IPC_SET_ARG2(call->data, inb((long)code->cmds[i].addr));
break;
case CMD_PORT_WRITE_1:
outb((long)code->cmds[i].addr, code->cmds[i].value);
break;
#endif
default:
break;
}
153,6 → 178,7
}
irq_conns[irq].box = box;
irq_conns[irq].code = code;
atomic_set(&irq_conns[irq].counter, 0);
spinlock_unlock(&irq_conns[irq].lock);
interrupts_restore(ipl);
 
175,6 → 201,7
call->flags |= IPC_CALL_NOTIF;
IPC_SET_METHOD(call->data, IPC_M_INTERRUPT);
IPC_SET_ARG1(call->data, irq);
IPC_SET_ARG3(call->data, atomic_preinc(&irq_conns[irq].counter));
 
/* Execute code to handle irq */
code_execute(call, irq_conns[irq].code);