mirror of
https://github.com/drasko/codezero.git
synced 2026-01-13 11:23:16 +01:00
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:
@@ -89,8 +89,9 @@ struct capability {
|
||||
/* Use count of resource */
|
||||
unsigned long used;
|
||||
|
||||
/* User attributes on capability such as device type, irqno */
|
||||
u32 uattr[2];
|
||||
/* Device attributes, if this is a device. */
|
||||
unsigned int attr;
|
||||
l4id_t irq;
|
||||
};
|
||||
|
||||
#endif /* __API_CAPABILITY_H__ */
|
||||
|
||||
@@ -139,5 +139,6 @@
|
||||
#define EACTIVE 132 /* Task active */
|
||||
#define ENOIPC 133 /* General IPC error */
|
||||
#define ENOCAP 134 /* None or insufficient capability */
|
||||
#define ENOUTCB 135 /* Task has no utcb set up */
|
||||
|
||||
#endif /* __ERRNO_H__ */
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#define __PL190_VIC_H__
|
||||
|
||||
#include INC_PLAT(platform.h)
|
||||
#include INC_ARCH(types.h)
|
||||
|
||||
#define PL190_BASE PLATFORM_IRQCTRL_BASE
|
||||
#define PL190_SIC_BASE PLATFORM_SIRQCTRL_BASE
|
||||
@@ -42,15 +43,16 @@
|
||||
#define PL190_SIC_PICENCLR (PL190_SIC_BASE + 0x24)
|
||||
|
||||
void pl190_vic_init(void);
|
||||
void pl190_ack_irq(int irq);
|
||||
void pl190_mask_irq(int irq);
|
||||
void pl190_unmask_irq(int irq);
|
||||
int pl190_read_irq(void);
|
||||
void pl190_ack_irq(l4id_t irq);
|
||||
void pl190_mask_irq(l4id_t irq);
|
||||
void pl190_unmask_irq(l4id_t irq);
|
||||
l4id_t pl190_read_irq(void);
|
||||
|
||||
int pl190_sic_read_irq(void);
|
||||
void pl190_sic_mask_irq(int irq);
|
||||
void pl190_sic_mask_irq(int irq);
|
||||
void pl190_sic_ack_irq(int irq);
|
||||
void pl190_sic_unmask_irq(int irq);
|
||||
l4id_t pl190_sic_read_irq(void);
|
||||
void pl190_sic_mask_irq(l4id_t irq);
|
||||
void pl190_sic_mask_irq(l4id_t irq);
|
||||
void pl190_sic_ack_irq(l4id_t irq);
|
||||
void pl190_sic_unmask_irq(l4id_t irq);
|
||||
void pl190_sic_init(void);
|
||||
|
||||
#endif /* __PL190_VIC_H__ */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
|
||||
@@ -78,12 +78,15 @@
|
||||
|
||||
#include INC_GLUE(memlayout.h)
|
||||
|
||||
#define TASK_NOTIFY_SLOTS 8
|
||||
#define TASK_NOTIFY_MAX 0xFF
|
||||
|
||||
#if !defined (__ASSEMBLY__)
|
||||
struct utcb {
|
||||
u32 mr[MR_TOTAL]; /* MRs that are mapped to real registers */
|
||||
u32 saved_tag; /* Saved tag field for stacked ipcs */
|
||||
u32 saved_sender; /* Saved sender field for stacked ipcs */
|
||||
u8 notify[8]; /* Notification slots */
|
||||
u8 notify[TASK_NOTIFY_SLOTS]; /* Notification slots */
|
||||
u32 mr_rest[MR_REST]; /* Complete the utcb for up to 64 words */
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -4,24 +4,47 @@
|
||||
#define IRQ_CHIPS_MAX 2
|
||||
#define IRQS_MAX 64
|
||||
|
||||
/* IRQ indices. */
|
||||
#define IRQ_TIMER01 4
|
||||
#define IRQ_TIMER23 5
|
||||
#define IRQ_RTC 10
|
||||
#define IRQ_UART0 12
|
||||
#define IRQ_UART1 13
|
||||
#define IRQ_UART2 14
|
||||
#define IRQ_SIC 31
|
||||
/* Global irq numbers */
|
||||
#define IRQ_TIMER01 (VIC_IRQ_TIMER01 + VIC_CHIP_OFFSET)
|
||||
#define IRQ_TIMER23 (VIC_IRQ_TIMER23 + VIC_CHIP_OFFSET)
|
||||
#define IRQ_RTC (VIC_IRQ_RTC + VIC_CHIP_OFFSET)
|
||||
#define IRQ_UART0 (VIC_IRQ_UART0 + VIC_CHIP_OFFSET)
|
||||
#define IRQ_UART1 (VIC_IRQ_UART1 + VIC_CHIP_OFFSET)
|
||||
#define IRQ_UART2 (VIC_IRQ_UART2 + VIC_CHIP_OFFSET)
|
||||
#define IRQ_SIC (VIC_IRQ_SIC + VIC_CHIP_OFFSET)
|
||||
|
||||
/* Cascading definitions */
|
||||
#define IRQ_SICSWI (SIC_IRQ_SWI + SIC_CHIP_OFFSET)
|
||||
#define IRQ_UART3 (SIC_IRQ_UART3 + SIC_CHIP_OFFSET)
|
||||
|
||||
#define PIC_IRQS_MAX 31 /* Total irqs on PIC */
|
||||
/* The local irq line of the dummy peripheral on this chip */
|
||||
#define LOCALIRQ_DUMMY 15
|
||||
/* The irq index offset of this chip, is the maximum of previous chip + 1 */
|
||||
#define SIRQ_CHIP_OFFSET (PIC_IRQS_MAX + 1)
|
||||
/* The global irq number of dummy is the local irq line + it's chip offset */
|
||||
#define IRQ_DUMMY (LOCALIRQ_DUMMY + SIRQ_CHIP_OFFSET)
|
||||
/* Vectored Interrupt Controller local IRQ numbers */
|
||||
#define VIC_IRQ_TIMER01 4
|
||||
#define VIC_IRQ_TIMER23 5
|
||||
#define VIC_IRQ_RTC 10
|
||||
#define VIC_IRQ_UART0 12
|
||||
#define VIC_IRQ_UART1 13
|
||||
#define VIC_IRQ_UART2 14
|
||||
#define VIC_IRQ_SIC 31
|
||||
|
||||
/* Secondary Interrupt controller local IRQ numbers */
|
||||
#define SIC_IRQ_SWI 0
|
||||
#define SIC_IRQ_UART3 6
|
||||
|
||||
/* Maximum irqs on VIC and SIC */
|
||||
#define VIC_IRQS_MAX 32
|
||||
#define SIC_IRQS_MAX 32
|
||||
|
||||
|
||||
/*
|
||||
* Globally unique irq chip offsets:
|
||||
*
|
||||
* A global irq number is calculated as
|
||||
* chip_offset + local_irq_offset.
|
||||
*
|
||||
* This way, the global irq number uniquely represents
|
||||
* an irq on any irq chip.
|
||||
*/
|
||||
#define VIC_CHIP_OFFSET 0
|
||||
#define SIC_CHIP_OFFSET 32
|
||||
|
||||
|
||||
#endif /* __PLATFORM_IRQ_H__ */
|
||||
|
||||
Reference in New Issue
Block a user