<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Feb 12, 2021 at 7:38 PM <<a href="mailto:chrisj@rtems.org">chrisj@rtems.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">From: Chris Johns <<a href="mailto:chrisj@rtems.org" target="_blank">chrisj@rtems.org</a>><br>
<br>
- Add support to the BSP to enable irq-generic management<br>
<br>
- Update the powerpc shared irq code to support irq-generic. This<br>
  is an option in option for existing powerpc bsps. This change<br></blockquote><div><br></div><div>Probably just an option. :)</div><div><br></div><div>I'm cool with the patch. This code is all over the place formatting</div><div>wise and caution is advised.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
  should be simpler now<br>
<br>
- Fix a number of issues in ISA IRQ controller handling by porting<br>
  fixes from the i386 (PC) BSP<br>
<br>
Closes #4238<br>
Closes #4239<br>
---<br>
 bsps/powerpc/include/bsp/irq_supp.h           |   5 +<br>
 .../motorola_powerpc/include/bsp/irq.h        |  15 +-<br>
 .../powerpc/motorola_powerpc/start/bspstart.c |   7 +-<br>
 bsps/powerpc/shared/irq/i8259.c               | 152 ++++++++++++++----<br>
 bsps/powerpc/shared/irq/irq_init.c            |  15 +-<br>
 bsps/powerpc/shared/irq/openpic_i8259_irq.c   |  27 ++--<br>
 bsps/powerpc/shared/irq/ppc-irq-generic.c     | 117 ++++++++++++++<br>
 .../bsps/powerpc/motorola_powerpc/grp.yml     |   2 +-<br>
 .../bsps/powerpc/motorola_powerpc/obj.yml     |   3 +-<br>
 9 files changed, 286 insertions(+), 57 deletions(-)<br>
 create mode 100644 bsps/powerpc/shared/irq/ppc-irq-generic.c<br>
<br>
diff --git a/bsps/powerpc/include/bsp/irq_supp.h b/bsps/powerpc/include/bsp/irq_supp.h<br>
index 65af48c87f..fbb16d6211 100644<br>
--- a/bsps/powerpc/include/bsp/irq_supp.h<br>
+++ b/bsps/powerpc/include/bsp/irq_supp.h<br>
@@ -50,6 +50,11 @@ extern int  BSP_disable_irq_at_pic(const rtems_irq_number irqLine);<br>
  */<br>
 extern int  BSP_setup_the_pic(rtems_irq_global_settings* config);<br>
<br>
+/*<br>
+ * Set up for the irq-generic.h interface.<br>
+ */<br>
+int BSP_rtems_irq_generic_set(rtems_irq_global_settings* config);<br>
+<br>
 /* IRQ dispatcher to be defined by the PIC driver; note that it MUST<br>
  * implement shared interrupts.<br>
  * Note also that the exception frame passed to this handler is not very<br>
diff --git a/bsps/powerpc/motorola_powerpc/include/bsp/irq.h b/bsps/powerpc/motorola_powerpc/include/bsp/irq.h<br>
index 3690dbbff7..cbb6ff69cf 100644<br>
--- a/bsps/powerpc/motorola_powerpc/include/bsp/irq.h<br>
+++ b/bsps/powerpc/motorola_powerpc/include/bsp/irq.h<br>
@@ -19,9 +19,17 @@<br>
 #ifndef BSP_POWERPC_IRQ_H<br>
 #define BSP_POWERPC_IRQ_H<br>
<br>
+#ifndef BSP_SHARED_HANDLER_SUPPORT<br>
 #define BSP_SHARED_HANDLER_SUPPORT      1<br>
+#endif<br>
+<br>
 #include <rtems/irq.h><br>
-#include <bsp/irq-default.h><br>
+<br>
+/*<br>
+ * Switch to using the generic support. Remove this when all BSPs have<br>
+ * been converted.<br>
+ */<br>
+#define BSP_POWERPC_IRQ_GENERIC_SUPPORT 1<br>
<br>
 /*<br>
  * 8259 edge/level control definitions at VIA<br>
@@ -107,6 +115,8 @@ extern "C" {<br>
 #define BSP_IRQ_NUMBER                 (BSP_MISC_IRQ_MAX_OFFSET + 1)<br>
 #define BSP_LOWEST_OFFSET              (BSP_ISA_IRQ_LOWEST_OFFSET)<br>
 #define BSP_MAX_OFFSET                 (BSP_MISC_IRQ_MAX_OFFSET)<br>
+#define BSP_INTERRUPT_VECTOR_MIN       (BSP_LOWEST_OFFSET)<br>
+#define BSP_INTERRUPT_VECTOR_MAX       (BSP_MAX_OFFSET)<br>
 /*<br>
  * Some ISA IRQ symbolic name definition<br>
  */<br>
