Message type for SYS_IRQCTL

Change-Id: Idef5a1e49aea3eea690e2a9bf046348766a8b944
This commit is contained in:
Lionel Sambuc 2014-05-21 16:44:37 +02:00
parent 30eae10274
commit b3085e334c
4 changed files with 37 additions and 25 deletions

View file

@ -301,18 +301,14 @@
#define DIO_VALUE m2_l2 /* single I/O value */ #define DIO_VALUE m2_l2 /* single I/O value */
/* Field names for SYS_IRQCTL. */ /* Field names for SYS_IRQCTL. */
#define IRQ_REQUEST m5_s1 /* what to do? */
# define IRQ_SETPOLICY 1 /* manage a slot of the IRQ table */ # define IRQ_SETPOLICY 1 /* manage a slot of the IRQ table */
# define IRQ_RMPOLICY 2 /* remove a slot of the IRQ table */ # define IRQ_RMPOLICY 2 /* remove a slot of the IRQ table */
# define IRQ_ENABLE 3 /* enable interrupts */ # define IRQ_ENABLE 3 /* enable interrupts */
# define IRQ_DISABLE 4 /* disable interrupts */ # define IRQ_DISABLE 4 /* disable interrupts */
#define IRQ_VECTOR m5_s2 /* irq vector */
#define IRQ_POLICY m5_i1 /* options for IRQCTL request */
# define IRQ_REENABLE 0x001 /* reenable IRQ line after interrupt */ # define IRQ_REENABLE 0x001 /* reenable IRQ line after interrupt */
# define IRQ_BYTE 0x100 /* byte values */ # define IRQ_BYTE 0x100 /* byte values */
# define IRQ_WORD 0x200 /* word values */ # define IRQ_WORD 0x200 /* word values */
# define IRQ_LONG 0x400 /* long values */ # define IRQ_LONG 0x400 /* long values */
#define IRQ_HOOK_ID m5_l3 /* id of irq hook at kernel */
/* Field names for SYS_ABORT. */ /* Field names for SYS_ABORT. */
#define ABRT_HOW m1_i1 /* RBT_REBOOT, RBT_HALT, etc. */ #define ABRT_HOW m1_i1 /* RBT_REBOOT, RBT_HALT, etc. */

View file

