Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:53

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * RTEMS generic MPC83xx BSP
0005  *
0006  * This file integrates the IPIC irq controller.
0007  */
0008 
0009 /*
0010  * Copyright (c) 2007 embedded brains GmbH & Co. KG
0011  *
0012  * Redistribution and use in source and binary forms, with or without
0013  * modification, are permitted provided that the following conditions
0014  * are met:
0015  * 1. Redistributions of source code must retain the above copyright
0016  *    notice, this list of conditions and the following disclaimer.
0017  * 2. Redistributions in binary form must reproduce the above copyright
0018  *    notice, this list of conditions and the following disclaimer in the
0019  *    documentation and/or other materials provided with the distribution.
0020  *
0021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0022  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0024  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0025  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0026  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0027  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0028  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0029  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0030  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0031  * POSSIBILITY OF SUCH DAMAGE.
0032  */
0033 
0034 #include <mpc83xx/mpc83xx.h>
0035 
0036 #include <rtems.h>
0037 
0038 #include <libcpu/powerpc-utility.h>
0039 #include <bsp/vectors.h>
0040 
0041 #include <bsp.h>
0042 #include <bsp/irq.h>
0043 #include <bsp/irq-generic.h>
0044 
0045 #define MPC83XX_IPIC_VECTOR_NUMBER 92
0046 
0047 #define MPC83XX_IPIC_IS_VALID_VECTOR( vector) ((vector) >= 0 && (vector) < MPC83XX_IPIC_VECTOR_NUMBER)
0048 
0049 #define MPC83XX_IPIC_INVALID_MASK_POSITION 255
0050 
0051 typedef struct {
0052   volatile uint32_t *pend_reg;
0053   volatile uint32_t *mask_reg;
0054   const uint32_t bit_num;
0055 } BSP_isrc_rsc_t;
0056 
0057 /*
0058  * data structure to handle all mask registers in the IPIC
0059  *
0060  * Mask positions:
0061  *   simsr [0] :  0 .. 31
0062  *   simsr [1] : 32 .. 63
0063  *   semsr     : 64 .. 95
0064  *   sermr     : 96 .. 127
0065  */
0066 typedef struct {
0067   uint32_t simsr_mask [2];
0068   uint32_t semsr_mask;
0069   uint32_t sermr_mask;
0070 } mpc83xx_ipic_mask_t;
0071 
0072 static const BSP_isrc_rsc_t mpc83xx_ipic_isrc_rsc [MPC83XX_IPIC_VECTOR_NUMBER] = {
0073   /* vector 0 */
0074   {&mpc83xx.ipic.sersr, &mpc83xx.ipic.sermr, 31},
0075   {NULL, NULL, 0},
0076   {NULL, NULL, 0},
0077   {NULL, NULL, 0},
0078   {NULL, NULL, 0},
0079   {NULL, NULL, 0},
0080   {NULL, NULL, 0},
0081   {NULL, NULL, 0},
0082   /* vector  8 */
0083   {NULL, NULL, 0},  /* reserved vector  8 */
0084   /* vector  9: UART1 SIxxR_H, Bit 24 */
0085   {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 24},
0086   /* vector 10: UART2 SIxxR_H, Bit 25 */
0087   {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 25},
0088   /* vector 11: SEC   SIxxR_H, Bit 26 */
0089   {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 26},
0090   {NULL, NULL, 0},  /* reserved vector 12 */
0091   {NULL, NULL, 0},  /* reserved vector 13 */
0092   /* vector 14: I2C1 SIxxR_H, Bit 29 */
0093   {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 29},
0094   /* vector 15: I2C2 SIxxR_H, Bit 30 */
0095   {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 30},
0096   /* vector 16: SPI  SIxxR_H, Bit 31 */
0097   {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 31},
0098   /* vector 17: IRQ1 SExxR  , Bit  1 */
0099   {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 1},
0100   /* vector 18: IRQ2 SExxR  , Bit  2 */
0101   {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 2},
0102   /* vector 19: IRQ3 SExxR  , Bit  3 */
0103   {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 3},
0104   /* vector 20: IRQ4 SExxR  , Bit  4 */
0105   {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 4},
0106   /* vector 21: IRQ5 SExxR  , Bit  5 */
0107   {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 5},
0108   /* vector 22: IRQ6 SExxR  , Bit  6 */
0109   {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 6},
0110   /* vector 23: IRQ7 SExxR  , Bit  7 */
0111   {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 7},
0112   {NULL, NULL, 0},  /* reserved vector 24 */
0113   {NULL, NULL, 0},  /* reserved vector 25 */
0114   {NULL, NULL, 0},  /* reserved vector 26 */
0115   {NULL, NULL, 0},  /* reserved vector 27 */
0116   {NULL, NULL, 0},  /* reserved vector 28 */
0117   {NULL, NULL, 0},  /* reserved vector 29 */
0118   {NULL, NULL, 0},  /* reserved vector 30 */
0119   {NULL, NULL, 0},  /* reserved vector 31 */
0120   /* vector 32: TSEC1 Tx  SIxxR_H  , Bit  0 */
0121   {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 0},
0122   /* vector 33: TSEC1 Rx  SIxxR_H  , Bit  1 */
0123   {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 1},
0124   /* vector 34: TSEC1 Err SIxxR_H  , Bit  2 */
0125   {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 2},
0126   /* vector 35: TSEC2 Tx  SIxxR_H  , Bit  3 */
0127   {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 3},
0128   /* vector 36: TSEC2 Rx  SIxxR_H  , Bit  4 */
0129   {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 4},
0130   /* vector 37: TSEC2 Err SIxxR_H  , Bit  5 */
0131   {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 5},
0132   /* vector 38: USB DR    SIxxR_H  , Bit  6 */
0133   {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 6},
0134   /* vector 39: USB MPH   SIxxR_H  , Bit  7 */
0135   {&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 7},
0136   {NULL, NULL, 0},  /* reserved vector 40 */
0137   {NULL, NULL, 0},  /* reserved vector 41 */
0138   {NULL, NULL, 0},  /* reserved vector 42 */
0139   {NULL, NULL, 0},  /* reserved vector 43 */
0140   {NULL, NULL, 0},  /* reserved vector 44 */
0141   {NULL, NULL, 0},  /* reserved vector 45 */
0142   {NULL, NULL, 0},  /* reserved vector 46 */
0143   {NULL, NULL, 0},  /* reserved vector 47 */
0144   /* vector 48: IRQ0 SExxR  , Bit  0 */
0145   {&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 0},
0146   {NULL, NULL, 0},  /* reserved vector 49 */
0147   {NULL, NULL, 0},  /* reserved vector 50 */
0148   {NULL, NULL, 0},  /* reserved vector 51 */
0149   {NULL, NULL, 0},  /* reserved vector 52 */
0150   {NULL, NULL, 0},  /* reserved vector 53 */
0151   {NULL, NULL, 0},  /* reserved vector 54 */
0152   {NULL, NULL, 0},  /* reserved vector 55 */
0153   {NULL, NULL, 0},  /* reserved vector 56 */
0154   {NULL, NULL, 0},  /* reserved vector 57 */
0155   {NULL, NULL, 0},  /* reserved vector 58 */
0156   {NULL, NULL, 0},  /* reserved vector 59 */
0157   {NULL, NULL, 0},  /* reserved vector 60 */
0158   {NULL, NULL, 0},  /* reserved vector 61 */
0159   {NULL, NULL, 0},  /* reserved vector 62 */
0160   {NULL, NULL, 0},  /* reserved vector 63 */
0161   /* vector 64: RTC SEC   SIxxR_L  , Bit  0 */
0162   {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 0},
0163   /* vector 65: PIT       SIxxR_L  , Bit  1 */
0164   {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 1},
0165   /* vector 66: PCI1      SIxxR_L  , Bit  2 */
0166   {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 2},
0167   /* vector 67: PCI2      SIxxR_L  , Bit  3 */
0168   {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 3},
0169   /* vector 68: RTC ALR   SIxxR_L  , Bit  4 */
0170   {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 4},
0171   /* vector 69: MU        SIxxR_L  , Bit  5 */
0172   {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 5},
0173   /* vector 70: SBA       SIxxR_L  , Bit  6 */
0174   {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 6},
0175   /* vector 71: DMA       SIxxR_L  , Bit  7 */
0176   {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 7},
0177   /* vector 72: GTM4      SIxxR_L  , Bit  8 */
0178   {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 8},
0179   /* vector 73: GTM8      SIxxR_L  , Bit  9 */
0180   {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 9},
0181   /* vector 74: GPIO1     SIxxR_L  , Bit 10 */
0182   {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 10},
0183   /* vector 75: GPIO2     SIxxR_L  , Bit 11 */
0184   {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 11},
0185   /* vector 76: DDR       SIxxR_L  , Bit 12 */
0186   {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 12},
0187   /* vector 77: LBC       SIxxR_L  , Bit 13 */
0188   {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 13},
0189   /* vector 78: GTM2      SIxxR_L  , Bit 14 */
0190   {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 14},
0191   /* vector 79: GTM6      SIxxR_L  , Bit 15 */
0192   {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 15},
0193   /* vector 80: PMC       SIxxR_L  , Bit 16 */
0194   {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 16},
0195   {NULL, NULL, 0},  /* reserved vector 81 */
0196   {NULL, NULL, 0},  /* reserved vector 82 */
0197   {NULL, NULL, 0},  /* reserved vector 63 */
0198   /* vector 84: GTM3      SIxxR_L  , Bit 20 */
0199   {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 20},
0200   /* vector 85: GTM7      SIxxR_L  , Bit 21 */
0201   {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 21},
0202   {NULL, NULL, 0},  /* reserved vector 81 */
0203   {NULL, NULL, 0},  /* reserved vector 82 */
0204   {NULL, NULL, 0},  /* reserved vector 63 */
0205   {NULL, NULL, 0},  /* reserved vector 63 */
0206   /* vector 90: GTM1      SIxxR_L  , Bit 26 */
0207   {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 26},
0208   /* vector 91: GTM5      SIxxR_L  , Bit 27 */
0209   {&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 27}
0210 };
0211 
0212 static const uint8_t
0213     mpc83xx_ipic_mask_position_table [MPC83XX_IPIC_VECTOR_NUMBER] = {
0214   MPC83XX_IPIC_INVALID_MASK_POSITION,
0215   MPC83XX_IPIC_INVALID_MASK_POSITION,
0216   MPC83XX_IPIC_INVALID_MASK_POSITION,
0217   MPC83XX_IPIC_INVALID_MASK_POSITION,
0218   MPC83XX_IPIC_INVALID_MASK_POSITION,
0219   MPC83XX_IPIC_INVALID_MASK_POSITION,
0220   MPC83XX_IPIC_INVALID_MASK_POSITION,
0221   MPC83XX_IPIC_INVALID_MASK_POSITION,
0222   MPC83XX_IPIC_INVALID_MASK_POSITION,
0223   7,
0224   6,
0225   5,
0226   MPC83XX_IPIC_INVALID_MASK_POSITION,
0227   MPC83XX_IPIC_INVALID_MASK_POSITION,
0228   2,
0229   1,
0230   0,
0231   94,
0232   93,
0233   92,
0234   91,
0235   90,
0236   89,
0237   88,
0238   MPC83XX_IPIC_INVALID_MASK_POSITION,
0239   MPC83XX_IPIC_INVALID_MASK_POSITION,
0240   MPC83XX_IPIC_INVALID_MASK_POSITION,
0241   MPC83XX_IPIC_INVALID_MASK_POSITION,
0242   MPC83XX_IPIC_INVALID_MASK_POSITION,
0243   MPC83XX_IPIC_INVALID_MASK_POSITION,
0244   MPC83XX_IPIC_INVALID_MASK_POSITION,
0245   MPC83XX_IPIC_INVALID_MASK_POSITION,
0246   31,
0247   30,
0248   29,
0249   28,
0250   27,
0251   26,
0252   25,
0253   24,
0254   MPC83XX_IPIC_INVALID_MASK_POSITION,
0255   MPC83XX_IPIC_INVALID_MASK_POSITION,
0256   MPC83XX_IPIC_INVALID_MASK_POSITION,
0257   MPC83XX_IPIC_INVALID_MASK_POSITION,
0258   MPC83XX_IPIC_INVALID_MASK_POSITION,
0259   MPC83XX_IPIC_INVALID_MASK_POSITION,
0260   MPC83XX_IPIC_INVALID_MASK_POSITION,
0261   MPC83XX_IPIC_INVALID_MASK_POSITION,
0262   95,
0263   MPC83XX_IPIC_INVALID_MASK_POSITION,
0264   MPC83XX_IPIC_INVALID_MASK_POSITION,
0265   MPC83XX_IPIC_INVALID_MASK_POSITION,
0266   MPC83XX_IPIC_INVALID_MASK_POSITION,
0267   MPC83XX_IPIC_INVALID_MASK_POSITION,
0268   MPC83XX_IPIC_INVALID_MASK_POSITION,
0269   MPC83XX_IPIC_INVALID_MASK_POSITION,
0270   MPC83XX_IPIC_INVALID_MASK_POSITION,
0271   MPC83XX_IPIC_INVALID_MASK_POSITION,
0272   MPC83XX_IPIC_INVALID_MASK_POSITION,
0273   MPC83XX_IPIC_INVALID_MASK_POSITION,
0274   MPC83XX_IPIC_INVALID_MASK_POSITION,
0275   MPC83XX_IPIC_INVALID_MASK_POSITION,
0276   MPC83XX_IPIC_INVALID_MASK_POSITION,
0277   MPC83XX_IPIC_INVALID_MASK_POSITION,
0278   63,
0279   62,
0280   61,
0281   60,
0282   59,
0283   58,
0284   57,
0285   56,
0286   55,
0287   54,
0288   53,
0289   52,
0290   51,
0291   50,
0292   49,
0293   48,
0294   47,
0295   MPC83XX_IPIC_INVALID_MASK_POSITION,
0296   MPC83XX_IPIC_INVALID_MASK_POSITION,
0297   MPC83XX_IPIC_INVALID_MASK_POSITION,
0298   43,
0299   42,
0300   MPC83XX_IPIC_INVALID_MASK_POSITION,
0301   MPC83XX_IPIC_INVALID_MASK_POSITION,
0302   MPC83XX_IPIC_INVALID_MASK_POSITION,
0303   MPC83XX_IPIC_INVALID_MASK_POSITION,
0304   37,
0305   36
0306 };
0307 
0308 /*
0309  * this array will be filled with mask values needed
0310  * to temporarily disable all IRQ soures with lower or same
0311  * priority of the current source (whose vector is the array index)
0312  */
0313 static mpc83xx_ipic_mask_t mpc83xx_ipic_prio2mask [MPC83XX_IPIC_VECTOR_NUMBER];
0314 
0315 rtems_status_code mpc83xx_ipic_set_mask(
0316   rtems_vector_number vector,
0317   rtems_vector_number mask_vector,
0318   bool mask
0319 )
0320 {
0321   uint8_t pos = 0;
0322   mpc83xx_ipic_mask_t *mask_entry;
0323   uint32_t *mask_reg;
0324   rtems_interrupt_level level;
0325 
0326   /* Parameter check */
0327   if (!MPC83XX_IPIC_IS_VALID_VECTOR( vector) ||
0328       !MPC83XX_IPIC_IS_VALID_VECTOR( mask_vector)) {
0329     return RTEMS_INVALID_NUMBER;
0330   } else if (vector == mask_vector) {
0331     return RTEMS_RESOURCE_IN_USE;
0332   }
0333 
0334   /* Position and mask entry */
0335   pos = mpc83xx_ipic_mask_position_table [mask_vector];
0336   mask_entry = &mpc83xx_ipic_prio2mask [vector];
0337 
0338   /* Mask register and position */
0339   if (pos < 32) {
0340     mask_reg = &mask_entry->simsr_mask [0];
0341   } else if (pos < 64) {
0342     pos -= 32;
0343     mask_reg = &mask_entry->simsr_mask [1];
0344   } else if (pos < 96) {
0345     pos -= 64;
0346     mask_reg = &mask_entry->semsr_mask;
0347   } else if (pos < 128) {
0348     pos -= 96;
0349     mask_reg = &mask_entry->sermr_mask;
0350   } else {
0351     return RTEMS_NOT_IMPLEMENTED;
0352   }
0353 
0354   /* Mask or unmask */
0355   if (mask) {
0356     rtems_interrupt_disable( level);
0357     *mask_reg &= ~(1 << pos);
0358     rtems_interrupt_enable( level);
0359   } else {
0360     rtems_interrupt_disable( level);
0361     *mask_reg |= 1 << pos;
0362     rtems_interrupt_enable( level);
0363   }
0364 
0365   return RTEMS_SUCCESSFUL;
0366 }
0367 
0368 rtems_status_code mpc83xx_ipic_set_highest_priority_interrupt(
0369   rtems_vector_number vector,
0370   int type
0371 )
0372 {
0373   rtems_interrupt_level level;
0374   uint32_t reg = 0;
0375 
0376   if (!MPC83XX_IPIC_IS_VALID_VECTOR( vector)) {
0377     return RTEMS_INVALID_NUMBER;
0378   } else if (type < 0 || type > MPC83XX_IPIC_INTERRUPT_CRITICAL) {
0379     return RTEMS_INVALID_NUMBER;
0380   }
0381 
0382   rtems_interrupt_disable( level);
0383   reg = mpc83xx.ipic.sicfr;
0384   mpc83xx.ipic.sicfr = (reg & ~0x7f000300) | (vector << 24) | (type << 8);
0385   rtems_interrupt_enable( level);
0386 
0387   return RTEMS_SUCCESSFUL;
0388 }
0389 
0390 /*
0391  * functions to enable/disable a source at the ipic
0392  */
0393 rtems_status_code bsp_interrupt_get_attributes(
0394   rtems_vector_number         vector,
0395   rtems_interrupt_attributes *attributes
0396 )
0397 {
0398   return RTEMS_SUCCESSFUL;
0399 }
0400 
0401 rtems_status_code bsp_interrupt_is_pending(
0402   rtems_vector_number vector,
0403   bool               *pending
0404 )
0405 {
0406   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0407   bsp_interrupt_assert(pending != NULL);
0408   *pending = false;
0409   return RTEMS_UNSATISFIED;
0410 }
0411 
0412 rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
0413 {
0414   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0415   return RTEMS_UNSATISFIED;
0416 }
0417 
0418 rtems_status_code bsp_interrupt_clear(rtems_vector_number vector)
0419 {
0420   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0421   return RTEMS_UNSATISFIED;
0422 }
0423 
0424 rtems_status_code bsp_interrupt_vector_is_enabled(
0425   rtems_vector_number vector,
0426   bool               *enabled
0427 )
0428 {
0429   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0430   bsp_interrupt_assert(enabled != NULL);
0431   *enabled = false;
0432   return RTEMS_UNSATISFIED;
0433 }
0434 
0435 rtems_status_code bsp_interrupt_vector_enable( rtems_vector_number vector)
0436 {
0437   rtems_vector_number vecnum = vector - BSP_IPIC_IRQ_LOWEST_OFFSET;
0438   const BSP_isrc_rsc_t *rsc_ptr;
0439 
0440   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0441 
0442   if (MPC83XX_IPIC_IS_VALID_VECTOR( vecnum)) {
0443     rsc_ptr = &mpc83xx_ipic_isrc_rsc [vecnum];
0444     if (rsc_ptr->mask_reg != NULL) {
0445       uint32_t bit = 1U << (31 - rsc_ptr->bit_num);
0446       rtems_interrupt_level level;
0447 
0448       rtems_interrupt_disable(level);
0449       *(rsc_ptr->mask_reg) |= bit;
0450       rtems_interrupt_enable(level);
0451     }
0452   }
0453 
0454   return RTEMS_SUCCESSFUL;
0455 }
0456 
0457 rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number vector)
0458 {
0459   rtems_vector_number vecnum = vector - BSP_IPIC_IRQ_LOWEST_OFFSET;
0460   const BSP_isrc_rsc_t *rsc_ptr;
0461 
0462   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0463 
0464   if (MPC83XX_IPIC_IS_VALID_VECTOR( vecnum)) {
0465     rsc_ptr = &mpc83xx_ipic_isrc_rsc [vecnum];
0466     if (rsc_ptr->mask_reg != NULL) {
0467       uint32_t bit = 1U << (31 - rsc_ptr->bit_num);
0468       rtems_interrupt_level level;
0469 
0470       rtems_interrupt_disable(level);
0471       *(rsc_ptr->mask_reg) &= ~bit;
0472       rtems_interrupt_enable(level);
0473     }
0474   }
0475 
0476   return RTEMS_SUCCESSFUL;
0477 }
0478 
0479 rtems_status_code bsp_interrupt_set_priority(
0480   rtems_vector_number vector,
0481   uint32_t priority
0482 )
0483 {
0484   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0485   return RTEMS_UNSATISFIED;
0486 }
0487 
0488 rtems_status_code bsp_interrupt_get_priority(
0489   rtems_vector_number vector,
0490   uint32_t *priority
0491 )
0492 {
0493   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0494   bsp_interrupt_assert(priority != NULL);
0495   return RTEMS_UNSATISFIED;
0496 }
0497 
0498 /*
0499  *  IRQ Handler: this is called from the primary exception dispatcher
0500  */
0501 static int BSP_irq_handle_at_ipic( unsigned excNum)
0502 {
0503   int32_t vecnum;
0504 #ifdef GEN83XX_ENABLE_INTERRUPT_NESTING
0505   mpc83xx_ipic_mask_t mask_save;
0506   const mpc83xx_ipic_mask_t *mask_ptr;
0507   uint32_t msr = 0;
0508   rtems_interrupt_level level;
0509 #endif
0510 
0511   /* Get vector number */
0512   switch (excNum) {
0513     case ASM_EXT_VECTOR:
0514       vecnum = MPC83xx_VCR_TO_VEC( mpc83xx.ipic.sivcr);
0515       break;
0516     case ASM_E300_SYSMGMT_VECTOR:
0517       vecnum = MPC83xx_VCR_TO_VEC( mpc83xx.ipic.smvcr);
0518       break;
0519     case ASM_E300_CRIT_VECTOR:
0520       vecnum = MPC83xx_VCR_TO_VEC( mpc83xx.ipic.scvcr);
0521       break;
0522     default:
0523       return 1;
0524   }
0525 
0526   /*
0527    * Check the vector number, mask lower priority interrupts, enable
0528    * exceptions and dispatch the handler.
0529    */
0530   if (MPC83XX_IPIC_IS_VALID_VECTOR( vecnum)) {
0531 #ifdef GEN83XX_ENABLE_INTERRUPT_NESTING
0532     mask_ptr = &mpc83xx_ipic_prio2mask [vecnum];
0533 
0534     rtems_interrupt_disable( level);
0535 
0536     /* Save current mask registers */
0537     mask_save.simsr_mask [0] = mpc83xx.ipic.simsr [0];
0538     mask_save.simsr_mask [1] = mpc83xx.ipic.simsr [1];
0539     mask_save.semsr_mask = mpc83xx.ipic.semsr;
0540     mask_save.sermr_mask = mpc83xx.ipic.sermr;
0541 
0542     /* Mask all lower priority interrupts */
0543     mpc83xx.ipic.simsr [0] &= mask_ptr->simsr_mask [0];
0544     mpc83xx.ipic.simsr [1] &= mask_ptr->simsr_mask [1];
0545     mpc83xx.ipic.semsr &= mask_ptr->semsr_mask;
0546     mpc83xx.ipic.sermr &= mask_ptr->sermr_mask;
0547 
0548     rtems_interrupt_enable( level);
0549 
0550     /* Enable all interrupts */
0551     if (excNum != ASM_E300_CRIT_VECTOR) {
0552       msr = ppc_external_exceptions_enable();
0553     }
0554 #endif /* GEN83XX_ENABLE_INTERRUPT_NESTING */
0555 
0556     /* Dispatch interrupt handlers */
0557     bsp_interrupt_handler_dispatch( vecnum + BSP_IPIC_IRQ_LOWEST_OFFSET);
0558 
0559 #ifdef GEN83XX_ENABLE_INTERRUPT_NESTING
0560     /* Restore machine state */
0561     if (excNum != ASM_E300_CRIT_VECTOR) {
0562       ppc_external_exceptions_disable( msr);
0563     }
0564 
0565     /* Restore initial masks */
0566     rtems_interrupt_disable( level);
0567     mpc83xx.ipic.simsr [0] = mask_save.simsr_mask [0];
0568     mpc83xx.ipic.simsr [1] = mask_save.simsr_mask [1];
0569     mpc83xx.ipic.semsr = mask_save.semsr_mask;
0570     mpc83xx.ipic.sermr = mask_save.sermr_mask;
0571     rtems_interrupt_enable( level);
0572 #endif /* GEN83XX_ENABLE_INTERRUPT_NESTING */
0573   } else {
0574     bsp_interrupt_handler_default( vecnum);
0575   }
0576 
0577   return 0;
0578 }
0579 
0580 /*
0581  * Fill the array mpc83xx_ipic_prio2mask to allow masking of lower prio sources
0582  * to implement nested interrupts.
0583  */
0584 static void mpc83xx_ipic_calc_prio2mask(void)
0585 {
0586   /*
0587    * FIXME: fill the array
0588    */
0589 }
0590 
0591 /*
0592  * Activate the interrupt controller
0593  */
0594 static void mpc83xx_ipic_initialize(void)
0595 {
0596   /*
0597    * mask off all interrupts
0598    */
0599   mpc83xx.ipic.simsr [0] = 0;
0600   mpc83xx.ipic.simsr [1] = 0;
0601   mpc83xx.ipic.semsr = 0;
0602   mpc83xx.ipic.sermr = 0;
0603   /*
0604    * set desired configuration as defined in bspopts.h
0605    * normally, the default values should be fine
0606    */
0607 #if defined( BSP_SICFR_VAL)  /* defined in bspopts.h ? */
0608   mpc83xx.ipic.sicfr = BSP_SICFR_VAL;
0609 #endif
0610 
0611   /*
0612    * set desired priorities as defined in bspopts.h
0613    * normally, the default values should be fine
0614    */
0615 #if defined( BSP_SIPRR0_VAL)  /* defined in bspopts.h ? */
0616   mpc83xx.ipic.siprr [0] = BSP_SIPRR0_VAL;
0617 #endif
0618 
0619 #if defined( BSP_SIPRR1_VAL)  /* defined in bspopts.h ? */
0620   mpc83xx.ipic.siprr [1] = BSP_SIPRR1_VAL;
0621 #endif
0622 
0623 #if defined( BSP_SIPRR2_VAL)  /* defined in bspopts.h ? */
0624   mpc83xx.ipic.siprr [2] = BSP_SIPRR2_VAL;
0625 #endif
0626 
0627 #if defined( BSP_SIPRR3_VAL)  /* defined in bspopts.h ? */
0628   mpc83xx.ipic.siprr [3] = BSP_SIPRR3_VAL;
0629 #endif
0630 
0631 #if defined( BSP_SMPRR0_VAL)  /* defined in bspopts.h ? */
0632   mpc83xx.ipic.smprr [0] = BSP_SMPRR0_VAL;
0633 #endif
0634 
0635 #if defined( BSP_SMPRR1_VAL)  /* defined in bspopts.h ? */
0636   mpc83xx.ipic.smprr [1] = BSP_SMPRR1_VAL;
0637 #endif
0638 
0639 #if defined( BSP_SECNR_VAL)  /* defined in bspopts.h ? */
0640   mpc83xx.ipic.secnr = BSP_SECNR_VAL;
0641 #endif
0642 
0643   /*
0644    * calculate priority masks
0645    */
0646   mpc83xx_ipic_calc_prio2mask();
0647 }
0648 
0649 static int mpc83xx_exception_handler(
0650   BSP_Exception_frame *frame,
0651   unsigned exception_number
0652 )
0653 {
0654   return BSP_irq_handle_at_ipic( exception_number);
0655 }
0656 
0657 void bsp_interrupt_facility_initialize()
0658 {
0659   rtems_status_code sc;
0660 
0661   /* Install exception handler */
0662   sc = ppc_exc_set_handler( ASM_EXT_VECTOR, mpc83xx_exception_handler);
0663   _Assert_Unused_variable_equals( sc, RTEMS_SUCCESSFUL);
0664   sc = ppc_exc_set_handler( ASM_E300_SYSMGMT_VECTOR, mpc83xx_exception_handler);
0665   _Assert_Unused_variable_equals( sc, RTEMS_SUCCESSFUL);
0666   sc = ppc_exc_set_handler( ASM_E300_CRIT_VECTOR, mpc83xx_exception_handler);
0667   _Assert_Unused_variable_equals( sc, RTEMS_SUCCESSFUL);
0668 
0669   /* Initialize the interrupt controller */
0670   mpc83xx_ipic_initialize();
0671 }