@@ -191,6 +201,9 @@ int BSP_irq_ack_at_i8259s                   (const rtems_irq_number irqLine);<br>
  */<br>
 int BSP_irq_enabled_at_i8259s          (const rtems_irq_number irqLine);<br>
<br>
+unsigned short BSP_irq_suspend_i8259s(unsigned short mask);<br>
+void BSP_irq_resume_i8259s(unsigned short in_progress_save);<br>
+<br>
 extern void BSP_rtems_irq_mng_init(unsigned cpuId);<br>
 extern void BSP_i8259s_init(void);<br>
<br>
diff --git a/bsps/powerpc/motorola_powerpc/start/bspstart.c b/bsps/powerpc/motorola_powerpc/start/bspstart.c<br>
index e74b02c446..ef8418e2c6 100644<br>
--- a/bsps/powerpc/motorola_powerpc/start/bspstart.c<br>
+++ b/bsps/powerpc/motorola_powerpc/start/bspstart.c<br>
@@ -27,6 +27,7 @@<br>
 #include <bsp/pci.h><br>
 #include <bsp/openpic.h><br>
 #include <bsp/irq.h><br>
+#include <bsp/irq-generic.h><br>
 #include <libcpu/bat.h><br>
 #include <libcpu/pte121.h><br>
 #include <libcpu/cpuIdent.h><br>
@@ -334,10 +335,8 @@ static void bsp_early( void )<br>
    */<br>
   bsp_clicks_per_usec   = BSP_bus_frequency/(BSP_time_base_divisor * 1000);<br>
<br>
-  /*<br>
-   * Initalize RTEMS IRQ system<br>
-   */<br>
-  BSP_rtems_irq_mng_init(0);<br>
+  /* Initialize interrupt support */<br>
+  bsp_interrupt_initialize();<br>
<br>
   /* Activate the page table mappings only after<br>
    * initializing interrupts because the irq_mng_init()<br>
diff --git a/bsps/powerpc/shared/irq/i8259.c b/bsps/powerpc/shared/irq/i8259.c<br>
index 7363e87ba0..6a80e24946 100644<br>
--- a/bsps/powerpc/shared/irq/i8259.c<br>
+++ b/bsps/powerpc/shared/irq/i8259.c<br>
@@ -12,6 +12,19 @@<br>
 #include <bsp.h><br>
 #include <bsp/irq.h><br>
<br>
+#define PIC_EOSI        0x60    ///< End of Specific Interrupt (EOSI)<br>
+#define PIC_EOI         0x20    ///< Generic End of Interrupt (EOI)<br>
+<br>
+/* Operation control word type 3.  Bit 3 (0x08) must be set. Even address. */<br>
+#define PIC_OCW3_RIS        0x01            /* 1 = read IS, 0 = read IR */<br>
+#define PIC_OCW3_RR         0x02            /* register read */<br>
+#define PIC_OCW3_P          0x04            /* poll mode command */<br>
+/* 0x08 must be 1 to select OCW3 vs OCW2 */<br>
+#define PIC_OCW3_SEL        0x08            /* must be 1 */<br>
+/* 0x10 must be 0 to select OCW3 vs ICW1 */<br>
+#define PIC_OCW3_SMM        0x20            /* special mode mask */<br>
+#define PIC_OCW3_ESMM       0x40            /* enable SMM */<br>
+<br>
 /*-------------------------------------------------------------------------+<br>
 | Cache for 1st and 2nd PIC IRQ line's status (enabled or disabled) register.<br>
 +--------------------------------------------------------------------------*/<br>
