source: rtems/c/src/lib/libbsp/powerpc/haleakala/irq/irq.c @ 3c6fe2e

4.104.114.95
Last change on this file since 3c6fe2e was 3c6fe2e, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on 07/14/08 at 08:46:06

added haleakala BSP contributed by Michael Hamel

  • Property mode set to 100644
File size: 7.8 KB
Line 
1/*
2 *
3 *
4 *  The license and distribution terms for this file may be
5 *  found in found in the file LICENSE in this distribution or at
6 *  http://www.rtems.com/license/LICENSE.
7 *
8 *  Middleware support for PPC405 by M.Hamel ADInstruments Ltd 2008
9 *
10 *  $Id$
11 */
12
13#include <rtems.h>
14#include <bsp.h>
15#include <bsp/irq.h>
16#include <bsp/irq_supp.h>
17#include <libcpu/raw_exception.h>
18#include <libcpu/powerpc-utility.h>
19
20
21/* PPC405EX UIC numbers */
22#define UIC_DCR_BASE 0xc0
23#define UIC0_SR      (UIC_DCR_BASE+0x0)  /* UIC status                       */
24#define UIC0_SRS     (UIC_DCR_BASE+0x1)  /* UIC status set                   */
25#define UIC0_ER      (UIC_DCR_BASE+0x2)  /* UIC enable                       */
26#define UIC0_CR      (UIC_DCR_BASE+0x3)  /* UIC critical                     */
27#define UIC0_PR      (UIC_DCR_BASE+0x4)  /* UIC polarity                     */
28#define UIC0_TR      (UIC_DCR_BASE+0x5)  /* UIC triggering                   */
29#define UIC0_MSR     (UIC_DCR_BASE+0x6)  /* UIC masked status                */
30#define UIC0_VR      (UIC_DCR_BASE+0x7)  /* UIC vector                       */
31#define UIC0_VCR     (UIC_DCR_BASE+0x8)  /* UIC vector configuration         */
32
33#define UIC1_SR      (UIC_DCR_BASE+0x10)  /* UIC status                       */
34#define UIC1_SRS     (UIC_DCR_BASE+0x11)  /* UIC status set                   */
35#define UIC1_ER      (UIC_DCR_BASE+0x12)  /* UIC enable                       */
36#define UIC1_CR      (UIC_DCR_BASE+0x13)  /* UIC critical                     */
37#define UIC1_PR      (UIC_DCR_BASE+0x14)  /* UIC polarity                     */
38#define UIC1_TR      (UIC_DCR_BASE+0x15)  /* UIC triggering                   */
39#define UIC1_MSR     (UIC_DCR_BASE+0x16)  /* UIC masked status                */
40#define UIC1_VR      (UIC_DCR_BASE+0x17)  /* UIC vector                       */
41#define UIC1_VCR     (UIC_DCR_BASE+0x18)  /* UIC vector configuration         */
42
43#define UIC2_SR      (UIC_DCR_BASE+0x20)  /* UIC status                       */
44#define UIC2_SRS     (UIC_DCR_BASE+0x21)  /* UIC status set                   */
45#define UIC2_ER      (UIC_DCR_BASE+0x22)  /* UIC enable                       */
46#define UIC2_CR      (UIC_DCR_BASE+0x23)  /* UIC critical                     */
47#define UIC2_PR      (UIC_DCR_BASE+0x24)  /* UIC polarity                     */
48#define UIC2_TR      (UIC_DCR_BASE+0x25)  /* UIC triggering                   */
49#define UIC2_MSR     (UIC_DCR_BASE+0x26)  /* UIC masked status                */
50#define UIC2_VR      (UIC_DCR_BASE+0x27)  /* UIC vector                       */
51#define UIC2_VCR     (UIC_DCR_BASE+0x28)  /* UIC vector configuration         */
52
53enum { kUICWords = 3 };
54
55static rtems_irq_connect_data* rtems_hdl_tblP;
56static rtems_irq_connect_data  dflt_entry;
57
58static uint32_t gEnabledInts[kUICWords];                /* 1-bits mean enabled */
59static uint32_t gIntInhibited[kUICWords];               /* 1-bits disable, overriding gEnabledInts because the interrupt
60                                                                                                   is being processed in C_dispatch_irq_handler */
61
62static inline int IsUICIRQ(const rtems_irq_number irqLine)
63{
64  return (((int) irqLine <= BSP_UIC_IRQ_MAX_OFFSET) &&
65          ((int) irqLine >= BSP_UIC_IRQ_LOWEST_OFFSET)
66         );
67}
68
69static void WriteIState()
70/* Write the gEnabledInts state masked by gIntInhibited to the hardware */
71{
72        mtdcr(UIC0_ER, gEnabledInts[0] & ~gIntInhibited[0]);
73        mtdcr(UIC1_ER, gEnabledInts[1] & ~gIntInhibited[1]);
74        mtdcr(UIC2_ER, gEnabledInts[2] & ~gIntInhibited[2]);
75}
76
77void
78BSP_enable_irq_at_pic(const rtems_irq_number irq)
79/* Enable an interrupt; this can be called from inside C_dispatch_irq_handler */
80{
81        if (IsUICIRQ(irq)) {
82                /* Set relevant bit in the state, write state to the UIC */
83                gEnabledInts[irq>>5] |= (0x80000000 >> (irq & 0x1F));
84                WriteIState();
85        }
86}
87
88int
89BSP_disable_irq_at_pic(const rtems_irq_number irq)
90/* Enable an interrupt; this can be called from inside C_dispatch_irq_handler */
91{
92        if (IsUICIRQ(irq)) {
93                uint32_t oldState;
94                int              iword = irq>>5;
95                uint32_t mask = (0x80000000 >> (irq & 0x1F));
96               
97                oldState = gEnabledInts[iword] & mask;
98                gEnabledInts[iword] &= ~mask;
99                WriteIState();
100                return oldState ? 1 : 0;
101        } else
102                return -1;
103}
104
105int
106BSP_setup_the_pic(rtems_irq_global_settings* config)
107{
108        int i;
109       
110        dflt_entry     = config->defaultEntry;
111        rtems_hdl_tblP = config->irqHdlTbl;
112        for (i=0; i<kUICWords; i++)
113                gIntInhibited[i] = 0;
114               
115        mtdcr (UIC2_ER, 0x00000000);    /* disable all interrupts */
116        mtdcr (UIC2_CR, 0x00000000);    /* Set Critical / Non Critical interrupts */
117        mtdcr (UIC2_PR, 0xf7ffffff);    /* Set Interrupt Polarities */
118        mtdcr (UIC2_TR, 0x01e1fff8);    /* Set Interrupt Trigger Levels */
119        mtdcr (UIC2_VR, 0x00000001);    /* Set Vect base=0,INT31 Highest priority */
120        mtdcr (UIC2_SR, 0xffffffff);    /* clear all interrupts */
121
122        mtdcr (UIC1_ER, 0x00000000);    /* disable all interrupts */
123        mtdcr (UIC1_CR, 0x00000000);    /* Set Critical / Non Critical interrupts */
124        mtdcr (UIC1_PR, 0xfffac785);    /* Set Interrupt Polarities */
125        mtdcr (UIC1_TR, 0x001d0040);    /* Set Interrupt Trigger Levels */
126        mtdcr (UIC1_VR, 0x00000001);    /* Set Vect base=0,INT31 Highest priority */
127        mtdcr (UIC1_SR, 0xffffffff);    /* clear all interrupts */
128
129        mtdcr (UIC0_ER, 0x0000000a);    /* Disable all interrupts except cascade UIC0 and UIC1 */
130        mtdcr (UIC0_CR, 0x00000000);    /* Set Critical / Non Critical interrupts */
131        mtdcr (UIC0_PR, 0xffbfefef);    /* Set Interrupt Polarities */
132        mtdcr (UIC0_TR, 0x00007000);    /* Set Interrupt Trigger Levels */
133        mtdcr (UIC0_VR, 0x00000001);    /* Set Vect base=0,INT31 Highest priority */
134        mtdcr (UIC0_SR, 0xffffffff);    /* clear all interrupts */
135       
136        return 1;
137}
138
139
140/*
141 * High level IRQ handler called from shared_raw_irq_code_entry; decode and
142 * dispatch. Note that this routine needs to be re-entrant
143 *
144 * No support for critical interrupts here yet
145 */
146 
147int
148C_dispatch_irq_handler( struct _BSP_Exception_frame* frame, unsigned int excNum )
149{
150        if (excNum == ASM_EXT_VECTOR) {
151                uint32_t active[kUICWords];
152
153                /* Fetch the masked flags that tell us what external ints are active.
154                   Likely to be only one, but we need to handle more than one,
155                   OR the flags into gIntInhibited */
156                active[0] = mfdcr(UIC0_MSR);
157                active[1] = mfdcr(UIC1_MSR);
158                active[2] = mfdcr(UIC2_MSR);
159                gIntInhibited[0] |= active[0];
160                gIntInhibited[1] |= active[1];
161                gIntInhibited[2] |= active[2];
162               
163                /*  ...and update the hardware so the active interrupts are disabled */
164                WriteIState();
165               
166                /* Loop, calling bsp_irq_dispatch_list for each active interrupt */
167                while ((active[0] | active[1] | active[2]) != 0) {
168                        uint32_t index = -1;
169                        uint32_t bit, bmask;
170                       
171                        /* Find an active interrupt, searching 0..2, bit 0..bit 31 (IBM order) */
172                        do {
173                                index++;
174                                asm volatile (" cntlzw %0, %1":"=r" (bit):"r" (active[index]));
175                        } while (bit==32);
176
177                        /* Call the matching handler */
178                        bsp_irq_dispatch_list(rtems_hdl_tblP, (index*32)+bit, dflt_entry.hdl);
179
180                        /* Write a 1-bit to the appropriate status register to clear it */
181                        bmask = 0x80000000 >> bit;
182                        switch (index) {
183                                case 0: mtdcr(UIC0_SR, bmask); break;
184                                case 1: mtdcr(UIC1_SR, bmask); break;
185                                case 2: mtdcr(UIC2_SR, bmask); break;
186                        }
187                       
188                        /* Clear in the active record and gIntInhibited */
189                        active[index] &= ~bmask;
190                        gIntInhibited[index] &= ~bmask;
191                };
192
193                /* Update the hardware again so the interrupts we have handled are unmasked */
194                WriteIState();
195                return 0;
196               
197        } else if (excNum == ASM_DEC_VECTOR) {          /* 0x1000 remapped by C_dispatch_dec_handler_bookE  */
198                bsp_irq_dispatch_list(rtems_hdl_tblP, BSP_PIT, dflt_entry.hdl);
199                return 0;
200               
201        } else if (excNum == ASM_BOOKE_FIT_VECTOR) {            /* 0x1010 mapped to 0x13 by ppc_get_vector_addr */
202                bsp_irq_dispatch_list(rtems_hdl_tblP, BSP_FIT, dflt_entry.hdl);
203                return 0;
204               
205        } else if (excNum == ASM_BOOKE_WDOG_VECTOR) {           /* 0x1020 mapped to 0x14 by ppc_get_vector_addr */
206                bsp_irq_dispatch_list(rtems_hdl_tblP, BSP_WDOG, dflt_entry.hdl);
207                return 0;
208               
209        } else
210                return -1; /* unhandled interrupt, panic time */
211}
212
Note: See TracBrowser for help on using the repository browser.