diff --git a/components/drivers/Kconfig b/components/drivers/Kconfig index 31a109cd4f024b662174e99934d088352c1a5fb9..66815f9b989c0388aad3a8614f9cb34a6b2d691d 100644 --- a/components/drivers/Kconfig +++ b/components/drivers/Kconfig @@ -95,6 +95,12 @@ if RT_USING_CPUTIME help Some Cortex-M3/4/7 MCU has Data Watchpoint and Trace Register, use the cycle counter in DWT for CPU time. + config RT_USING_CPUTIME_RISCV + bool "Use rdtime instructions for CPU time" + default y + depends on ARCH_RISCV64 + help + Some RISCV64 MCU Use rdtime instructions read CPU time. endif config RT_USING_I2C diff --git a/components/drivers/cputime/SConscript b/components/drivers/cputime/SConscript index 57c0b44fa831b7f33cf340db98a7ac8bbb1c0364..e1b447e16b70d271a65a445e4c1e373797626d64 100644 --- a/components/drivers/cputime/SConscript +++ b/components/drivers/cputime/SConscript @@ -9,6 +9,9 @@ cputime.c if GetDepend('RT_USING_CPUTIME_CORTEXM'): src += ['cputime_cortexm.c'] +if GetDepend('RT_USING_CPUTIME_RISCV'): + src += ['cputime_riscv.c'] + group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_CPUTIME'], CPPPATH = CPPPATH) Return('group') diff --git a/components/drivers/cputime/cputime.c b/components/drivers/cputime/cputime.c index 3ec860d5c5e73ac79c9e5a5ced13aab094929e8f..500497385f12a1baf22f63350249264669b2ad2f 100644 --- a/components/drivers/cputime/cputime.c +++ b/components/drivers/cputime/cputime.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -33,7 +33,7 @@ float clock_cpu_getres(void) * * @return the cpu tick */ -uint32_t clock_cpu_gettime(void) +uint64_t clock_cpu_gettime(void) { if (_cputime_ops) return _cputime_ops->cputime_gettime(); @@ -50,11 +50,11 @@ uint32_t clock_cpu_gettime(void) * * @return the microsecond */ -uint32_t clock_cpu_microsecond(uint32_t cpu_tick) +uint64_t clock_cpu_microsecond(uint64_t cpu_tick) { float unit = clock_cpu_getres(); - return (uint32_t)((cpu_tick * unit) / 1000); + return (uint64_t)((cpu_tick * unit) / 1000); } /** @@ -65,11 +65,11 @@ uint32_t clock_cpu_microsecond(uint32_t cpu_tick) * * @return the millisecond */ -uint32_t clock_cpu_millisecond(uint32_t cpu_tick) +uint64_t clock_cpu_millisecond(uint64_t cpu_tick) { float unit = clock_cpu_getres(); - return (uint32_t)((cpu_tick * unit) / (1000 * 1000)); + return (uint64_t)((cpu_tick * unit) / (1000 * 1000)); } /** diff --git a/components/drivers/cputime/cputime_cortexm.c b/components/drivers/cputime/cputime_cortexm.c index 05ed6ed447c1fe5414c92cbbd40923217c098fbc..a23076bfcd0aceff94bbc43b655e6deec498e727 100644 --- a/components/drivers/cputime/cputime_cortexm.c +++ b/components/drivers/cputime/cputime_cortexm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -24,7 +24,7 @@ static float cortexm_cputime_getres(void) return ret; } -static uint32_t cortexm_cputime_gettime(void) +static uint64_t cortexm_cputime_gettime(void) { return DWT->CYCCNT; } diff --git a/components/drivers/cputime/cputime_riscv.c b/components/drivers/cputime/cputime_riscv.c new file mode 100644 index 0000000000000000000000000000000000000000..7e327fc2d42516233f2455a75b497715fc816de5 --- /dev/null +++ b/components/drivers/cputime/cputime_riscv.c @@ -0,0 +1,39 @@ +#include +#include +#include + +#include + + +#define TIMER_FREQ (24000000) + +/* Use Cycle counter of Data Watchpoint and Trace Register for CPU time */ + +static float riscv_cputime_getres(void) +{ + float ret = 1000 * 1000 * 1000; + + ret = ret / TIMER_FREQ; + return ret; +} + +static uint64_t riscv_cputime_gettime(void) +{ + uint64_t time_elapsed; + __asm__ __volatile__( + "rdtime %0" + : "=r"(time_elapsed)); + return time_elapsed; +} + +const static struct rt_clock_cputime_ops _riscv_ops = + { + riscv_cputime_getres, + riscv_cputime_gettime}; + +int riscv_cputime_init(void) +{ + clock_cpu_setops(&_riscv_ops); + return 0; +} +INIT_BOARD_EXPORT(riscv_cputime_init); diff --git a/components/drivers/include/drivers/cputime.h b/components/drivers/include/drivers/cputime.h index 78c22fc1daf3c024a8f5b59cfc80ad435727d253..583c147866ad2bcca40ae7c7aafb7c681adf5cb8 100644 --- a/components/drivers/include/drivers/cputime.h +++ b/components/drivers/include/drivers/cputime.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -14,14 +14,14 @@ struct rt_clock_cputime_ops { float (*cputime_getres) (void); - uint32_t (*cputime_gettime)(void); + uint64_t (*cputime_gettime)(void); }; float clock_cpu_getres(void); -uint32_t clock_cpu_gettime(void); +uint64_t clock_cpu_gettime(void); -uint32_t clock_cpu_microsecond(uint32_t cpu_tick); -uint32_t clock_cpu_millisecond(uint32_t cpu_tick); +uint64_t clock_cpu_microsecond(uint64_t cpu_tick); +uint64_t clock_cpu_millisecond(uint64_t cpu_tick); int clock_cpu_setops(const struct rt_clock_cputime_ops *ops); diff --git a/components/libc/time/clock_time.c b/components/libc/time/clock_time.c index 6cfb8a2eb993fc0ca163f4d59b53bfbf7c2700b8..2c37272d89e51ac837f8ed218513c62a0772f3f1 100644 --- a/components/libc/time/clock_time.c +++ b/components/libc/time/clock_time.c @@ -10,6 +10,7 @@ */ #include +#include #include "clock_time.h" static struct timeval _timevalue; @@ -88,6 +89,7 @@ int clock_getres(clockid_t clockid, struct timespec *res) break; #ifdef RT_USING_CPUTIME + case CLOCK_MONOTONIC: case CLOCK_CPUTIME_ID: res->tv_sec = 0; res->tv_nsec = clock_cpu_getres(); @@ -127,6 +129,7 @@ int clock_gettime(clockid_t clockid, struct timespec *tp) break; #ifdef RT_USING_CPUTIME + case CLOCK_MONOTONIC: case CLOCK_CPUTIME_ID: { float unit = 0; diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c index 09c6556a234b79def62522ec008fd7a2edd18ff0..3c88c78a7e6611c81a70c5d49d4a8cca16f04556 100644 --- a/components/lwp/lwp_syscall.c +++ b/components/lwp/lwp_syscall.c @@ -3748,15 +3748,7 @@ int sys_pipe(int fd[2]) int sys_clock_settime(clockid_t clk, const struct timespec *ts) { - rt_device_t device; - time_t now; - - device = rt_device_find("rtc"); - if (device == RT_NULL) - { - return -ENODEV; - } - + int ret = 0; #ifdef RT_USING_USERSPACE size_t size = sizeof(struct timespec); struct timespec *kts = NULL; @@ -3773,32 +3765,21 @@ int sys_clock_settime(clockid_t clk, const struct timespec *ts) } lwp_get_from_user(kts, (void *)ts, size); - now = kts->tv_sec; - + ret = clock_settime(clk, kts); kmem_put(kts); #else if (!lwp_user_accessable((void *)ts, sizeof(struct timespec))) { return -EFAULT; } - now = ts->tv_sec; + ret = clock_settime(clk, ts); #endif - return rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &now); + return (ret < 0 ? GET_ERRNO() : ret); } int sys_clock_gettime(clockid_t clk, struct timespec *ts) { int ret = 0; - rt_device_t device; - time_t now; - - device = rt_device_find("rtc"); - if (device == RT_NULL) - { - return -ENODEV; - } - ret = rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &now); - #ifdef RT_USING_USERSPACE size_t size = sizeof(struct timespec); struct timespec *kts = NULL; @@ -3814,9 +3795,9 @@ int sys_clock_gettime(clockid_t clk, struct timespec *ts) return -ENOMEM; } - kts->tv_sec = now; - kts->tv_nsec = 0; - lwp_put_to_user(ts, kts, size); + ret = clock_gettime(clk, kts); + if (ret != -1) + lwp_put_to_user(ts, kts, size); kmem_put(kts); #else @@ -3824,14 +3805,14 @@ int sys_clock_gettime(clockid_t clk, struct timespec *ts) { return -EFAULT; } - ts->tv_sec = now; - ts->tv_nsec = 0; + ret = clock_gettime(clk, ts); #endif return (ret < 0 ? GET_ERRNO() : ret); } int sys_clock_getres(clockid_t clk, struct timespec *ts) { + int ret = 0; #ifdef RT_USING_USERSPACE struct timespec kts; size_t size = sizeof(struct timespec); @@ -3841,18 +3822,18 @@ int sys_clock_getres(clockid_t clk, struct timespec *ts) return -EFAULT; } - kts.tv_sec = 1; - kts.tv_nsec = 0; - lwp_put_to_user(ts, &kts, size); + ret = clock_getres(clk, &kts); + + if (ret != -1) + lwp_put_to_user(ts, &kts, size); #else if (!lwp_user_accessable((void *)ts, sizeof(struct timespec))) { return -EFAULT; } - ts->tv_sec = 1; - ts->tv_nsec = 0; + ret = clock_getres(clk, ts); #endif - return 0; + return (ret < 0 ? GET_ERRNO() : ret); } int sys_rename(const char *oldpath, const char *newpath)