@@ -19,91 +32,137 @@<br>
  * lower byte is interrupt mask on the master PIC.<br>
  * while upper bits are interrupt on the slave PIC.<br>
  */<br>
-volatile rtems_i8259_masks i8259s_cache = 0xfffb;<br>
+static rtems_i8259_masks i8259s_imr_cache = 0xFFFB;<br>
+static rtems_i8259_masks i8259s_in_progress = 0;<br>
+<br>
+static inline<br>
+void BSP_i8259s_irq_update_master_imr( void )<br>
+{<br>
+  rtems_i8259_masks mask = i8259s_in_progress | i8259s_imr_cache;<br>
+  outport_byte( PIC_MASTER_IMR_IO_PORT, mask & 0xff );<br>
+}<br>
+<br>
+static inline<br>
+void BSP_i8259s_irq_update_slave_imr( void )<br>
+{<br>
+  rtems_i8259_masks mask = i8259s_in_progress | i8259s_imr_cache;<br>
+  outport_byte( PIC_SLAVE_IMR_IO_PORT, ( mask >> 8 ) & 0xff );<br>
+}<br>
+<br>
+/*<br>
+ * Is the IRQ valid?<br>
+ */<br>
+static inline bool BSP_i8259s_irq_valid(const rtems_irq_number irqLine)<br>
+{<br>
+  return ((int)irqLine >= BSP_ISA_IRQ_LOWEST_OFFSET) &&<br>
+    ((int)irqLine <= BSP_ISA_IRQ_MAX_OFFSET);<br>
+}<br>
+<br>
+/*<br>
+ * Read the IRR register. The default.<br>
+ */<br>
+static inline uint8_t BSP_i8259s_irq_int_request_reg(uint32_t ioport)<br>
+{<br>
+  uint8_t isr;<br>
+  inport_byte(ioport, isr);<br>
+  return isr;<br>
+}<br>
+<br>
+/*<br>
+ * Read the ISR register. Keep the default of the IRR.<br>
+ */<br>
+static inline uint8_t BSP_i8259s_irq_in_service_reg(uint32_t ioport)<br>
+{<br>
+  uint8_t isr;<br>
+  outport_byte(ioport, PIC_OCW3_SEL | PIC_OCW3_RR | PIC_OCW3_RIS);<br>
+  inport_byte(ioport, isr);<br>
+  outport_byte(ioport, PIC_OCW3_SEL | PIC_OCW3_RR);<br>
+  return isr;<br>
+}<br>
<br>
 /*-------------------------------------------------------------------------+<br>
 |         Function:  BSP_irq_disable_at_i8259s<br>
 |      Description: Mask IRQ line in appropriate PIC chip.<br>
-| Global Variables: i8259s_cache<br>
+| Global Variables: i8259s_imr_cache, i8259s_in_progress<br>
 |        Arguments: vector_offset - number of IRQ line to mask.<br>
-|          Returns: original state or -1 on error.<br>
+|          Returns: 0 is OK.<br>
 +--------------------------------------------------------------------------*/<br>
-int BSP_irq_disable_at_i8259s    (const rtems_irq_number irqLine)<br>
+int BSP_irq_disable_at_i8259s(const rtems_irq_number irqLine)<br>
 {<br>
   unsigned short        mask;<br>
   rtems_interrupt_level level;<br>
-  int                   rval;<br>
<br>
-  if ( ((int)irqLine < BSP_ISA_IRQ_LOWEST_OFFSET) ||<br>
-       ((int)irqLine > BSP_ISA_IRQ_MAX_OFFSET)<br>
-       )<br>
+  if (!BSP_i8259s_irq_valid(irqLine))<br>
     return -1;<br>
<br>
   rtems_interrupt_disable(level);<br>
<br>
   mask = 1 << irqLine;<br>
-  rval = i8259s_cache & mask ? 0 : 1;<br>
-  i8259s_cache |= mask;<br>
+  i8259s_imr_cache |= mask;<br>
<br>
   if (irqLine < 8)<br>
   {<br>
-    outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);<br>
+    BSP_i8259s_irq_update_master_imr();<br>
   }<br>
   else<br>
   {<br>
-    outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));<br>
+    BSP_i8259s_irq_update_slave_imr();<br>
   }<br>
