apic_timer.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #include "apic_timer.h"
  2. #include <exception/irq.h>
  3. #include <process/process.h>
  4. #include <common/kprint.h>
  5. #include <sched/sched.h>
  6. uint64_t apic_timer_ticks_result = 0;
  7. void apic_timer_enable(uint64_t irq_num)
  8. {
  9. // 启动apic定时器
  10. uint64_t val = apic_timer_get_LVT();
  11. val &= (~APIC_LVT_INT_MASKED);
  12. apic_timer_write_LVT(val);
  13. }
  14. void apic_timer_disable(uint64_t irq_num)
  15. {
  16. apic_timer_stop();
  17. }
  18. /**
  19. * @brief 安装local apic定时器中断
  20. *
  21. * @param irq_num 中断向量号
  22. * @param arg 初始计数值
  23. * @return uint64_t
  24. */
  25. uint64_t apic_timer_install(ul irq_num, void *arg)
  26. {
  27. // 设置div16
  28. apic_timer_stop();
  29. apic_timer_set_div(APIC_TIMER_DIVISOR);
  30. // 设置初始计数
  31. apic_timer_set_init_cnt(*(uint64_t *)arg);
  32. // 填写LVT
  33. apic_timer_set_LVT(APIC_TIMER_IRQ_NUM, 1, APIC_LVT_Timer_Periodic);
  34. }
  35. void apic_timer_uninstall(ul irq_num)
  36. {
  37. apic_timer_write_LVT(APIC_LVT_INT_MASKED);
  38. }
  39. hardware_intr_controller apic_timer_intr_controller =
  40. {
  41. .enable = apic_timer_enable,
  42. .disable = apic_timer_disable,
  43. .install = apic_timer_install,
  44. .uninstall = apic_timer_uninstall,
  45. .ack = apic_local_apic_edge_ack,
  46. };
  47. /**
  48. * @brief local apic定时器的中断处理函数
  49. *
  50. * @param number 中断向量号
  51. * @param param 参数
  52. * @param regs 寄存器值
  53. */
  54. void apic_timer_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
  55. {
  56. sched_update_jiffies();
  57. }
  58. /**
  59. * @brief 初始化local APIC定时器
  60. *
  61. */
  62. void apic_timer_init()
  63. {
  64. if (apic_timer_ticks_result == 0)
  65. {
  66. kBUG("APIC timer ticks in 5ms is equal to ZERO!");
  67. while (1)
  68. hlt();
  69. }
  70. kinfo("Initializing apic timer for cpu %d", proc_current_cpu_id);
  71. irq_register(APIC_TIMER_IRQ_NUM, &apic_timer_ticks_result, &apic_timer_handler, 0, &apic_timer_intr_controller, "apic timer");
  72. kinfo("Successfully initialized apic timer for cpu %d", proc_current_cpu_id);
  73. }