🆕 测定tsc频率

This commit is contained in:
fslongjin 2022-07-27 21:05:33 +08:00
parent 72b67ddf1c
commit 4bc64de8f9
7 changed files with 57 additions and 32 deletions

View File

@ -112,7 +112,8 @@
"time.h": "c",
"ia64_msi.h": "c",
"errno.h": "c",
"bug.h": "c"
"bug.h": "c",
"apic_timer.h": "c"
},
"C_Cpp.errorSquiggles": "Enabled",
"esbonio.sphinx.confDir": ""

View File

@ -26,6 +26,8 @@ uint Cpu_Processor_Type;
uint Cpu_max_phys_addrline_size;
// 处理器支持的最大线性地址可寻址地址线宽度
uint Cpu_max_linear_addrline_size;
// 处理器的tsc频率单位hz(HPET定时器在测定apic频率时顺便测定了这个值)
uint64_t Cpu_tsc_freq = 0;
struct cpu_core_info_t cpu_core_info[MAX_CPU_NUM];
void cpu_init(void)
@ -115,6 +117,6 @@ uint32_t cpu_get_core_crysral_freq()
: "0"(0x15), "2"(0)
: "memory");
// kdebug("Cpu_cpuid_max_Basic_mop = %#03x, a=%ld, b=%ld, c=%ld, d=%ld", Cpu_cpuid_max_Basic_mop, a, b, c, d);
return c;
}

View File