+<br>
   rtems_interrupt_enable(level);<br>
<br>
-  return rval;<br>
+  return 0;<br>
 }<br>
<br>
 /*-------------------------------------------------------------------------+<br>
 |         Function:  BSP_irq_enable_at_i8259s<br>
 |      Description: Unmask IRQ line in appropriate PIC chip.<br>
-| Global Variables: i8259s_cache<br>
+| Global Variables: i8259s_imr_cache, i8259s_in_progress<br>
 |        Arguments: irqLine - number of IRQ line to mask.<br>
 |          Returns: Nothing.<br>
 +--------------------------------------------------------------------------*/<br>
-int BSP_irq_enable_at_i8259s    (const rtems_irq_number irqLine)<br>
+int BSP_irq_enable_at_i8259s(const rtems_irq_number irqLine)<br>
 {<br>
-  unsigned short        mask;<br>
   rtems_interrupt_level level;<br>
+  unsigned short        mask;<br>
+  uint8_t               isr;<br>
+  uint8_t               irr;<br>
<br>
-  if ( ((int)irqLine < BSP_ISA_IRQ_LOWEST_OFFSET) ||<br>
-       ((int)irqLine > BSP_ISA_IRQ_MAX_OFFSET )<br>
-       )<br>
+  if (!BSP_i8259s_irq_valid(irqLine))<br>
     return 1;<br>
<br>
   rtems_interrupt_disable(level);<br>
<br>
-  mask = ~(1 << irqLine);<br>
-  i8259s_cache &= mask;<br>
+  mask = 1 << irqLine;<br>
+  i8259s_imr_cache &= ~mask;<br>
<br>
   if (irqLine < 8)<br>
   {<br>
-    outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);<br>
+    isr = BSP_i8259s_irq_in_service_reg(PIC_MASTER_COMMAND_IO_PORT);<br>
+    irr = BSP_i8259s_irq_int_request_reg(PIC_MASTER_COMMAND_IO_PORT);<br>
+    BSP_i8259s_irq_update_master_imr();<br>
   }<br>
   else<br>
   {<br>
-    outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));<br>
+    isr = BSP_i8259s_irq_in_service_reg(PIC_SLAVE_COMMAND_IO_PORT);<br>
+    irr = BSP_i8259s_irq_int_request_reg(PIC_SLAVE_COMMAND_IO_PORT);<br>
+    BSP_i8259s_irq_update_slave_imr();<br>
   }<br>
+<br>
   rtems_interrupt_enable(level);<br>
<br>
   return 0;<br>
 } /* mask_irq */<br>
<br>
-int BSP_irq_enabled_at_i8259s          (const rtems_irq_number irqLine)<br>
+int BSP_irq_enabled_at_i8259s(const rtems_irq_number irqLine)<br>
 {<br>
   unsigned short mask;<br>
<br>
-  if ( ((int)irqLine < BSP_ISA_IRQ_LOWEST_OFFSET) ||<br>
-       ((int)irqLine > BSP_ISA_IRQ_MAX_OFFSET)<br>
-     )<br>
+  if (!BSP_i8259s_irq_valid(irqLine))<br>
     return 1;<br>
<br>
   mask = (1 << irqLine);<br>
-  return  (~(i8259s_cache & mask));<br>
+  return  (~(i8259s_imr_cache & mask));<br>
 }<br>
