source: rtems/c/src/lib/libbsp/powerpc/score603e/irq/irq.c @ 0c875c6a

4.115
Last change on this file since 0c875c6a was 0c875c6a, checked in by Joel Sherrill <joel.sherrill@…>, on 01/28/11 at 20:29:53

2011-01-28 Joel Sherrill <joel.sherrilL@…>

  • beatnik/include/bsp.h, beatnik/irq/irq.h, beatnik/pci/gt_pci_init.c, ep1a/console/polled_io.c, ep1a/irq/openpic_xxx_irq.c, gen5200/include/irq.h, gen5200/irq/irq.c, gen5200/startup/bspstart.c, haleakala/irq/irq.c, mbx8xx/irq/irq.c, mbx8xx/irq/irq.h, motorola_powerpc/include/bsp.h, mpc8260ads/irq/irq.c, mpc8260ads/irq/irq.h, mvme3100/include/bsp.h, mvme3100/irq/irq.h, mvme3100/start/start.S, mvme5500/include/bsp.h, mvme5500/irq/irq.h, psim/include/bsp.h, psim/include/coverhd.h, psim/irq/irq.h, psim/shmsupp/addrconv.c, psim/shmsupp/getcfg.c, psim/startup/linkcmds, psim/tools/psim-gdb-top.in, psim/tools/psim-top.in, psim/tools/runtest-top.in, qemuppc/irq/irq.h, score603e/irq/irq.c, shared/bootloader/bootldr.h, shared/bootloader/em86.c, shared/bootloader/em86real.S, shared/bootloader/exception.S, shared/bootloader/head.S, shared/bootloader/lib.c, shared/bootloader/misc.c, shared/bootloader/mm.c, shared/bootloader/pci.c, shared/console/console.c, shared/console/consoleIo.h, shared/console/inch.c, shared/console/keyboard.h, shared/console/polled_io.c, shared/irq/i8259.c, shared/irq/irq.h, shared/irq/openpic_i8259_irq.c, shared/motorola/motorola.c, shared/motorola/motorola.h, shared/openpic/openpic.c, shared/openpic/openpic.h, shared/pci/pci.c, shared/residual/residual.c, shared/start/start.S, ss555/irq/irq.h: Fix typo where license said found in found in.
  • Property mode set to 100644
