1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #include <rtthread.h>
- #include "interrupt.h"
- #ifndef RT_CPUS_NR
- #define RT_CPUS_NR 1
- #endif
- #define GTIMER_IRQ (27)
- static uint64_t _tickval[RT_CPUS_NR];
- static uint64_t _increaseval[RT_CPUS_NR];
- #define tickval _tickval[cpu_id]
- #define increaseval _increaseval[cpu_id]
- /**
- * This function is the gtimer isr handler.
- *
- * @param vector interrupt ID
- * @param parameter the parameter specified by rt_hw_interrupt_install
- *
- * @return none
- */
- static void _hw_timer_isr(int vector, void *parameter)
- {
- #ifdef RT_USING_SMP
- int cpu_id = rt_hw_cpu_id();
- #else
- int cpu_id = 0;
- #endif
- uint64_t cntvct_el0;
- do
- {
- tickval += increaseval;
- __asm__ volatile("msr CNTV_CVAL_EL0, %0"::"r"(tickval));
- __asm__ volatile("mrs %0, CNTVCT_EL0":"=r"(cntvct_el0));
- } while (cntvct_el0 >= tickval);
- rt_tick_increase();
- }
- /**
- * The function will initialize the general timer used for the system tick.
- *
- * @param none
- *
- * @return none
- */
- rt_weak int rt_hw_gtimer_init(void)
- {
- #ifdef RT_USING_SMP
- int cpu_id = rt_hw_cpu_id();
- #else
- int cpu_id = 0;
- #endif
- uint64_t val;
- rt_hw_interrupt_install(GTIMER_IRQ, _hw_timer_isr, RT_NULL, "tick");
- rt_hw_interrupt_umask(GTIMER_IRQ);
- __asm__ volatile("mrs %0, CNTFRQ_EL0":"=r"(val));
- increaseval = val / RT_TICK_PER_SECOND;
- __asm__ volatile("msr CNTV_CTL_EL0, %0"::"r"(val));
- tickval = increaseval;
- __asm__ volatile("msr CNTV_CVAL_EL0, %0"::"r"(tickval));
- val = 1;
- __asm__ volatile("msr CNTV_CTL_EL0, %0"::"r"(val));
- return 0;
- }
- INIT_BOARD_EXPORT(rt_hw_gtimer_init);
|