<br>
 /*-------------------------------------------------------------------------+<br>
@@ -113,24 +172,47 @@ int BSP_irq_enabled_at_i8259s             (const rtems_irq_number irqLine)<br>
 |        Arguments: irqLine - number of IRQ line to acknowledge.<br>
 |          Returns: Nothing.<br>
 +--------------------------------------------------------------------------*/<br>
-int BSP_irq_ack_at_i8259s      (const rtems_irq_number irqLine)<br>
+int BSP_irq_ack_at_i8259s(const rtems_irq_number irqLine)<br>
 {<br>
+  uint8_t slave_isr = 0;<br>
+<br>
   if (irqLine >= 8) {<br>
-    outport_byte(PIC_MASTER_COMMAND_IO_PORT, SLAVE_PIC_EOSI);<br>
-    outport_byte(PIC_SLAVE_COMMAND_IO_PORT, (PIC_EOSI | (irqLine - 8)));<br>
-  }<br>
-  else {<br>
-    outport_byte(PIC_MASTER_COMMAND_IO_PORT, (PIC_EOSI | irqLine));<br>
+   outport_byte(PIC_SLAVE_COMMAND_IO_PORT, PIC_EOI);<br>
+   slave_isr = BSP_i8259s_irq_in_service_reg(PIC_SLAVE_COMMAND_IO_PORT);<br>
   }<br>
<br>
+  /*<br>
+   * Only issue the EOI to the master if there are no more interrupts in<br>
+   * service for the slave. i8259a data sheet page 18, The Special Fully Nested<br>
+   * Mode, b.<br>
+   */<br>
+  if (slave_isr == 0)<br>
+    outport_byte(PIC_MASTER_COMMAND_IO_PORT, PIC_EOI);<br>
+<br>
   return 0;<br>
<br>
 } /* ackIRQ */<br>
<br>
+unsigned short BSP_irq_suspend_i8259s(unsigned short mask)<br>
+{<br>
+  unsigned short in_progress_save = i8259s_in_progress;<br>
+  i8259s_in_progress |= mask;<br>
+  BSP_i8259s_irq_update_master_imr();<br>
+  BSP_i8259s_irq_update_slave_imr();<br>
+  return in_progress_save;<br>
+}<br>
+<br>
+void BSP_irq_resume_i8259s(unsigned short in_progress_save)<br>
+{<br>
+  i8259s_in_progress = in_progress_save;<br>
+  BSP_i8259s_irq_update_master_imr();<br>
+  BSP_i8259s_irq_update_slave_imr();<br>
+}<br>
+<br>
 void BSP_i8259s_init(void)<br>
 {<br>
   /*<br>
-   * init master 8259 interrupt controller<br>
+   * Always mask at least current interrupt to prevent re-entrance<br>
    */<br>
   outport_byte(PIC_MASTER_COMMAND_IO_PORT, 0x11); /* Start init sequence */<br>
   outport_byte(PIC_MASTER_IMR_IO_PORT, 0x00);/* Vector base  = 0 */<br>
diff --git a/bsps/powerpc/shared/irq/irq_init.c b/bsps/powerpc/shared/irq/irq_init.c<br>
index 1042c9d1a8..233c659b85 100644<br>
--- a/bsps/powerpc/shared/irq/irq_init.c<br>
+++ b/bsps/powerpc/shared/irq/irq_init.c<br>
@@ -280,6 +280,7 @@ void BSP_rtems_irq_mng_init(unsigned cpuId)<br>
   int known_cpi_isa_bridge = 0;<br>
 #endif<br>
   int i;<br>
+  int r;<br>
<br>
   /*<br>
    * First initialize the Interrupt management hardware<br>
@@ -351,7 +352,19 @@ void BSP_rtems_irq_mng_init(unsigned cpuId)<br>
     initial_config.irqBase     = BSP_LOWEST_OFFSET;<br>
     initial_config.irqPrioTbl  = irqPrioTable;<br>
<br>
-    if (!BSP_rtems_irq_mngt_set(&initial_config)) {<br>
+#ifdef BSP_POWERPC_IRQ_GENERIC_SUPPORT<br>
+#ifdef TRACE_IRQ_INIT<br>
+    printk("RTEMS IRQ management: irq-generic\n");<br>
+#endif<br>
+    r = BSP_rtems_irq_generic_set(&initial_config);<br>
+#else<br>
+#ifdef TRACE_IRQ_INIT<br>
+    printk("RTEMS IRQ management: legacy\n");<br>
+#endif<br>
+    r = BSP_rtems_irq_mngt_set(&initial_config);<br>
+#endif<br>
+<br>
+    if (!r) {<br>
       /*<br>
        * put something here that will show the failure...<br>
        */<br>
diff --git a/bsps/powerpc/shared/irq/openpic_i8259_irq.c b/bsps/powerpc/shared/irq/openpic_i8259_irq.c<br>
index 513b9ac3e0..2617555658 100644<br>
--- a/bsps/powerpc/shared/irq/openpic_i8259_irq.c<br>
+++ b/bsps/powerpc/shared/irq/openpic_i8259_irq.c<br>
@@ -15,6 +15,7 @@<br>
 #include <bsp.h><br>
 #include <bsp/irq.h><br>
 #include <bsp/irq_supp.h><br>
+#include <bsp/irq-generic.h><br>
 #ifndef BSP_HAS_NO_VME<br>
 #include <bsp/VMEConfig.h><br>
 #endif<br>
@@ -234,15 +235,15 @@ int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)<br>
 #if BSP_ISA_IRQ_NUMBER > 0<br>
   register unsigned isaIntr;                  /* boolean */<br>
   register unsigned oldMask = 0;             /* old isa pic masks */<br>
