🆕 测量local apic定时器频率

This commit is contained in:
fslongjin
2022-07-11 18:40:23 +08:00
parent 7d64ad6c1a
commit 4c9719f477
11 changed files with 260 additions and 54 deletions

View File

@ -0,0 +1,14 @@
all: pic.o
# 中断处理芯片的驱动程序
ifeq ($(PIC), _INTR_8259A_)
pic.o: 8259A/8259A.c
gcc $(CFLAGS) -c 8259A/8259A.c -o pic.o
else
pic.o: apic/apic.c apic_timer.o
gcc $(CFLAGS) -c apic/apic.c -o pic.o
apic_timer.o: apic/apic_timer.c
gcc $(CFLAGS) -c apic/apic_timer.c -o apic/apic_timer.o
endif

View File

@ -187,7 +187,7 @@ void apic_init_ap_core_local_apic()
void apic_local_apic_init()
{
// 映射Local APIC 寄存器地址
mm_map_phys_addr(APIC_LOCAL_APIC_VIRT_BASE_ADDR, 0xfee00000, PAGE_2M_SIZE, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD);
mm_map_phys_addr(APIC_LOCAL_APIC_VIRT_BASE_ADDR, 0xfee00000UL, PAGE_2M_SIZE, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD);
uint a, b, c, d;
cpu_cpuid(1, 0, &a, &b, &c, &d);
@ -235,6 +235,7 @@ void apic_local_apic_init()
// 检测是否成功启用xAPIC和x2APIC
if (eax & 0xc00)
kinfo("xAPIC & x2APIC enabled!");
/*
io_mfence();
uint *svr = (uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_SVR);
@ -336,7 +337,7 @@ void apic_local_apic_init()
io_mfence();
kdebug("cmci = %#018lx", *(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_CMCI));
*/
*(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER) = 0x10000;
*(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER) = APIC_LVT_INT_MASKED;
io_mfence();
/*
*(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_THERMAL) = 0x1000000;

View File

@ -202,6 +202,7 @@ struct apic_IO_APIC_RTE_entry
// 屏蔽
#define UNMASKED 0
#define MASKED 1
#define APIC_LVT_INT_MASKED 0x10000
// 触发模式
#define EDGE_TRIGGER 0 // 边沿触发

View File

@ -0,0 +1,3 @@
#include "apic_timer.h"
uint64_t apic_timer_ticksIn1ms = 0;

View File

@ -0,0 +1,60 @@
#pragma once
#include <common/unistd.h>
#include "apic.h"
extern uint64_t apic_timer_ticksIn1ms;
/**
* @brief 设置apic定时器的分频计数
*
* @param divider 分频除数
*/
#define apic_timer_set_div(divider) \
do \
{ \
wrmsr(0x83e, divider); \
} while (0)
/**
* @brief 设置apic定时器的初始计数值
*
* @param init_cnt 初始计数值
*/
#define apic_timer_set_init_cnt(init_cnt) \
do \
{ \
wrmsr(0x838, init_cnt); \
} while (0)
/**
* @brief 停止apic定时器
*
*/
#define apic_timer_stop() \
do \
{ \
wrmsr(0x832, APIC_LVT_INT_MASKED); \
} while (0)
/**
* @brief 设置apic定时器的lvt并启动定时器
*
*/
#define apic_timer_set_LVT(vector, mode) \
do \
{ \
wrmsr(0x832, (mode << 17) | vector); \
io_mfence(); \
} while (0)
/**
* @brief 获取apic定时器的LVT的值
*
*/
#define apic_timer_get_LVT() (rdmsr(0x832))
/**
* @brief 获取apic定时器当前计数值
*
*/
#define apic_timer_get_current() (rdmsr(0x839))