new: 为ipi添加xapic支持

This commit is contained in:
fslongjin
2022-09-01 17:40:11 +08:00
parent 588603a10a
commit dffa51b1ef
7 changed files with 140 additions and 179 deletions

View File

@ -12,27 +12,32 @@ extern uint64_t apic_timer_ticks_result;
#pragma GCC push_options
#pragma GCC optimize("O0")
/**
* @brief 设置apic定时器的分频计数
*
* @param divider 分频除数
*/
#define apic_timer_set_div(divider) \
do \
{ \
wrmsr(0x83e, divider); \
} while (0)
static __always_inline void apic_timer_set_div(uint64_t divider)
{
if (CURRENT_APIC_STATE == APIC_X2APIC_ENABLED)
wrmsr(0x83e, divider);
else
*(uint32_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_CLKDIV) = (uint32_t)divider;
}
/**
* @brief 设置apic定时器的初始计数值
*
* @param init_cnt 初始计数值
*/
#define apic_timer_set_init_cnt(init_cnt) \
do \
{ \
wrmsr(0x838, init_cnt); \
} while (0)
static __always_inline void apic_timer_set_init_cnt(uint32_t init_cnt)
{
if (CURRENT_APIC_STATE == APIC_X2APIC_ENABLED)
wrmsr(0x838, init_cnt);
else
*(uint32_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_INITIAL_COUNT_REG) = (uint32_t)init_cnt;
}
/**
* @brief 设置apic定时器的lvt并启动定时器
@ -41,28 +46,46 @@ extern uint64_t apic_timer_ticks_result;
* @param mask 是否屏蔽1屏蔽 0不屏蔽
* @param mode 计时模式
*/
#define apic_timer_set_LVT(vector, mask, mode) \
do \
{ \
wrmsr(0x832, (mode << 17) | vector | (mask ? (APIC_LVT_INT_MASKED) : 0)); \
} while (0)
static __always_inline void apic_timer_set_LVT(uint32_t vector, uint32_t mask, uint32_t mode)
{
register uint32_t val = (mode << 17) | vector | (mask ? (APIC_LVT_INT_MASKED) : 0);
if (CURRENT_APIC_STATE == APIC_X2APIC_ENABLED)
wrmsr(0x832, val);
else
*(uint32_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER) = (uint32_t)val;
}
#define apic_timer_write_LVT(value) \
do \
{ \
wrmsr(0x832, value); \
} while (0)
static __always_inline void apic_timer_write_LVT(uint32_t value)
{
if (CURRENT_APIC_STATE == APIC_X2APIC_ENABLED)
wrmsr(0x832, value);
else
*(uint32_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER) = (uint32_t)value;
}
/**
* @brief 获取apic定时器的LVT的值
*
*/
#define apic_timer_get_LVT() (rdmsr(0x832))
static __always_inline uint32_t apic_timer_get_LVT()
{
if (CURRENT_APIC_STATE == APIC_X2APIC_ENABLED)
return rdmsr(0x832);
else
return *(uint32_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER);
}
/**
* @brief 获取apic定时器当前计数值
*
*/
#define apic_timer_get_current() (rdmsr(0x839))
static __always_inline uint32_t apic_timer_get_current()
{
if (CURRENT_APIC_STATE == APIC_X2APIC_ENABLED)
return (uint32_t)rdmsr(0x839);
else
return *(uint32_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_CURRENT_COUNT_REG);
}
/**
* @brief 停止apic定时器
@ -71,7 +94,7 @@ extern uint64_t apic_timer_ticks_result;
#define apic_timer_stop() \
do \
{ \
uint64_t val = apic_timer_get_LVT(); \
uint32_t val = apic_timer_get_LVT(); \
val |= APIC_LVT_INT_MASKED; \
apic_timer_write_LVT(val); \
} while (0)