Preliminary irq registration call + irq capability checking

Need to add irqctrl capabilities and irq bits to device memory
caps.

Also need to initialize irq field of devmem caps.
This commit is contained in:
Bahadir Balban
2009-11-28 19:13:23 +02:00
parent b5e6c66426
commit 6e40a2b601
17 changed files with 380 additions and 110 deletions

View File

@@ -15,7 +15,7 @@
#define CAP_TYPE_MAP_PHYSMEM (1 << 2)
#define CAP_TYPE_MAP_VIRTMEM (1 << 3)
#define CAP_TYPE_IPC (1 << 4)
#define CAP_TYPE_SCHED (1 << 5)
#define CAP_TYPE_IRQCTRL (1 << 5)
#define CAP_TYPE_UMUTEX (1 << 6)
#define CAP_TYPE_QUANTITY (1 << 7)
#define CAP_TYPE_CAP (1 << 8)
@@ -52,17 +52,16 @@
#define CAP_DEVNUM_MASK 0xFFFF0000
#define CAP_DEVNUM_SHIFT 16
#define cap_is_devmem(c) (c)->uattr[0]
#define cap_is_devmem(c) ((c)->attr)
#define cap_set_devtype(c, devtype) \
{(c)->uattr[0] &= ~CAP_DEVTYPE_MASK; \
(c)->uattr[0] |= CAP_DEVTYPE_MASK & devtype;}
{(c)->attr &= ~CAP_DEVTYPE_MASK; \
(c)->attr |= CAP_DEVTYPE_MASK & devtype;}
#define cap_set_devnum(c, devnum) \
{(c)->uattr[0] &= ~CAP_DEVNUM_MASK; \
(c)->uattr[0] |= CAP_DEVNUM_MASK & devnum;}
{(c)->attr &= ~CAP_DEVNUM_MASK; \
(c)->attr |= CAP_DEVNUM_MASK & devnum;}
#define cap_devnum(c) \
(((c)->uattr[0] & CAP_DEVNUM_MASK) >> CAP_DEVNUM_SHIFT)
#define cap_devtype(c) ((c)->uattr[0] & CAP_DEVTYPE_MASK)
#define cap_irqno(c) ((c)->uattr[1])
(((c)->attr & CAP_DEVNUM_MASK) >> CAP_DEVNUM_SHIFT)
#define cap_devtype(c) ((c)->attr & CAP_DEVTYPE_MASK)
/*
* Access permissions
@@ -103,6 +102,14 @@
#define CAP_MAP_UNMAP (1 << 5)
#define CAP_MAP_UTCB (1 << 6)
/*
* IRQ Control capability
*
* This is a common one and it applies to both
* CAP_TYPE_IRQCTRL and CAP_TYPE_MAP_PHYSMEM
*/
#define CAP_IRQCTRL_REGISTER (1 << 7)
/* Ipc capability */
#define CAP_IPC_SEND (1 << 0)
#define CAP_IPC_RECV (1 << 1)

View File

@@ -104,4 +104,7 @@ int cap_ipc_check(l4id_t to, l4id_t from,
int cap_cap_check(struct ktcb *task, unsigned int req, unsigned int flags);
int cap_mutex_check(unsigned long mutex_address, int mutex_op);
int cap_irq_check(struct ktcb *registrant, unsigned int req,
unsigned int flags, l4id_t irq);
#endif /* __GENERIC_CAPABILITY_H__ */

View File

@@ -60,7 +60,8 @@ struct cap_info {
unsigned long start;
unsigned long end;
unsigned long size;
unsigned int uattr[2]; /* User-level attributes (like device types) */
unsigned int attr; /* Attributes (like device types) */
l4id_t irq;
};

View File

@@ -8,17 +8,18 @@
#include <l4/lib/string.h>
#include INC_PLAT(irq.h)
#include INC_ARCH(types.h)
/* Represents none or spurious irq */
#define IRQ_NIL (-1)
#define IRQ_NIL 0xFFFFFFFF
/* Successful irq handling state */
#define IRQ_HANDLED 0
typedef void (*irq_op_t)(int irq);
typedef void (*irq_op_t)(l4id_t irq);
struct irq_chip_ops {
void (*init)(void);
int (*read_irq)(void);
l4id_t (*read_irq)(void);
irq_op_t ack_and_mask;
irq_op_t unmask;
};
@@ -27,16 +28,24 @@ struct irq_chip {
char name[32];
int level; /* Cascading level */
int cascade; /* The irq that lower chip uses on this chip */
int offset; /* The global offset for this irq chip */
int start; /* The global irq offset for this chip */
int end; /* End of this chip's irqs */
struct irq_chip_ops ops;
};
typedef int (*irq_handler_t)(void);
struct irq_desc;
typedef int (*irq_handler_t)(struct irq_desc *irq_desc);
struct irq_desc {
char name[8];
struct irq_chip *chip;
/* TODO: This could be a list for multiple handlers */
/* Thread registered for this irq */
struct ktcb *irq_thread;
/* Notification slot for this irq */
int task_notify_slot;
/* NOTE: This could be a list for multiple handlers for shared irqs */
irq_handler_t handler;
};
@@ -48,7 +57,7 @@ static inline void irq_enable(int irq_index)
struct irq_desc *this_irq = irq_desc_array + irq_index;
struct irq_chip *this_chip = this_irq->chip;
this_chip->ops.unmask(irq_index - this_chip->offset);
this_chip->ops.unmask(irq_index - this_chip->start);
}
static inline void irq_disable(int irq_index)
@@ -56,23 +65,11 @@ static inline void irq_disable(int irq_index)
struct irq_desc *this_irq = irq_desc_array + irq_index;
struct irq_chip *this_chip = this_irq->chip;
this_chip->ops.ack_and_mask(irq_index - this_chip->offset);
this_chip->ops.ack_and_mask(irq_index - this_chip->start);
}
static inline void register_irq(char *name, int irq_index, irq_handler_t handler)
{
struct irq_desc *this_desc = irq_desc_array + irq_index;
struct irq_chip *current_chip = irq_chip_array;
strncpy(&this_desc->name[0], name, sizeof(this_desc->name));
for (int i = 0; i < IRQ_CHIPS_MAX; i++)
if (irq_index <= current_chip->offset) {
this_desc->chip = current_chip;
break;
}
this_desc->handler = handler;
}
int irq_register(struct ktcb *task, int notify_slot,
l4id_t irq_index, irq_handler_t handler);
void do_irq(void);
void irq_controllers_init(void);

View File

@@ -132,6 +132,9 @@ struct ktcb {
struct waitqueue_head wqh_send;
l4id_t expected_sender;
/* Waitqueue for notifiactions */
struct waitqueue_head wqh_notify;
/* Waitqueue for pagers to wait for task states */
struct waitqueue_head wqh_pager;
@@ -180,7 +183,7 @@ void ktcb_list_remove(struct ktcb *task, struct ktcb_list *ktcb_list);
void ktcb_list_add(struct ktcb *new, struct ktcb_list *ktcb_list);
void init_ktcb_list(struct ktcb_list *ktcb_list);
void task_update_utcb(struct ktcb *task);
int tcb_check_and_lazy_map_utcb(struct ktcb *task);
int tcb_check_and_lazy_map_utcb(struct ktcb *task, int page_in);
#endif /* __TCB_H__ */