Changeset 162f919 in mainline


Ignore:
Timestamp:
2006-05-02T21:49:05Z (19 years ago)
Author:
Ondrej Palkovsky <ondrap@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
cc35e88
Parents:
281224a
Message:

Added means to make a simple action upon interrupt.

Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • Makefile

    r281224a r162f919  
    157157        generic/src/ipc/sysipc.c \
    158158        generic/src/ipc/ipcrsc.c \
     159        generic/src/ipc/irq.c \
    159160        generic/src/security/cap.c
    160161
  • arch/amd64/src/interrupt.c

    r281224a r162f919  
    4646#include <arch/ddi/ddi.h>
    4747#include <interrupt.h>
    48 #include <ipc/sysipc.h>
     48#include <ipc/irq.h>
    4949
    5050void print_info_errcode(int n, istate_t *istate)
  • generic/include/errno.h

    r281224a r162f919  
    4242                        * to close the connection.  */
    4343#define EEXISTS    -8  /* Entry already exists */
     44#define EBADMEM    -9  /* Bad memory pointer */
    4445
    4546#endif
  • generic/include/ipc/ipc.h

    r281224a r162f919  
    211211extern void ipc_backsend_err(phone_t *phone, call_t *call, __native err);
    212212
    213 extern int ipc_irq_register(answerbox_t *box, int irq);
    214 extern void ipc_irq_send_notif(int irq);
    215 extern void ipc_irq_unregister(answerbox_t *box, int irq);
    216 
    217213
    218214extern answerbox_t *ipc_phone_0;
  • generic/include/ipc/sysipc.h

    r281224a r162f919  
    3131
    3232#include <ipc/ipc.h>
     33#include <ipc/irq.h>
    3334
    3435__native sys_ipc_call_sync_fast(__native phoneid, __native method,
     
    4647                              __native method, __native arg1);
    4748__native sys_ipc_hangup(int phoneid);
    48 __native sys_ipc_register_irq(__native irq);
     49__native sys_ipc_register_irq(__native irq, irq_code_t *ucode);
    4950__native sys_ipc_unregister_irq(__native irq);
    5051
    51 void irq_ipc_bind_arch(__native irq);
    52 
    5352#endif
  • generic/src/ipc/ipc.c

    r281224a r162f919  
    4545#include <proc/thread.h>
    4646#include <arch/interrupt.h>
     47#include <ipc/irq.h>
    4748
    4849/* Open channel that is assigned automatically to new tasks */
     
    5051
    5152static slab_cache_t *ipc_call_slab;
    52 
    53 typedef struct {
    54         SPINLOCK_DECLARE(lock);
    55         answerbox_t *box;
    56 } ipc_irq_t;
    57 
    58 static ipc_irq_t *irq_conns = NULL;
    59 static int irq_conns_size;
    6053
    6154/* Initialize new call */
     
    329322                spinlock_lock(&box->irq_lock);
    330323
    331                 request = list_get_instance(box->answers.next, call_t, list);
     324                request = list_get_instance(box->irq_notifs.next, call_t, list);
    332325                list_remove(&request->list);
    333326
     
    371364}
    372365
    373 /** Disconnect all irq's notifications
    374  *
    375  * TODO: It may be better to do some linked list, so that
    376  *       we wouldn't need to go through whole array every cleanup
    377  */
    378 static void ipc_irq_cleanup(answerbox_t *box)
    379 {
    380         int i;
    381         ipl_t ipl;
    382        
    383         for (i=0; i < irq_conns_size; i++) {
    384                 ipl = interrupts_disable();
    385                 spinlock_lock(&irq_conns[i].lock);
    386                 if (irq_conns[i].box == box)
    387                         irq_conns[i].box = NULL;
    388                 spinlock_unlock(&irq_conns[i].lock);
    389                 interrupts_restore(ipl);
    390         }
    391 }
    392 
    393366/** Cleans up all IPC communication of the given task
    394367 *
     
    444417}
    445418
    446 /** Initialize table of interrupt handlers */
    447 static void ipc_irq_make_table(int irqcount)
    448 {
    449         int i;
    450 
    451         irq_conns_size = irqcount;
    452         irq_conns = malloc(irqcount * (sizeof(*irq_conns)), 0);
    453         for (i=0; i < irqcount; i++) {
    454                 spinlock_initialize(&irq_conns[i].lock, "irq_ipc_lock");
    455                 irq_conns[i].box = NULL;
    456         }
    457 }
    458 
    459 void ipc_irq_unregister(answerbox_t *box, int irq)
    460 {
    461         ipl_t ipl;
    462 
    463         ipl = interrupts_disable();
    464         spinlock_lock(&irq_conns[irq].lock);
    465         if (irq_conns[irq].box == box)
    466                 irq_conns[irq].box = NULL;
    467 
    468         spinlock_unlock(&irq_conns[irq].lock);
    469         interrupts_restore(ipl);
    470 }
    471 
    472 /** Register an answerbox as a receiving end of interrupts notifications */
    473 int ipc_irq_register(answerbox_t *box, int irq)
    474 {
    475         ipl_t ipl;
    476 
    477         ASSERT(irq_conns);
    478 
    479         ipl = interrupts_disable();
    480         spinlock_lock(&irq_conns[irq].lock);
    481 
    482         if (irq_conns[irq].box) {
    483                 spinlock_unlock(&irq_conns[irq].lock);
    484                 interrupts_restore(ipl);
    485                 return EEXISTS;
    486         }
    487         irq_conns[irq].box = box;
    488         spinlock_unlock(&irq_conns[irq].lock);
    489         interrupts_restore(ipl);
    490 
    491         return 0;
    492 }
    493 
    494 /** Notify process that an irq had happend
    495  *
    496  * We expect interrupts to be disabled
    497  */
    498 void ipc_irq_send_notif(int irq)
    499 {
    500         call_t *call;
    501 
    502         ASSERT(irq_conns);
    503         spinlock_lock(&irq_conns[irq].lock);
    504 
    505         if (irq_conns[irq].box) {
    506                 call = ipc_call_alloc(FRAME_ATOMIC);
    507                 call->flags |= IPC_CALL_NOTIF;
    508                 IPC_SET_METHOD(call->data, IPC_M_INTERRUPT);
    509                 IPC_SET_ARG1(call->data, irq);
    510 
    511                 spinlock_lock(&irq_conns[irq].box->irq_lock);
    512                 list_append(&call->list, &irq_conns[irq].box->irq_notifs);
    513                 spinlock_unlock(&irq_conns[irq].box->irq_lock);
    514 
    515                 waitq_wakeup(&irq_conns[irq].box->wq, 0);
    516         }
    517                
    518         spinlock_unlock(&irq_conns[irq].lock);
    519 }
    520419
    521420/** Initilize ipc subsystem */
  • generic/src/ipc/sysipc.c

    r281224a r162f919  
    3636#include <ipc/ipc.h>
    3737#include <ipc/sysipc.h>
     38#include <ipc/irq.h>
    3839#include <ipc/ipcrsc.h>
    3940#include <arch/interrupt.h>
     
    478479
    479480/** Connect irq handler to task */
    480 __native sys_ipc_register_irq(__native irq)
     481__native sys_ipc_register_irq(__native irq, irq_code_t *ucode)
    481482{
    482483        if (irq >= IRQ_COUNT)
     
    484485
    485486        irq_ipc_bind_arch(irq);
    486         return ipc_irq_register(&TASK->answerbox, irq);
     487
     488        return ipc_irq_register(&TASK->answerbox, irq, ucode);
    487489}
    488490
Note: See TracChangeset for help on using the changeset viewer.