Back to home page

LXR

 
 

    


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

0001 /* irq_init.c
0002  *
0003  *  This file contains the implementation of rtems initialization
0004  *  related to interrupt handling.
0005  *
0006  *  Copyright (c) 2009 embedded brains GmbH & Co. KG
0007  *  CopyRight (C) 1998 valette@crf.canon.fr
0008  *
0009  *  COPYRIGHT (c) 2011.
0010  *  On-Line Applications Research Corporation (OAR).
0011  *
0012  *  The license and distribution terms for this file may be
0013  *  found in the file LICENSE in this distribution or at
0014  *  http://www.rtems.org/license/LICENSE.
0015  */
0016 
0017 #include <rtems/bspIo.h>
0018 
0019 #include <rtems/score/cpu.h>
0020 
0021 #include <bsp.h>
0022 #include <bsp/irq.h>
0023 #include <bsp/irq-generic.h>
0024 
0025 /*
0026  * rtems prologue generated in irq_asm.S
0027  */
0028 extern void rtems_irq_prologue_0(void);
0029 extern void rtems_irq_prologue_1(void);
0030 extern void rtems_irq_prologue_2(void);
0031 extern void rtems_irq_prologue_3(void);
0032 extern void rtems_irq_prologue_4(void);
0033 extern void rtems_irq_prologue_5(void);
0034 extern void rtems_irq_prologue_6(void);
0035 extern void rtems_irq_prologue_7(void);
0036 extern void rtems_irq_prologue_8(void);
0037 extern void rtems_irq_prologue_9(void);
0038 extern void rtems_irq_prologue_10(void);
0039 extern void rtems_irq_prologue_11(void);
0040 extern void rtems_irq_prologue_12(void);
0041 extern void rtems_irq_prologue_13(void);
0042 extern void rtems_irq_prologue_14(void);
0043 extern void rtems_irq_prologue_15(void);
0044 extern void rtems_irq_prologue_16(void);
0045 /*
0046  * default vectors
0047  */
0048 extern void default_raw_idt_handler(void);
0049 
0050 /*
0051  * default raw on/off function
0052  */
0053 static void raw_nop_func(const struct __rtems_raw_irq_connect_data__ *unused)
0054 {
0055 }
0056 
0057 /*
0058  * default raw isOn function
0059  */
0060 static int raw_not_connected(
0061   const struct __rtems_raw_irq_connect_data__ *unused
0062 )
0063 {
0064   return 0;
0065 }
0066 
0067 static rtems_raw_irq_connect_data   idtHdl[IDT_SIZE];
0068 
0069 static rtems_raw_irq_hdl rtemsIrq[BSP_IRQ_VECTOR_NUMBER] = {
0070   rtems_irq_prologue_0,
0071   rtems_irq_prologue_1,
0072   rtems_irq_prologue_2,
0073   rtems_irq_prologue_3,
0074   rtems_irq_prologue_4,
0075   rtems_irq_prologue_5,
0076   rtems_irq_prologue_6,
0077   rtems_irq_prologue_7,
0078   rtems_irq_prologue_8,
0079   rtems_irq_prologue_9,
0080   rtems_irq_prologue_10,
0081   rtems_irq_prologue_11,
0082   rtems_irq_prologue_12,
0083   rtems_irq_prologue_13,
0084   rtems_irq_prologue_14,
0085   rtems_irq_prologue_15,
0086   rtems_irq_prologue_16,
0087 };
0088 
0089 static rtems_raw_irq_connect_data   defaultRawIrq = {
0090   0,                       /* vectorIdex */
0091   default_raw_idt_handler, /* hdl */
0092   raw_nop_func,            /* on */
0093   raw_nop_func,            /* off */
0094   raw_not_connected        /* isOn */
0095 };
0096 
0097 static interrupt_gate_descriptor    idtEntry;
0098 
0099 static rtems_raw_irq_global_settings raw_initial_config;
0100 
0101 
0102 /*
0103  *  This method is called from irq_asm.S and cannot be static.
0104  */
0105 void raw_idt_notify(void)
0106 {
0107   printk("raw_idt_notify has been called \n");
0108 }
0109 
0110 void  rtems_irq_mngt_init(void)
0111 {
0112     int             i;
0113     interrupt_gate_descriptor*  idt_entry_tbl;
0114     unsigned int                limit;
0115     rtems_interrupt_level       level;
0116 
0117     i386_get_info_from_IDTR(&idt_entry_tbl, &limit);
0118 
0119     /* Convert into number of entries */
0120     limit = (limit + 1)/sizeof(interrupt_gate_descriptor);
0121 
0122     if(limit != IDT_SIZE) {
0123        printk("IDT table size mismatch !!! System locked\n");
0124        while(1);
0125     }
0126 
0127     /*
0128      * The interrupt management can be initialized only once
0129      * during system bootup and that should happen on boot
0130      * CPU so there is no need to synchronize with others CPUs.
0131      */
0132     rtems_interrupt_local_disable(level);
0133 
0134     /*
0135      * Init the complete IDT vector table with defaultRawIrq value
0136      */
0137     for (i = 0; i < IDT_SIZE ; i++) {
0138       idtHdl[i]      = defaultRawIrq;
0139       idtHdl[i].idtIndex = i;
0140     }
0141 
0142     raw_initial_config.idtSize = IDT_SIZE;
0143     raw_initial_config.defaultRawEntry = defaultRawIrq;
0144     raw_initial_config.rawIrqHdlTbl = idtHdl;
0145 
0146     if (!i386_init_idt (&raw_initial_config)) {
0147       /*
0148        * put something here that will show the failure...
0149        */
0150       printk("Unable to initialize IDT!!! System locked\n");
0151       while (1);
0152     }
0153     /*
0154      * Patch the entry that will be used by RTEMS for interrupt management
0155      * with RTEMS prologue.
0156      */
0157     for (i = 0; i < BSP_IRQ_VECTOR_NUMBER; i++) {
0158       create_interrupt_gate_descriptor(&idtEntry, rtemsIrq[i]);
0159       idt_entry_tbl[i + BSP_ASM_IRQ_VECTOR_BASE] = idtEntry;
0160     }
0161     /*
0162      * At this point we have completed the initialization of IDT
0163      * with raw handlers.  We must now initialize the higher level
0164      * interrupt management.
0165      */
0166 
0167     /*
0168      * Init initial Interrupt management config
0169      */
0170     bsp_interrupt_initialize();
0171 
0172     /*
0173      * #define DEBUG
0174      */
0175 #ifdef DEBUG
0176     {
0177       /*
0178        * following adresses should be the same
0179        */
0180       unsigned tmp;
0181 
0182       printk("idt_entry_tbl =  %x Interrupt_descriptor_table addr = %x\n",
0183          idt_entry_tbl, &Interrupt_descriptor_table);
0184       tmp = (unsigned) get_hdl_from_vector (BSP_ASM_IRQ_VECTOR_BASE + BSP_PERIODIC_TIMER);
0185       printk("clock isr address from idt = %x should be %x\n",
0186          tmp, (unsigned) rtems_irq_prologue_0);
0187     }
0188     printk("i8259s_cache = %x\n", * (unsigned short*) &i8259s_cache);
0189     BSP_wait_polled_input();
0190 #endif
0191 }