Opened 13 years ago

Last modified 13 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 Nicolas Pouillon)

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

Conversion en png du schema dia

Soclib

Conversion en png du schema dia

Attachments (5)

irqs_soclib.dia (2.8 KB) - added by becoulet 13 years ago.
irqs_x86.dia (3.2 KB) - added by becoulet 13 years ago.
irqs_soclib.png (20.9 KB) - added by Nicolas Pouillon 13 years ago.
Conversion en png du schema dia
irqs_x86.png (24.6 KB) - added by Nicolas Pouillon 13 years ago.
Conversion en png du schema dia
icu.png (2.9 KB) - added by Nicolas Pouillon 13 years ago.

Download all attachments as: .zip

Change History (9)

comment:1 Changed 13 years ago by becoulet

Description: modified (diff)

Changed 13 years ago by becoulet

Attachment: irqs_soclib.dia added

Changed 13 years ago by becoulet

Attachment: irqs_x86.dia added

Changed 13 years ago by Nicolas Pouillon

Attachment: irqs_soclib.png added

Conversion en png du schema dia

Changed 13 years ago by Nicolas Pouillon

Attachment: irqs_x86.png added

Conversion en png du schema dia

comment:2 Changed 13 years ago by Nicolas Pouillon

Description: modified (diff)

Changed 13 years ago by Nicolas Pouillon

Attachment: icu.png added

comment:3 Changed 13 years ago by Nicolas Pouillon

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)

How can we get id = 5 in the current scheme ?

comment:4 in reply to:  3 Changed 13 years ago by becoulet

Replying to nipo:

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)

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.