Opened 14 years ago
Last modified 14 years ago
#59 new enhancement
Devices irqs handling and irqs topology
Reported by: | becoulet | Owned by: | Nicolas Pouillon |
---|---|---|---|
Priority: | major | Milestone: | Topology handling |
Component: | drivers | Keywords: | |
Cc: |
Description (last modified by )
Change devices IRQ handling and use an IRQ lines topology graph.
API proposal in pseudo C:
enum irq_ep_type_e { IRQ_EP_SOURCE, IRQ_EP_SINK, IRQ_EP_MIXED }; struct irq_ep_s { /** endpoint type, may only be usefull for checking */ enum irq_ep_type_e type; /** source ep: link to device which may raise irq, sink ep: link to device which can handle irq */ struct device_s *dev; /** source ep: list of sink ep which can recieve the irq signal, sink ep: list of source ep which can relay this irq */ ep_list_root_t links; CLIST list_entry; }; /* FIXME both endpoints have the same structure, should we merge?*/ /********** devices drivers API */ /** @this is handling function of device node. @param src end point which relayed the irq @param id local identifier of irq line for relaying device, must be updated to next local id by icu devs. Must be changed to -1 when no irq were pending. Non-icu devices only set to -1 or 0. @return pointer to next icu device or NULL The next sink endpoint may be found from icu registers or passed id. On some systems the icu passes the decoded vector id to the processor in hardware and we need a way to pass the value back to icu handler from processor handler. */ #define IRQ_EVENT(n) struct irq_ep_s (*n)(struct irq_ep_s *src, \ intptr_t *id) typedef IRQ_EVENT(irq_event_t); /** irq ack function for *icu devs* only */ #define IRQ_ACK(n) void (*n)(struct irq_ep_s *src, \ intptr_t id) typedef IRQ_ACK(irq_ack_t); /********** global irq processing code */ /** @return true if irq were handled */ bool_t irq_src_process(struct irq_ep_s *src, intptr_t id) { assert(src->type != IRQ_EP_SINK); /* process irq and get next sink */ intptr_t next_id = id; struct irq_ep_s *sink = src->dev->irq_event(src, &next_id); assert(sink->type != IRQ_EP_SOURCE); if (sink == NULL) return next_id == 0; /* not an icu device */ bool_t done = irq_sink_process(sink, next_id); /* for icu devs only */ src->dev->irq_ack(src, id); return done; } bool_t irq_sink_process(struct irq_ep_s *sink, intptr_t id) { bool_t done = 0; assert(sink->type != IRQ_EP_SOURCE); /* for all source connected to icu sink, process */ FOREACH(src, sink->links) done |= irq_src_process(src, id); return done; } /********** cpu irq handling code */ static irq_ep_s cpu_irq_lines[CPU_LINES_COUNT]; CPU_INTERRUPT_HANDLER(irq_handler) { irq_sink_process(cpu_irq_lines + irq, irq); /* may check for lost irqs here */ }
x86
Soclib
Attachments (5)
Change History (9)
comment:1 Changed 14 years ago by
Description: | modified (diff) |
---|
Changed 14 years ago by
Attachment: | irqs_soclib.dia added |
---|
Changed 14 years ago by
Attachment: | irqs_x86.dia added |
---|
Changed 14 years ago by
Attachment: | irqs_soclib.png added |
---|
comment:2 Changed 14 years ago by
Description: | modified (diff) |
---|
Changed 14 years ago by
comment:3 follow-up: 4 Changed 14 years ago by
In the following image:
Let's say d0
has an interrupt line routed to c2,1
through icu0,5
.
Trace should be like:
- in cpu irq handler, call
irq_event(c2, 1)
- find it routes to
icu0
, with id = 5 (not available) - icu0 decodes the priority for its input line 5, and finds it corresponds to input #0
- call
irq_event(d0, 0)
- call
- find it routes to
How can we get id = 5 in the current scheme ?
comment:4 Changed 14 years ago by
Replying to nipo:
In the following image:
Let's say
d0
has an interrupt line routed toc2,1
throughicu0,5
.Trace should be like:
- in cpu irq handler, call
irq_event(c2, 1)
- find it routes to
icu0
, with id = 5 (not available)- icu0 decodes the priority for its input line 5, and finds it corresponds to input #0
- call
irq_event(d0, 0)
How can we get id = 5 in the current scheme ?
What append is:
- c2 has two sink endpoints c2_sink_0 and c2_sink_1 and no vector id is multiplexed so id is not used here
- irq_event(icu_src_5, 0) is called because icu_src_5 ep is linked to c2_sink_1
- icu0 has internal data attached to icu_src_5 ep and use it to routes to icu_sink_0
- irq_event(d0_src_0, 0) is called.
Note: See
TracTickets for help on using
tickets.
Conversion en png du schema dia