-  register unsigned newMask;                  /* new isa pic masks */<br>
 #endif<br>
<br>
   if (excNum == ASM_DEC_VECTOR) {<br>
-<br>
-       bsp_irq_dispatch_list(rtems_hdl_tbl, BSP_DECREMENTER, default_rtems_entry.hdl);<br>
-<br>
+#ifdef BSP_POWERPC_IRQ_GENERIC_SUPPORT<br>
+    bsp_interrupt_handler_dispatch(BSP_DECREMENTER);<br>
+#else<br>
+    bsp_irq_dispatch_list(rtems_hdl_tbl, BSP_DECREMENTER, default_rtems_entry.hdl);<br>
+#endif<br>
     return 0;<br>
-<br>
   }<br>
<br>
 #if BSP_PCI_IRQ_NUMBER > 0<br>
@@ -274,7 +275,7 @@ int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)<br>
<br>
 #if BSP_ISA_IRQ_NUMBER > 0<br>
 #ifdef BSP_PCI_ISA_BRIDGE_IRQ<br>
-#if 0 == BSP_PCI_IRQ_NUMBER <br>
+#if 0 == BSP_PCI_IRQ_NUMBER<br>
 #error "Configuration Error -- BSP w/o PCI IRQs MUST NOT define BSP_PCI_ISA_BRIDGE_IRQ"<br>
 #endif<br>
   isaIntr = (irq == BSP_PCI_ISA_BRIDGE_IRQ);<br>
@@ -289,11 +290,7 @@ int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)<br>
     /*<br>
      * store current PIC mask<br>
      */<br>
-    oldMask = i8259s_cache;<br>
-    newMask = oldMask | irq_mask_or_tbl [irq];<br>
-    i8259s_cache = newMask;<br>
-    outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);<br>
-    outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));<br>
+    oldMask = BSP_irq_suspend_i8259s(irq_mask_or_tbl [irq]);<br>
     BSP_irq_ack_at_i8259s (irq);<br>
 #if BSP_PCI_IRQ_NUMBER > 0<br>
        if ( OpenPIC )<br>
@@ -303,13 +300,15 @@ int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)<br>
 #endif<br>
<br>
   /* dispatch handlers */<br>
+#ifdef BSP_POWERPC_IRQ_GENERIC_SUPPORT<br>
+  bsp_interrupt_handler_dispatch(irq);<br>
+#else<br>
   bsp_irq_dispatch_list(rtems_hdl_tbl, irq, default_rtems_entry.hdl);<br>