File size: 12.0 KB
Line 
1/*
2 *  This file contains the implementation of the function described in irq.h
3 *
4 *  Copyright (C) 1998, 1999 valette@crf.canon.fr
5 *
6 *  The license and distribution terms for this file may be
7 *  found in the file LICENSE in this distribution or at
8 *  http://www.rtems.com/license/LICENSE.
9 *
10 *  $Id$
11 */
12
13#include <stdlib.h>
14
15#include <bsp.h>
16#include <bsp/irq.h>
17#include <bsp/VME.h>
18#include <rtems/score/apiext.h>  /* for post ISR signal processing */
19#include <libcpu/io.h>
20#include <bsp/vectors.h>
21#include <stdlib.h>
22#include <rtems/bspIo.h> /* for printk */
23
24/*
25 * default handler connected on each irq after bsp initialization
26 */
27static rtems_irq_connect_data   default_rtems_entry;
28
29/*
30 * location used to store initial tables used for interrupt
31 * management.
32 */
33static rtems_irq_global_settings*       internal_config;
34static rtems_irq_connect_data*          rtems_hdl_tbl;
35
36/*
37 * Check if IRQ is an ISA IRQ
38 */
39static inline int is_isa_irq(const rtems_irq_number irqLine)
40{
41  return (((int) irqLine <= BSP_ISA_IRQ_MAX_OFFSET) &
42          ((int) irqLine >= BSP_ISA_IRQ_LOWEST_OFFSET)
43         );
44}
45
46/*
47 * Check if IRQ is an pci IRQ
48 */
49static inline int is_pci_irq(const rtems_irq_number irqLine)
50{
51  return (((int) irqLine <= BSP_PCI_IRQ_MAX_OFFSET) &
52          ((int) irqLine >= BSP_PCI_IRQ_LOWEST_OFFSET)
53         );
54}
55
56/*
57 * Check if IRQ is a Processor IRQ
58 */
59static inline int is_processor_irq(const rtems_irq_number irqLine)
60{
61  return (((int) irqLine <= BSP_PROCESSOR_IRQ_MAX_OFFSET) &
62          ((int) irqLine >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET)
63         );
64}
65
66/*
67 * ------------------------ RTEMS Irq helper functions ----------------
68 */
69
70/*
71 * This function check that the value given for the irq line
72 * is valid.
73 */
74
75static int isValidInterrupt(int irq)
76{
77  if ( (irq < BSP_LOWEST_OFFSET) || (irq > BSP_MAX_OFFSET))
78    return 0;
79  return 1;
80}
81
82/*
83 * ------------------------ RTEMS Shared Irq Handler Mngt Routines ----------------
84 */
85int BSP_install_rtems_shared_irq_handler  (const rtems_irq_connect_data* irq)
86{
87    rtems_interrupt_level   level;
88    rtems_irq_connect_data* vchain;
89
90printk(" BSP_install_rtems_shared_irq_handler %d\n", irq->name );
91
92    if (!isValidInterrupt(irq->name)) {
93      printk("Invalid interrupt vector %d\n",irq->name);
94      return 0;
95    }
96
97    rtems_interrupt_disable(level);
98
99    if ( (int)rtems_hdl_tbl[irq->name].next_handler  == -1 ) {
100      rtems_interrupt_enable(level);
101      printk("IRQ vector %d already connected to an unshared handler\n",irq->name);
102      return 0;
103    }
104
105     vchain = (rtems_irq_connect_data*)malloc(sizeof(rtems_irq_connect_data));
106
107    /* save off topmost handler */
108    vchain[0]= rtems_hdl_tbl[irq->name];
109
110    /*
111     * store the data provided by user
112     */
113    rtems_hdl_tbl[irq->name] = *irq;
114
115    /* link chain to new topmost handler */
116    rtems_hdl_tbl[irq->name].next_handler = (void *)vchain;
117
118    /*
119     * XXX FIX ME
120     */
121    if (is_pci_irq(irq->name)) {
122    }
123
124    if (is_processor_irq(irq->name)) {
125      /*
126       * Enable exception at processor level
127       */
128    }
129    /*
130     * Enable interrupt on device
131     */
132        if (irq->on)
133        irq->on(irq);
134
135    rtems_interrupt_enable(level);
136
137    return 1;
138}
139
140/*
141 * This function disables a given XXX interrupt
142 */
143rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number irqLine)
144{
145  /* XXX FIX ME!!!! */
146
147  printk("bsp_interrupt_vector_disable: 0x%x\n", irqLine );
148  return RTEMS_SUCCESSFUL;
149}
150
151rtems_status_code bsp_interrupt_vector_enable( rtems_vector_number irqLine)
152{
153  /* XXX FIX ME!!!! */
154  printk("bsp_interrupt_vector_enable: 0x%x\n", irqLine );
155
156  return RTEMS_SUCCESSFUL;
157}
158
159
160
161/*
162 * ------------------------ RTEMS Single Irq Handler Mngt Routines ----------------
163 */
164
165int BSP_install_rtems_irq_handler  (const rtems_irq_connect_data* irq)
166{
167    rtems_interrupt_level       level;
168
169printk(" BSP_install_rtems_irq_handler %d\n", irq->name );
170
171    if (!isValidInterrupt(irq->name)) {
172      printk("Invalid interrupt vector %d\n",irq->name);
173      return 0;
174    }
175    /*
176     * Check if default handler is actually connected. If not issue an error.
177     * You must first get the current handler via i386_get_current_idt_entry
178     * and then disconnect it using i386_delete_idt_entry.
179     * RATIONALE : to always have the same transition by forcing the user
180     * to get the previous handler before accepting to disconnect.
181     */
182    rtems_interrupt_disable(level);
183    if (rtems_hdl_tbl[irq->name].hdl != default_rtems_entry.hdl) {
184      rtems_interrupt_enable(level);
185      printk("IRQ vector %d already connected\n",irq->name);
186      return 0;
187    }
188
189    /*
190     * store the data provided by user
191     */
192    rtems_hdl_tbl[irq->name] = *irq;
193    rtems_hdl_tbl[irq->name].next_handler = (void *)-1;
194
195    /* XXX -FIX ME !! */
196    if (is_pci_irq(irq->name)) {
197      /*
198       * Enable interrupt
199       */
200      printk("is_pci_irq = TRUE - FIX THIS!\n");
201    }
202
203    if (is_processor_irq(irq->name)) {
204      /*
205       * Enable exception at processor level
206       */
207      printk("is_processor_irq = TRUE : Fix This\n");
208    }
209
210    /*
211     * Enable interrupt on device
212     */
213    if (irq->on) {
214        printk("Call 0x%x\n", irq->on );
215        irq->on(irq);
216    }
217
218    rtems_interrupt_enable(level);
219
220    return 1;
221}
222
223int BSP_get_current_rtems_irq_handler   (rtems_irq_connect_data* irq)
224{
225    rtems_interrupt_level       level;
226
227printk(" BSP_get_current_rtems_irq_handler %d\n", irq->name );
228    if (!isValidInterrupt(irq->name)) {
229      return 0;
230    }
231    rtems_interrupt_disable(level);
232      *irq = rtems_hdl_tbl[irq->name];
233    rtems_interrupt_enable(level);
234    return 1;
235}
236
237int BSP_remove_rtems_irq_handler  (const rtems_irq_connect_data* irq)
238{
239    rtems_irq_connect_data *pchain= NULL, *vchain = NULL;
240    rtems_interrupt_level       level;
241
242printk(" BSP_remove_rtems_irq_handler %d\n", irq->name );
243    if (!isValidInterrupt(irq->name)) {
244      return 0;
245    }
246    /*
247     * Check if default handler is actually connected. If not issue an error.
248     * You must first get the current handler via i386_get_current_idt_entry
249     * and then disconnect it using i386_delete_idt_entry.
250     * RATIONALE : to always have the same transition by forcing the user
251     * to get the previous handler before accepting to disconnect.
252     */
253    rtems_interrupt_disable(level);
254    if (rtems_hdl_tbl[irq->name].hdl != irq->hdl) {
255      rtems_interrupt_enable(level);
256      return 0;
257    }
258
259    if( (int)rtems_hdl_tbl[irq->name].next_handler != -1 )
260    {
261       int found = 0;
262
263       for( (pchain= NULL, vchain = &rtems_hdl_tbl[irq->name]);
264            (vchain->hdl != default_rtems_entry.hdl);
265            (pchain= vchain, vchain = (rtems_irq_connect_data*)vchain->next_handler) )
266       {
267          if( vchain->hdl == irq->hdl )
268          {
269             found= -1; break;
270          }
271       }
272
273       if( !found )
274       {
275          rtems_interrupt_enable(level);
276          return 0;
277       }
278    }
279    else
280    {
281       if (rtems_hdl_tbl[irq->name].hdl != irq->hdl)
282       {
283          rtems_interrupt_enable(level);
284         return 0;
285       }
286    }
287
288    /* XXX - FIX ME !! */
289    if (is_pci_irq(irq->name)) {
290      /*
291       * disable interrupt
292       */
293    }
294    if (is_processor_irq(irq->name)) {
295      /*
296       * disable exception at processor level
297       */
298    }
299
300    /*
301     * Disable interrupt on device
302     */
303        if (irq->off)
304        irq->off(irq);
305
306    /*
307     * restore the default irq value
308     */
309    if( !vchain )
310    {
311       /* single handler vector... */
312       rtems_hdl_tbl[irq->name] = default_rtems_entry;
313    }
314    else
315    {
316       if( pchain )
317       {
318          /* non-first handler being removed */
319          pchain->next_handler = vchain->next_handler;
320       }
321       else
322       {
323          /* first handler isn't malloc'ed, so just overwrite it.  Since
324          the contents of vchain are being struct copied, vchain itself
325          goes away */
326          rtems_hdl_tbl[irq->name]= *vchain;
327       }
328       free(vchain);
329    }
330
331    rtems_interrupt_enable(level);
332
333    return 1;
334}
335
336/*
337 * RTEMS Global Interrupt Handler Management Routines
338 */
339
340int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
341{
342    int                    i;
343    rtems_interrupt_level  level;
344
345    /*
346     * Store various code accelerators
347     */
348    internal_config             = config;
349    default_rtems_entry         = config->defaultEntry;
350    rtems_hdl_tbl               = config->irqHdlTbl;
351
352printk(" BSP_rtems_irq_mngt_set\n");
353
354    rtems_interrupt_disable(level);
355    /*
356     * set up internal tables used by rtems interrupt prologue
357     */
358
359    /*
360     *  XXX - FIX ME !!!
361     */
362    for (i=BSP_PCI_IRQ_LOWEST_OFFSET; i < BSP_PCI_IRQ_LOWEST_OFFSET + BSP_PCI_IRQ_NUMBER ; i++) {
363      if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
364         {
365            rtems_irq_connect_data* vchain;
366            for( vchain = &rtems_hdl_tbl[i];
367                 ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
368                 vchain = (rtems_irq_connect_data*)vchain->next_handler )
369            {
370                          if (vchain->on)
371                vchain->on(vchain);
372            }
373         }
374
375      }
376      else {
377         /* if (rtems_hdl_tbl[i].off) rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); */
378         {
379            rtems_irq_connect_data* vchain;
380            for( vchain = &rtems_hdl_tbl[i];
381                 ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
382                 vchain = (rtems_irq_connect_data*)vchain->next_handler )
383            {
384                          if (vchain->off)
385               vchain->off(vchain);
386            }
387         }
388      }
389    }
390    /*
391     * finish with Processor exceptions handled like IRQ
392     */
393    for (i=BSP_PROCESSOR_IRQ_LOWEST_OFFSET; i < BSP_PROCESSOR_IRQ_LOWEST_OFFSET+BSP_PROCESSOR_IRQ_NUMBER; i++){
394      if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
395         {
396            rtems_irq_connect_data* vchain;
397            for( vchain = &rtems_hdl_tbl[i];
398                 ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
399                 vchain = (rtems_irq_connect_data*)vchain->next_handler )
400            {
401                          if (vchain->on)
402               vchain->on(vchain);
403            }
404         }
405
406      }
407      else {
408         {
409            rtems_irq_connect_data* vchain;
410            for( vchain = &rtems_hdl_tbl[i];
411                 ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
412                 vchain = (rtems_irq_connect_data*)vchain->next_handler )
413            {
414                          if (vchain->off)
415               vchain->off(vchain);
416            }
417         }
418
419      }
420    }
421    rtems_interrupt_enable(level);
422    return 1;
423}
424
425int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** config)
426{
427    *config = internal_config;
428    return 0;
429}
430
431unsigned BSP_spuriousIntr = 0;
432
433/*
434 * High level IRQ handler called from shared_raw_irq_code_entry
435 */
436int C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
437{
438  register unsigned int irq;
439  register unsigned msr;
440  register unsigned new_msr;
441
442  if (excNum == ASM_DEC_VECTOR) {
443    _CPU_MSR_GET(msr);
444    new_msr = msr | MSR_EE;
445    _CPU_MSR_SET(new_msr);
446
447    rtems_hdl_tbl[BSP_DECREMENTER].hdl(rtems_hdl_tbl[BSP_DECREMENTER].handle);
448
449    _CPU_MSR_SET(msr);
450    return 0;
451
452  }
453
454  irq = read_and_clear_irq();
455  _CPU_MSR_GET(msr);
456  new_msr = msr | MSR_EE;
457  _CPU_MSR_SET(new_msr);
458
459  /* rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle); */
460  {
461     rtems_irq_connect_data* vchain;
462     for( vchain = &rtems_hdl_tbl[irq];
463          ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
464          vchain = (rtems_irq_connect_data*)vchain->next_handler )
465     {
466        vchain->hdl(vchain->handle);
467     }
468  }
469
470  _CPU_MSR_SET(msr);
471
472  return 0;
473}
474
475rtems_status_code bsp_interrupt_facility_initialize(void)
476{
477  /* Install exception handler */
478  if (ppc_exc_set_handler( ASM_EXT_VECTOR, C_dispatch_irq_handler)) {
479    return RTEMS_IO_ERROR;
480  }
481  if (ppc_exc_set_handler( ASM_DEC_VECTOR, C_dispatch_irq_handler)) {
482    return RTEMS_IO_ERROR;
483  }
484  if (ppc_exc_set_handler( ASM_E300_SYSMGMT_VECTOR, C_dispatch_irq_handler)) {
485    return RTEMS_IO_ERROR;
486  }
487
488  return RTEMS_SUCCESSFUL;
489}
490
491void bsp_interrupt_handler_default( rtems_vector_number vector )
492{
493  if (vector != BSP_DECREMENTER) {
494    printk( "Spurious interrupt: 0x%08x\n", vector);
495  }
496}
497
Note: See TracBrowser for help on using the repository browser.