@ -29,39 +29,41 @@ extern uint32_t Cpu_max_phys_addrline_size;
// 处理器支持的最大线性地址可寻址地址线宽度
extern uint32_t Cpu_max_linear_addrline_size;
// 处理器的tsc频率单位hz(HPET定时器在测定apic频率时顺便测定了这个值)
extern uint64_t Cpu_tsc_freq;
/**
* @brief cpuid指令
*
*
* @param mop
* @param sop
* @param eax eax值
* @param ebx ebx值
* @param ecx ecx值
* @param edx edx值
*
*
* cpuid指令参考英特尔开发手册卷2A Chapter3 3.2 Instruction
*/
void cpu_cpuid(uint32_t mop, uint32_t sop, uint32_t *eax, uint32_t*ebx, uint32_t*ecx, uint32_t*edx);
void cpu_cpuid(uint32_t mop, uint32_t sop, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
/**
* @brief
*
*
*/
void cpu_init(void);
struct cpu_core_info_t
{
uint64_t stack_start; // 栈基地址
uint64_t ist_stack_start; // IST栈基地址
uint64_t tss_vaddr; // tss地址
uint64_t stack_start; // 栈基地址
uint64_t ist_stack_start; // IST栈基地址
uint64_t tss_vaddr; // tss地址
};
extern struct cpu_core_info_t cpu_core_info[MAX_CPU_NUM];
/**
* @brief cpu核心晶振频率
*
*
* @return uint32_t cpu核心晶振频率
*/
uint32_t cpu_get_core_crysral_freq();

View File

@ -10,6 +10,7 @@
#include <stdint.h>
#include <common/stddef.h>
#include <arch/arch.h>
#include <common/compiler.h>
#define sti() __asm__ __volatile__("sti\n\t" :: \
: "memory") //开启外部中断
@ -27,6 +28,13 @@
#define io_lfence() __asm__ __volatile__("lfence\n\t" :: \
: "memory") // 在lfence指令前的读操作必须在lfence指令后的读操作前完成。
#define rdtsc() ({ \
uint64_t tmp1 = 0, tmp2 = 0; \
asm volatile("rdtsc" \
: "=d"(tmp1), "=a"(tmp2)::"memory"); \
(tmp1 << 32 | tmp2); \
})
/**
* @brief member的基地址
* @param ptr member的指针
@ -170,7 +178,7 @@ static inline struct List *list_next(struct List *entry)
//计算字符串的长度经过测试该版本比采用repne/scasb汇编的运行速度快16.8%左右)
static inline int strlen(const char *s)
{
if(s == NULL)
if (s == NULL)
return 0;
register int __res = 0;
while (s[__res] != '\0')
@ -182,10 +190,10 @@ static inline int strlen(const char *s)
/**
* @brief
*
*
* @param src
* @param maxlen
* @return long
* @return long
*/
long strnlen(const char *src, unsigned long maxlen);
@ -213,14 +221,14 @@ void *memset(void *dst, unsigned char C, ul size)
return dst;
}
void *memset_c(void* dst, uint8_t c, size_t count)
void *memset_c(void *dst, uint8_t c, size_t count)
{
uint8_t* xs = (uint8_t*)dst;
while (count--)
*xs++ = c;
return dst;
uint8_t *xs = (uint8_t *)dst;
while (count--)
*xs++ = c;
return dst;
}
/**
@ -233,7 +241,7 @@ void *memset_c(void* dst, uint8_t c, size_t count)
*/
static void *memcpy(void *dst, const void *src, long Num)
{
int d0=0, d1=0, d2=0;
int d0 = 0, d1 = 0, d2 = 0;
__asm__ __volatile__("cld \n\t"
"rep \n\t"
"movsq \n\t"
@ -283,7 +291,6 @@ int strcmp(char *FirstPart, char *SecondPart)
return __res;
}
// 从io口读入8个bit
unsigned char io_in8(unsigned short port)
{

View File

@ -18,7 +18,13 @@ static uint32_t HPET_COUNTER_CLK_PERIOD = 0; // 主计数器时间精度(单
static double HPET_freq = 0; // 主计时器频率
static uint8_t HPET_NUM_TIM_CAP = 0; // 定时器数量
static char measure_apic_timer_flag; // 初始化apic时钟时所用到的标志变量
extern struct rtc_time_t rtc_now; // 导出全局墙上时钟
// 测定tsc频率的临时变量
static uint64_t test_tsc_start = 0;
static uint64_t test_tsc_end = 0;
extern uint64_t Cpu_tsc_freq; // 导出自cpu.c
extern struct rtc_time_t rtc_now; // 导出全局墙上时钟
enum
{
@ -91,11 +97,12 @@ void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
}
/**
* @brief apic定时器频率的中断回调函数
* @brief apic定时器以及tsc的频率的中断回调函数
*
*/
void HPET_measure_apic_timer_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
void HPET_measure_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
{
test_tsc_end = rdtsc();
// 停止apic定时器
// 写入每1ms的ticks
apic_timer_stop();
@ -104,10 +111,10 @@ void HPET_measure_apic_timer_handler(uint64_t number, uint64_t param, struct pt_
}
/**
* @brief apic定时器的频率
* @brief apic定时器以及tsc的频率
*
*/
void HPET_measure_apic_timer_freq()
void HPET_measure_freq()
{
kinfo("Measuring local APIC timer's frequency...");
const uint64_t interval = APIC_TIMER_INTERVAL; // 测量给定时间内的计数
@ -136,7 +143,7 @@ void HPET_measure_apic_timer_freq()
measure_apic_timer_flag = false;
// 注册中断
irq_register(34, &entry, &HPET_measure_apic_timer_handler, 0, &HPET_intr_controller, "HPET0 measure");
irq_register(34, &entry, &HPET_measure_handler, 0, &HPET_intr_controller, "HPET0 measure");
// 设置div16
apic_timer_stop();
@ -148,6 +155,8 @@ void HPET_measure_apic_timer_freq()
// 启动apic定时器
apic_timer_set_LVT(151, 0, APIC_LVT_Timer_One_Shot);
*(uint64_t *)(HPET_REG_BASE + GEN_CONF) = 3; // 置位旧设备中断路由兼容标志位、定时器组使能标志位,开始计时
// 顺便测定tsc频率
test_tsc_start = rdtsc();
io_mfence();
while (measure_apic_timer_flag == false)
@ -158,6 +167,10 @@ void HPET_measure_apic_timer_freq()
*(uint64_t *)(HPET_REG_BASE + GEN_CONF) = 0; // 停用HPET定时器
io_mfence();
kinfo("Local APIC timer's freq: %d ticks/ms.", apic_timer_ticks_result);
// 计算tsc频率
Cpu_tsc_freq = (test_tsc_end - test_tsc_start) * (1000UL / interval);
kinfo("TSC frequency: %ldMHz", Cpu_tsc_freq / 1000000);
}
/**

View File

@ -10,10 +10,10 @@
int HPET_init();
/**
* @brief apic定时器的频率
* @brief apic定时器以及tsc的频率
*
*/
void HPET_measure_apic_timer_freq();
void HPET_measure_freq();
/**
* @brief HPET周期中断5ms

View File

@ -144,7 +144,7 @@ void system_initialize()
// process_init();
HPET_init();
HPET_measure_apic_timer_freq();
HPET_measure_freq();
// current_pcb->preempt_count = 0;
// kdebug("cpu_get_core_crysral_freq()=%ld", cpu_get_core_crysral_freq());