+#endif<br>
<br>
 #if BSP_ISA_IRQ_NUMBER > 0<br>
   if (isaIntr)  {<br>
-    i8259s_cache = oldMask;<br>
-    outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);<br>
-    outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));<br>
+    BSP_irq_resume_i8259s(oldMask);<br>
   }<br>
   else<br>
 #endif<br>
diff --git a/bsps/powerpc/shared/irq/ppc-irq-generic.c b/bsps/powerpc/shared/irq/ppc-irq-generic.c<br>
new file mode 100644<br>
index 0000000000..8a70109e52<br>
--- /dev/null<br>
+++ b/bsps/powerpc/shared/irq/ppc-irq-generic.c<br>
@@ -0,0 +1,117 @@<br>
+/* SPDX-License-Identifier: BSD-2-Clause */<br>
+<br>
+/**<br>
+ * @file<br>
+ *<br>
+ * @ingroup RTEMSBSPsPowerPC<br>
+ *<br>
+ * @brief Generic Interrupt suppoer<br>
+ */<br>
+<br>
+/*<br>
+ * Copyright (C) 2021 Chris Johns. All rights reserved.<br>
+ *<br>
+ * Redistribution and use in source and binary forms, with or without<br>
+ * modification, are permitted provided that the following conditions<br>
+ * are met:<br>
+ * 1. Redistributions of source code must retain the above copyright<br>
+ *    notice, this list of conditions and the following disclaimer.<br>
+ * 2. Redistributions in binary form must reproduce the above copyright<br>
+ *    notice, this list of conditions and the following disclaimer in the<br>
+ *    documentation and/or other materials provided with the distribution.<br>
+ *<br>
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"<br>
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE<br>
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE<br>
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE<br>
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR<br>
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF<br>
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS<br>
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN<br>
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)<br>
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE<br>
+ * POSSIBILITY OF SUCH DAMAGE.<br>
+ */<br>
+<br>
+#include <stdlib.h><br>
+<br>
+#include <rtems.h><br>
+#include <stdlib.h><br>
+#include <rtems/bspIo.h> /* for printk */<br>
+#include <libcpu/spr.h><br>
+#include <bsp/irq_supp.h><br>
+#include <bsp/irq-generic.h><br>
+#include <bsp/vectors.h><br>
+<br>
+SPR_RW(BOOKE_TSR)<br>
+SPR_RW(PPC405_TSR)<br>
+<br>
+/* legacy mode for bookE DEC exception;<br>
+ * to avoid the double layer of function calls<br>
+ * (dec_handler_bookE -> C_dispatch_irq_handler -> user handler)<br>
+ * it is preferrable for the user to hook the DEC<br>
+ * exception directly.<br>
+ * However, the legacy mode works with less modifications<br>
+ * of user code.<br>
+ */<br>
+static int C_dispatch_dec_handler_bookE (BSP_Exception_frame *frame, unsigned int excNum)<br>
+{<br>
+  /* clear interrupt; we must do this<br>
+   * before C_dispatch_irq_handler()<br>
+   * re-enables MSR_EE.<br>
+   * Note that PPC405 uses a different SPR# for TSR<br>
+   */<br>
+  if (ppc_cpu_is_bookE()==PPC_BOOKE_405)<br>
+    _write_PPC405_TSR( BOOKE_TSR_DIS );<br>
+  else<br>
+    _write_BOOKE_TSR( BOOKE_TSR_DIS );<br>
+  return C_dispatch_irq_handler(frame, ASM_DEC_VECTOR);<br>
+}<br>
+<br>
+/*<br>
+ * RTEMS Global Interrupt Handler Management Routines<br>
+ */<br>
+int BSP_rtems_irq_generic_set(rtems_irq_global_settings* config)<br>
+{<br>
+  int r;<br>
+<br>
+  r = BSP_setup_the_pic(config);<br>
+  if (!r)<br>
+    return r;<br>
+<br>
+  ppc_exc_set_handler(ASM_EXT_VECTOR, C_dispatch_irq_handler);<br>
+  if ( ppc_cpu_is_bookE() ) {<br>
+    /* bookE decrementer interrupt needs to be cleared BEFORE<br>
+     * dispatching the user ISR (because the user ISR is called<br>
+     * with EE enabled)<br>
+     * We do this so that existing DEC handlers can be used<br>
+     * with minor modifications.<br>
+     */<br>
+    ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, C_dispatch_dec_handler_bookE);<br>
+  } else {<br>
+    ppc_exc_set_handler(ASM_DEC_VECTOR, C_dispatch_irq_handler);<br>
+  }<br>
+<br>
+  return 1;<br>
+}<br>
+<br>
+void bsp_interrupt_vector_enable(rtems_vector_number vector)<br>
+{<br>
+  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));<br>
+  BSP_enable_irq_at_pic(vector);<br>
+}<br>
+<br>
+void bsp_interrupt_vector_disable(rtems_vector_number vector)<br>
+{<br>
+  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));<br>
+  BSP_disable_irq_at_pic(vector);<br>
+}<br>
+<br>
+rtems_status_code bsp_interrupt_facility_initialize(void)<br>
+{<br>
+  /*<br>
+   * Initialize RTEMS IRQ system<br>
+   */<br>
+  BSP_rtems_irq_mng_init(0);<br>
+  return RTEMS_SUCCESSFUL;<br>
+}<br>
diff --git a/spec/build/bsps/powerpc/motorola_powerpc/grp.yml b/spec/build/bsps/powerpc/motorola_powerpc/grp.yml<br>
index f256fec10f..a3ad2b115d 100644<br>
--- a/spec/build/bsps/powerpc/motorola_powerpc/grp.yml<br>
+++ b/spec/build/bsps/powerpc/motorola_powerpc/grp.yml<br>
@@ -10,7 +10,7 @@ links:<br>
 - role: build-dependency<br>
   uid: ../../obj<br>
 - role: build-dependency<br>
