91 lines
2.6 KiB
C
91 lines
2.6 KiB
C
/*
|
|
* Copyright (c) 2020 Institute of Parallel And Distributed Systems (IPADS),
|
|
* Shanghai Jiao Tong University (SJTU) OS-Lab-2020 (i.e., ChCore) is licensed
|
|
* under the Mulan PSL v1. You can use this software according to the terms and
|
|
* conditions of the Mulan PSL v1. You may obtain a copy of Mulan PSL v1 at:
|
|
* http://license.coscl.org.cn/MulanPSL
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
|
|
* KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
* NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the
|
|
* Mulan PSL v1 for more details.
|
|
*/
|
|
|
|
#include <common/kprint.h>
|
|
#include <common/machine.h>
|
|
#include <common/smp.h>
|
|
#include <common/tools.h>
|
|
#include <common/types.h>
|
|
#include <exception/irq.h>
|
|
#include <exception/timer.h>
|
|
#include <process/thread.h>
|
|
#include <sched/sched.h>
|
|
|
|
u64 cntv_tval;
|
|
|
|
/* Per core IRQ SOURCE MMIO address */
|
|
u64 core_timer_irqcntl[PLAT_CPU_NUM] = {
|
|
CORE0_TIMER_IRQCNTL, CORE1_TIMER_IRQCNTL, CORE2_TIMER_IRQCNTL,
|
|
CORE3_TIMER_IRQCNTL
|
|
};
|
|
|
|
void timer_init(void)
|
|
{
|
|
u64 cur_freq = 0;
|
|
u64 cur_cnt = 0;
|
|
u64 count_down = 0;
|
|
u64 timer_ctl = 0;
|
|
u32 cpuid = smp_get_cpu_id();
|
|
|
|
/* Since QEMU only emulate the generic timer, we use the generic timer
|
|
* here */
|
|
asm volatile ("mrs %0, cntpct_el0":"=r" (cur_cnt));
|
|
kdebug("timer init cntpct_el0 = %lu\n", cur_cnt);
|
|
asm volatile ("mrs %0, cntfrq_el0":"=r" (cur_freq));
|
|
kdebug("timer init cntfrq_el0 = %lu\n", cur_freq);
|
|
|
|
/* Calculate the tv */
|
|
cntv_tval = (cur_freq * TICK_MS / 1000);
|
|
kdebug("CPU freq %lu, set timer %lu\n", cur_freq, cntv_tval);
|
|
|
|
/* set the timervalue here */
|
|
asm volatile ("msr cntv_tval_el0, %0"::"r" (cntv_tval));
|
|
asm volatile ("mrs %0, cntv_tval_el0":"=r" (count_down));
|
|
kdebug("timer init cntv_tval_el0 = %lu\n", count_down);
|
|
|
|
put32(core_timer_irqcntl[cpuid], INT_SRC_TIMER3);
|
|
|
|
/* Set the control register */
|
|
timer_ctl = 0 << 1 | 1; /* IMASK = 0 ENABLE = 1 */
|
|
asm volatile ("msr cntv_ctl_el0, %0"::"r" (timer_ctl));
|
|
asm volatile ("mrs %0, cntv_ctl_el0":"=r" (timer_ctl));
|
|
kdebug("timer init cntv_ctl_el0 = %lu\n", timer_ctl);
|
|
/* enable interrupt controller */
|
|
return;
|
|
}
|
|
|
|
void plat_handle_timer_irq(void)
|
|
{
|
|
asm volatile ("msr cntv_tval_el0, %0"::"r" (cntv_tval));
|
|
}
|
|
|
|
void plat_disable_timer(void)
|
|
{
|
|
u64 timer_ctl = 0x0;
|
|
|
|
asm volatile ("msr cntv_ctl_el0, %0"::"r" (timer_ctl));
|
|
}
|
|
|
|
void plat_enable_timer(void)
|
|
{
|
|
u64 timer_ctl = 0x1;
|
|
|
|
asm volatile ("msr cntv_tval_el0, %0"::"r" (cntv_tval));
|
|
asm volatile ("msr cntv_ctl_el0, %0"::"r" (timer_ctl));
|
|
}
|
|
|
|
void handle_timer_irq(void)
|
|
{
|
|
plat_handle_timer_irq();
|
|
sched_handle_timer_irq();
|
|
}
|