apic_timer.c 2.0 KB

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