-  uid: ../../objirqdflt<br>
+  uid: ../../objirq<br>
 - role: build-dependency<br>
   uid: ../crti<br>
 - role: build-dependency<br>
diff --git a/spec/build/bsps/powerpc/motorola_powerpc/obj.yml b/spec/build/bsps/powerpc/motorola_powerpc/obj.yml<br>
index 07ee6fa721..ae7b9f96e2 100644<br>
--- a/spec/build/bsps/powerpc/motorola_powerpc/obj.yml<br>
+++ b/spec/build/bsps/powerpc/motorola_powerpc/obj.yml<br>
@@ -39,7 +39,7 @@ source:<br>
 - bsps/powerpc/shared/irq/irq_init.c<br>
 - bsps/powerpc/shared/irq/openpic.c<br>
 - bsps/powerpc/shared/irq/openpic_i8259_irq.c<br>
-- bsps/powerpc/shared/irq/ppc-irq-legacy.c<br>
+- bsps/powerpc/shared/irq/ppc-irq-generic.c<br>
 - bsps/powerpc/shared/mmu/bat.c<br>
 - bsps/powerpc/shared/mmu/mmuAsm.S<br>
 - bsps/powerpc/shared/mmu/pte121.c<br>
@@ -57,5 +57,6 @@ source:<br>
 - bsps/powerpc/shared/start/zerobss.c<br>
 - bsps/shared/dev/getentropy/getentropy-cpucounter.c<br>
 - bsps/shared/dev/rtc/rtc-support.c<br>
+- bsps/shared/irq/irq-default-handler.c<br>
 - bsps/shared/start/bspfatal-default.c<br>
 type: build<br>
-- <br>
2.24.1<br>
<br>
_______________________________________________<br>
devel mailing list<br>
<a href="mailto:devel@rtems.org" target="_blank">devel@rtems.org</a><br>
<a href="http://lists.rtems.org/mailman/listinfo/devel" rel="noreferrer" target="_blank">http://lists.rtems.org/mailman/listinfo/devel</a><br>
</blockquote></div></div>