@ -700,6 +700,23 @@ typedef struct {
} mess_lsys_krn_schedctl; } mess_lsys_krn_schedctl;
_ASSERT_MSG_SIZE(mess_lsys_krn_schedctl); _ASSERT_MSG_SIZE(mess_lsys_krn_schedctl);
typedef struct {
int request;
int vector;
int policy;
int hook_id;
uint8_t padding[40];
} mess_lsys_krn_sys_irqctl;
_ASSERT_MSG_SIZE(mess_lsys_krn_sys_irqctl);
typedef struct {
int hook_id;
uint8_t padding[52];
} mess_krn_lsys_sys_irqctl;
_ASSERT_MSG_SIZE(mess_krn_lsys_sys_irqctl);
typedef struct { typedef struct {
int request; int request;
long int port; long int port;
@ -1387,6 +1404,7 @@ typedef struct {
mess_sigcalls m_sigcalls; mess_sigcalls m_sigcalls;
mess_krn_lsys_schedule m_krn_lsys_schedule; mess_krn_lsys_schedule m_krn_lsys_schedule;
mess_krn_lsys_sys_irqctl m_krn_lsys_sys_irqctl;
mess_fs_vfs_breadwrite m_fs_vfs_breadwrite; mess_fs_vfs_breadwrite m_fs_vfs_breadwrite;
mess_fs_vfs_chmod m_fs_vfs_chmod; mess_fs_vfs_chmod m_fs_vfs_chmod;
@ -1463,6 +1481,7 @@ typedef struct {
mess_lsys_krn_schedctl m_lsys_krn_schedctl; mess_lsys_krn_schedctl m_lsys_krn_schedctl;
mess_lsys_krn_schedule m_lsys_krn_schedule; mess_lsys_krn_schedule m_lsys_krn_schedule;
mess_lsys_krn_sys_irqctl m_lsys_krn_sys_irqctl;
mess_lsys_krn_sys_memset m_lsys_krn_sys_memset; mess_lsys_krn_sys_memset m_lsys_krn_sys_memset;
mess_lsys_krn_sys_sdevio m_lsys_krn_sys_sdevio; mess_lsys_krn_sys_sdevio m_lsys_krn_sys_sdevio;
mess_lsys_krn_sys_setalarm m_lsys_krn_sys_setalarm; mess_lsys_krn_sys_setalarm m_lsys_krn_sys_setalarm;

View file

@ -2,11 +2,11 @@
* m_type: SYS_IRQCTL * m_type: SYS_IRQCTL
* *
* The parameters for this kernel call are: * The parameters for this kernel call are:
* m5_s1: IRQ_REQUEST (control operation to perform) * m_lsys_krn_sys_irqctl.request (control operation to perform)
* m5_s2: IRQ_VECTOR (irq line that must be controlled) * m_lsys_krn_sys_irqctl.vector (irq line that must be controlled)
* m5_i1: IRQ_POLICY (irq policy allows reenabling interrupts) * m_lsys_krn_sys_irqctl.policy (irq policy allows reenabling interrupts)
* m5_l3: IRQ_HOOK_ID (provides index to be returned on interrupt) * m_lsys_krn_sys_irqctl.hook_id (provides index to be returned on interrupt)
* ,, ,, (returns index of irq hook assigned at kernel) * m_krn_lsys_sys_irqctl.hook_id (returns index of irq hook assigned at kernel)
*/ */
#include "kernel/kernel.h" #include "kernel/kernel.h"
@ -33,11 +33,11 @@ int do_irqctl(struct proc * caller, message * m_ptr)
struct priv *privp; struct priv *privp;
/* Hook identifiers start at 1 and end at NR_IRQ_HOOKS. */ /* Hook identifiers start at 1 and end at NR_IRQ_HOOKS. */
irq_hook_id = (unsigned) m_ptr->IRQ_HOOK_ID - 1; irq_hook_id = m_ptr->m_lsys_krn_sys_irqctl.hook_id - 1;
irq_vec = (unsigned) m_ptr->IRQ_VECTOR; irq_vec = m_ptr->m_lsys_krn_sys_irqctl.vector;
/* See what is requested and take needed actions. */ /* See what is requested and take needed actions. */
switch(m_ptr->IRQ_REQUEST) { switch(m_ptr->m_lsys_krn_sys_irqctl.request) {
/* Enable or disable IRQs. This is straightforward. */ /* Enable or disable IRQs. This is straightforward. */
case IRQ_ENABLE: case IRQ_ENABLE:
@ -45,7 +45,7 @@ int do_irqctl(struct proc * caller, message * m_ptr)
if (irq_hook_id >= NR_IRQ_HOOKS || irq_hook_id < 0 || if (irq_hook_id >= NR_IRQ_HOOKS || irq_hook_id < 0 ||
irq_hooks[irq_hook_id].proc_nr_e == NONE) return(EINVAL); irq_hooks[irq_hook_id].proc_nr_e == NONE) return(EINVAL);
if (irq_hooks[irq_hook_id].proc_nr_e != caller->p_endpoint) return(EPERM); if (irq_hooks[irq_hook_id].proc_nr_e != caller->p_endpoint) return(EPERM);
if (m_ptr->IRQ_REQUEST == IRQ_ENABLE) { if (m_ptr->m_lsys_krn_sys_irqctl.request == IRQ_ENABLE) {
enable_irq(&irq_hooks[irq_hook_id]); enable_irq(&irq_hooks[irq_hook_id]);
} }
else else
@ -85,7 +85,7 @@ int do_irqctl(struct proc * caller, message * m_ptr)
/* When setting a policy, the caller must provide an identifier that /* When setting a policy, the caller must provide an identifier that
* is returned on the notification message if a interrupt occurs. * is returned on the notification message if a interrupt occurs.
*/ */
notify_id = (unsigned) m_ptr->IRQ_HOOK_ID; notify_id = m_ptr->m_lsys_krn_sys_irqctl.hook_id;
if (notify_id > CHAR_BIT * sizeof(irq_id_t) - 1) return(EINVAL); if (notify_id > CHAR_BIT * sizeof(irq_id_t) - 1) return(EINVAL);
/* Try to find an existing mapping to override. */ /* Try to find an existing mapping to override. */
@ -111,13 +111,13 @@ int do_irqctl(struct proc * caller, message * m_ptr)
/* Install the handler. */ /* Install the handler. */
hook_ptr->proc_nr_e = caller->p_endpoint; /* process to notify */ hook_ptr->proc_nr_e = caller->p_endpoint; /* process to notify */
hook_ptr->notify_id = notify_id; /* identifier to pass */ hook_ptr->notify_id = notify_id; /* identifier to pass */
hook_ptr->policy = m_ptr->IRQ_POLICY; /* policy for interrupts */ hook_ptr->policy = m_ptr->m_lsys_krn_sys_irqctl.policy; /* policy for interrupts */
put_irq_handler(hook_ptr, irq_vec, generic_handler); put_irq_handler(hook_ptr, irq_vec, generic_handler);
DEBUGBASIC(("IRQ %d handler registered by %s / %d\n", DEBUGBASIC(("IRQ %d handler registered by %s / %d\n",
irq_vec, caller->p_name, caller->p_endpoint)); irq_vec, caller->p_name, caller->p_endpoint));
/* Return index of the IRQ hook in use. */ /* Return index of the IRQ hook in use. */
m_ptr->IRQ_HOOK_ID = irq_hook_id + 1; m_ptr->m_krn_lsys_sys_irqctl.hook_id = irq_hook_id + 1;
break; break;
case IRQ_RMPOLICY: case IRQ_RMPOLICY:
@ -133,7 +133,7 @@ int do_irqctl(struct proc * caller, message * m_ptr)
break; break;
default: default:
r = EINVAL; /* invalid IRQ_REQUEST */ r = EINVAL; /* invalid IRQ REQUEST */
} }
return(r); return(r);
} }
@ -174,4 +174,3 @@ irq_hook_t *hook;
} }
#endif /* USE_IRQCTL */ #endif /* USE_IRQCTL */

View file

@ -13,14 +13,12 @@ int *hook_id; /* ID of IRQ hook at kernel */
int s; int s;
m_irq.m_type = SYS_IRQCTL; m_irq.m_type = SYS_IRQCTL;
m_irq.IRQ_REQUEST = req; m_irq.m_lsys_krn_sys_irqctl.request = req;
m_irq.IRQ_VECTOR = irq_vec; m_irq.m_lsys_krn_sys_irqctl.vector = irq_vec;
m_irq.IRQ_POLICY = policy; m_irq.m_lsys_krn_sys_irqctl.policy = policy;
m_irq.IRQ_HOOK_ID = *hook_id; m_irq.m_lsys_krn_sys_irqctl.hook_id = *hook_id;
s = _kernel_call(SYS_IRQCTL, &m_irq); s = _kernel_call(SYS_IRQCTL, &m_irq);
if (req == IRQ_SETPOLICY) *hook_id = m_irq.IRQ_HOOK_ID; if (req == IRQ_SETPOLICY) *hook_id = m_irq.m_krn_lsys_sys_irqctl.hook_id;
return(s); return(s);
} }