interrupt.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2015/9/15 Bernard Update to new interrupt framework.
  9. */
  10. #include <rtthread.h>
  11. #include <rthw.h>
  12. #include <bsp.h>
  13. extern rt_uint32_t rt_interrupt_nest;
  14. extern void rt_hw_idt_init(void);
  15. rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
  16. rt_uint32_t rt_thread_switch_interrupt_flag;
  17. /* exception and interrupt handler table */
  18. struct rt_irq_desc irq_desc[MAX_HANDLERS];
  19. rt_uint16_t irq_mask_8259A = 0xFFFF;
  20. void rt_hw_interrupt_handle(int vector, void* param);
  21. /**
  22. * @addtogroup I386
  23. */
  24. /*@{*/
  25. /**
  26. * This function initializes 8259 interrupt controller
  27. */
  28. void rt_hw_pic_init()
  29. {
  30. outb(IO_PIC1, 0x11);
  31. outb(IO_PIC1+1, IRQ_OFFSET);
  32. outb(IO_PIC1+1, 1<<IRQ_SLAVE);
  33. outb(IO_PIC1+1, 0x3);
  34. outb(IO_PIC1+1, 0xff);
  35. outb(IO_PIC1, 0x68);
  36. outb(IO_PIC1, 0x0a);
  37. outb(IO_PIC2, 0x11);
  38. outb(IO_PIC2+1, IRQ_OFFSET + 8);
  39. outb(IO_PIC2+1, IRQ_SLAVE);
  40. outb(IO_PIC2+1, 0x3);
  41. outb(IO_PIC2+1, 0xff);
  42. outb(IO_PIC2, 0x68);
  43. outb(IO_PIC2, 0x0a);
  44. if (irq_mask_8259A != 0xFFFF)
  45. {
  46. outb(IO_PIC1+1, (char)irq_mask_8259A);
  47. outb(IO_PIC2+1, (char)(irq_mask_8259A >> 8));
  48. }
  49. /* init interrupt nest, and context */
  50. rt_interrupt_nest = 0;
  51. rt_interrupt_from_thread = 0;
  52. rt_interrupt_to_thread = 0;
  53. rt_thread_switch_interrupt_flag = 0;
  54. }
  55. void rt_hw_interrupt_handle(int vector, void* param)
  56. {
  57. rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
  58. }
  59. void rt_hw_isr(int vector)
  60. {
  61. if (vector < MAX_HANDLERS)
  62. {
  63. irq_desc[vector].handler(vector, irq_desc[vector].param);
  64. }
  65. }
  66. /**
  67. * This function initializes interrupt descript table and 8259 interrupt controller
  68. *
  69. */
  70. void rt_hw_interrupt_init(void)
  71. {
  72. int idx;
  73. rt_hw_idt_init();
  74. rt_hw_pic_init();
  75. /* init exceptions table */
  76. for(idx=0; idx < MAX_HANDLERS; idx++)
  77. {
  78. irq_desc[idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle;
  79. irq_desc[idx].param = RT_NULL;
  80. #ifdef RT_USING_INTERRUPT_INFO
  81. rt_snprintf(irq_desc[idx].name, RT_NAME_MAX - 1, "default");
  82. irq_desc[idx].counter = 0;
  83. #endif
  84. }
  85. }
  86. void rt_hw_interrupt_umask(int vector)
  87. {
  88. irq_mask_8259A = irq_mask_8259A&~(1<<vector);
  89. outb(IO_PIC1+1, (char)irq_mask_8259A);
  90. outb(IO_PIC2+1, (char)(irq_mask_8259A >> 8));
  91. }
  92. void rt_hw_interrupt_mask(int vector)
  93. {
  94. irq_mask_8259A = irq_mask_8259A | (1<<vector);
  95. outb(IO_PIC1+1, (char)irq_mask_8259A);
  96. outb(IO_PIC2+1, (char)(irq_mask_8259A >> 8));
  97. }
  98. rt_isr_handler_t rt_hw_interrupt_install(int vector,
  99. rt_isr_handler_t handler,
  100. void *param,
  101. const char *name)
  102. {
  103. rt_isr_handler_t old_handler = RT_NULL;
  104. if(vector < MAX_HANDLERS)
  105. {
  106. old_handler = irq_desc[vector].handler;
  107. if (handler != RT_NULL)
  108. {
  109. irq_desc[vector].handler = (rt_isr_handler_t)handler;
  110. irq_desc[vector].param = param;
  111. #ifdef RT_USING_INTERRUPT_INFO
  112. rt_snprintf(irq_desc[vector].name, RT_NAME_MAX - 1, "%s", name);
  113. irq_desc[vector].counter = 0;
  114. #endif
  115. }
  116. }
  117. return old_handler;
  118. }
  119. rt_base_t rt_hw_interrupt_disable(void)
  120. {
  121. rt_base_t level;
  122. __asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (level): :"memory");
  123. return level;
  124. }
  125. void rt_hw_interrupt_enable(rt_base_t level)
  126. {
  127. __asm__ __volatile__("pushl %0 ; popfl": :"g" (level):"memory", "cc");
  128. }
  129. /*@}*/