irq.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #include "irq.h"
  2. #include <common/errno.h>
  3. #include <common/asm.h>
  4. #include <common/printk.h>
  5. #include <common/string.h>
  6. #include <mm/slab.h>
  7. #include <arch/arch.h>
  8. #pragma GCC push_options
  9. #pragma GCC optimize("O0")
  10. /**
  11. * @brief 中断注册函数
  12. *
  13. * @param irq_num 中断向量号
  14. * @param arg 传递给中断安装接口的参数
  15. * @param handler 中断处理函数
  16. * @param paramater 中断处理函数的参数
  17. * @param controller 中断控制器结构
  18. * @param irq_name 中断名
  19. * @return int
  20. */
  21. int irq_register(ul irq_num, void *arg, void (*handler)(ul irq_num, ul parameter, struct pt_regs *regs), ul paramater,
  22. hardware_intr_controller *controller, char *irq_name)
  23. {
  24. // 由于为I/O APIC分配的中断向量号是从32开始的,因此要减去32才是对应的interrupt_desc的元素
  25. irq_desc_t *p = NULL;
  26. if (irq_num >= 32 && irq_num < 0x80)
  27. p = &interrupt_desc[irq_num - 32];
  28. else if (irq_num >= 150 && irq_num < 200)
  29. p = &local_apic_interrupt_desc[irq_num - 150];
  30. else
  31. {
  32. kerror("irq_register(): invalid irq num: %ld.", irq_num);
  33. return -EINVAL;
  34. }
  35. p->controller = controller;
  36. if (p->irq_name == NULL)
  37. {
  38. int namelen = sizeof(strlen(irq_name) + 1);
  39. p->irq_name = (char *)kmalloc(namelen, 0);
  40. memset(p->irq_name, 0, namelen);
  41. strncpy(p->irq_name, irq_name, namelen);
  42. }
  43. p->parameter = paramater;
  44. p->flags = 0;
  45. p->handler = handler;
  46. io_mfence();
  47. p->controller->install(irq_num, arg);
  48. io_mfence();
  49. p->controller->enable(irq_num);
  50. io_mfence();
  51. return 0;
  52. }
  53. /**
  54. * @brief 中断注销函数
  55. *
  56. * @param irq_num 中断向量号
  57. * @return int
  58. */
  59. int irq_unregister(ul irq_num)
  60. {
  61. irq_desc_t *p = &interrupt_desc[irq_num - 32];
  62. p->controller->disable(irq_num);
  63. p->controller->uninstall(irq_num);
  64. p->controller = NULL;
  65. if (p->irq_name)
  66. kfree(p->irq_name);
  67. p->irq_name = NULL;
  68. p->parameter = (ul)NULL;
  69. p->flags = 0;
  70. p->handler = NULL;
  71. return 0;
  72. }
  73. #pragma GCC optimize("O0")