interrupt.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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 <rthw.h>
  11. #include <rtthread.h>
  12. #include <bsp.h>
  13. extern void rt_hw_idt_init(void);
  14. /* exception and interrupt handler table */
  15. struct rt_irq_desc irq_desc[MAX_HANDLERS];
  16. rt_uint16_t irq_mask_8259A = 0xFFFF;
  17. rt_inline rt_bool_t _interrupt_vector_is_valid(int vector)
  18. {
  19. return (vector >= 0) && (vector < MAX_HANDLERS);
  20. }
  21. void rt_hw_interrupt_handle(int vector, void* param);
  22. /**
  23. * @addtogroup I386
  24. */
  25. /*@{*/
  26. /**
  27. * This function initializes 8259 interrupt controller
  28. */
  29. void rt_hw_pic_init()
  30. {
  31. outb(IO_PIC1, 0x11);
  32. outb(IO_PIC1+1, IRQ_OFFSET);
  33. outb(IO_PIC1+1, 1<<IRQ_SLAVE);
  34. outb(IO_PIC1+1, 0x3);
  35. outb(IO_PIC1+1, 0xff);
  36. outb(IO_PIC1, 0x68);
  37. outb(IO_PIC1, 0x0a);
  38. outb(IO_PIC2, 0x11);
  39. outb(IO_PIC2+1, IRQ_OFFSET + 8);
  40. outb(IO_PIC2+1, IRQ_SLAVE);
  41. outb(IO_PIC2+1, 0x3);
  42. outb(IO_PIC2+1, 0xff);
  43. outb(IO_PIC2, 0x68);
  44. outb(IO_PIC2, 0x0a);
  45. if (irq_mask_8259A != 0xFFFF)
  46. {
  47. outb(IO_PIC1+1, (char)irq_mask_8259A);
  48. outb(IO_PIC2+1, (char)(irq_mask_8259A >> 8));
  49. }
  50. }
  51. void rt_hw_interrupt_handle(int vector, void* param)
  52. {
  53. rt_kprintf("Unhandled interrupt %d occurred!!!\n", vector);
  54. }
  55. void rt_hw_isr(int vector)
  56. {
  57. if (vector < MAX_HANDLERS)
  58. {
  59. irq_desc[vector].handler(vector, irq_desc[vector].param);
  60. }
  61. }
  62. /**
  63. * This function initializes interrupt descript table and 8259 interrupt controller
  64. *
  65. */
  66. void rt_hw_interrupt_init(void)
  67. {
  68. int idx;
  69. rt_hw_idt_init();
  70. rt_hw_pic_init();
  71. /* init exceptions table */
  72. for(idx=0; idx < MAX_HANDLERS; idx++)
  73. {
  74. irq_desc[idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle;
  75. irq_desc[idx].param = RT_NULL;
  76. #ifdef RT_USING_INTERRUPT_INFO
  77. rt_snprintf(irq_desc[idx].name, RT_NAME_MAX - 1, "default");
  78. irq_desc[idx].counter = 0;
  79. #endif
  80. }
  81. }
  82. void rt_hw_interrupt_umask(int vector)
  83. {
  84. if (!_interrupt_vector_is_valid(vector))
  85. {
  86. return;
  87. }
  88. irq_mask_8259A = irq_mask_8259A & ~(rt_uint16_t)(1U << 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. if (!_interrupt_vector_is_valid(vector))
  95. {
  96. return;
  97. }
  98. irq_mask_8259A = irq_mask_8259A | (rt_uint16_t)(1U << vector);
  99. outb(IO_PIC1+1, (char)irq_mask_8259A);
  100. outb(IO_PIC2+1, (char)(irq_mask_8259A >> 8));
  101. }
  102. rt_isr_handler_t rt_hw_interrupt_install(int vector,
  103. rt_isr_handler_t handler,
  104. void *param,
  105. const char *name)
  106. {
  107. rt_isr_handler_t old_handler = RT_NULL;
  108. if(vector < MAX_HANDLERS)
  109. {
  110. old_handler = irq_desc[vector].handler;
  111. if (handler != RT_NULL)
  112. {
  113. irq_desc[vector].handler = (rt_isr_handler_t)handler;
  114. irq_desc[vector].param = param;
  115. #ifdef RT_USING_INTERRUPT_INFO
  116. rt_snprintf(irq_desc[vector].name, RT_NAME_MAX - 1, "%s", name);
  117. irq_desc[vector].counter = 0;
  118. #endif
  119. }
  120. }
  121. return old_handler;
  122. }
  123. /*@}*/