From 0265a1ff5bd7c4f129351521fc23167cb4fcab7c Mon Sep 17 00:00:00 2001 From: kuangyufei Date: Mon, 11 Jan 2021 15:15:47 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E7=A1=AC=E6=97=B6?= =?UTF-8?q?=E9=92=9F.=20=20=20=20=20=E6=90=9C=E7=B4=A2=20@note=5Fpic=20?= =?UTF-8?q?=E5=8F=AF=E6=9F=A5=E7=9C=8B=E7=BB=98=E5=88=B6=E7=9A=84=E5=85=A8?= =?UTF-8?q?=E9=83=A8=E5=AD=97=E7=AC=A6=E5=9B=BE=20=20=20=20=20=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=20@note=5Fwhy=20=E6=98=AF=E5=B0=9A=E6=9C=AA=E7=9C=8B?= =?UTF-8?q?=E6=98=8E=E7=99=BD=E7=9A=84=E5=9C=B0=E6=96=B9=EF=BC=8C=E6=9C=89?= =?UTF-8?q?=E7=9C=8B=E6=98=8E=E7=99=BD=E7=9A=84=EF=BC=8C=E8=AF=B7Pull=20Re?= =?UTF-8?q?quest=E5=AE=8C=E5=96=84=20=20=20=20=20=E6=90=9C=E7=B4=A2=20@not?= =?UTF-8?q?e=5Fthinking=20=E6=98=AF=E4=B8=80=E4=BA=9B=E7=9A=84=E6=80=9D?= =?UTF-8?q?=E8=80=83=E5=92=8C=E5=BB=BA=E8=AE=AE=20=20=20=20=20=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=20@note=5F#if0=20=E6=98=AF=E7=94=B1=E7=AC=AC=E4=B8=89?= =?UTF-8?q?=E6=96=B9=E9=A1=B9=E7=9B=AE=E6=8F=90=E4=BE=9B=E4=B8=8D=E5=9C=A8?= =?UTF-8?q?=E5=86=85=E6=A0=B8=E6=BA=90=E7=A0=81=E4=B8=AD=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E7=9A=84=E6=9E=81=E4=B8=BA=E9=87=8D=E8=A6=81=E7=BB=93=E6=9E=84?= =?UTF-8?q?=E4=BD=93=EF=BC=8C=E4=B8=BA=E6=96=B9=E4=BE=BF=E7=90=86=E8=A7=A3?= =?UTF-8?q?=E8=80=8C=E6=B7=BB=E5=8A=A0=E7=9A=84=E3=80=82=20=20=20=20=20?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=20@note=5Fgood=20=E6=98=AF=E7=BB=99=E6=BA=90?= =?UTF-8?q?=E7=A0=81=E7=82=B9=E8=B5=9E=E7=9A=84=E5=9C=B0=E6=96=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 +- kernel/base/core/los_process.c | 46 +- kernel/base/core/los_tick.c | 6 +- kernel/base/include/los_process_pri.h | 6 +- .../arm/timer/arm_generic/arm_generic_timer.c | 398 ++++----- .../arm/timer/arm_private/arm_private_timer.c | 16 +- platform/hw/hisoc/timer/timer.c | 816 +++++++++--------- zzz/git/push.sh | 2 +- 8 files changed, 650 insertions(+), 654 deletions(-) diff --git a/README.md b/README.md index 5ace6c3b..bb57b516 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![star](https://gitee.com/weharmony/kernel_liteos_a_note/badge/star.svg?theme=dark)](https://gitee.com/weharmony/kernel_liteos_a_note)[![fork](https://gitee.com/weharmony/kernel_liteos_a_note/badge/fork.svg?theme=dark)](https://gitee.com/weharmony/kernel_liteos_a_note) -每个码农,学职生涯,都应精读一遍内核源码.精读内核源码最大的好处是:将孤立知识点织成一张高浓度,高密度底层网,是对计算机底层体系化理解形成永久记忆 +每个码农,学职生涯,都应精读一遍内核源码.是浇筑计算机知识大厦的地基工程,地基纵深坚固程度,决定了大厦能盖多高。为何一定要精读?因为内核代码本身并不太多,都是浓缩的精华,精读就是让各个知识点高频出现,闪爆大脑,短时间内容易结成一张高浓度,高密度的底层网,形成永久大脑记忆。跟骑单车一样,一旦学会,即便多年不骑,照样跨上就走,游刃有余。 ## **做了些什么呢?** @@ -61,17 +61,15 @@ 第二: **专业概念抽象级** 对抽象的专业逻辑概念具体化认知, 比如虚拟内存,老百姓是听不懂的,学过计算机的人都懂,具体怎么实现的很多人又都不懂了,但这并不妨碍成为一个优秀的上层应用程序员,因为虚拟内存已经被抽象出来,目的是要屏蔽上层对它的现实认知.试图用 **[鸿蒙源码分析系列篇 【 CSDN](https://blog.csdn.net/kuangyufei/article/details/108727970) [| OSCHINA](https://my.oschina.net/u/3751245/blog/4626852) [| WIKI 】](https://gitee.com/weharmony/kernel_liteos_a_note/wikis/pages)** 去拆解那些已经被抽象出来的专业概念, 希望能卷入更多对内核感兴趣的应用软件人才流入基础软件生态, 应用软件咱们是无敌宇宙,但基础软件却很薄弱. 第三: **具体微观代码级** 这一级是具体到每一行代码的实现,到了用代码指令级的地步,这段代码是什么意思?为什么要这么设计? **[kernel\_liteos\_a_note:鸿蒙内核源码注释中文版](https://gitee.com/weharmony/kernel_liteos_a_note)** 试图从细微处去解释代码实现层,英文真的是天生适合设计成编程语言的人类语言,计算机的01码映射到人类世界的26个字母,诞生了太多的伟大奇迹.但我们的母语注定了很大部分人存在着自然语言层级的理解映射,希望注释中文版能让更多爱好者快速的理解内核,共同进步. - -- ### **鸿蒙内核500问,你知道多少?** - - 抛出的500个内核知识问题,可前往 **[鸿蒙内核源码分析(源码结构篇) | 内核500问 【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/111938348) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4869137)** 查看. - ### **系列博客更新到哪里了?** - 把研究过程心得写成鸿蒙源码分析系列篇,如此源码中文注释+系列篇文章,将加速理解鸿蒙内核实现过程,因时间有限,博文更新较慢,会反复修正. + 把研究过程心得写成鸿蒙源码分析系列篇,如此源码中文注释+系列篇文章,将加速理解鸿蒙内核实现过程. - **[鸿蒙源码分析系列(总目录) | 持续更新中... 【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/108727970) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4626852)** + * **[|- 鸿蒙内核源码分析(位图管理篇) | 为何进程和线程都是32个优先级? 【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/112394982) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4888467)** + * **[|- 鸿蒙内核源码分析(源码结构篇) | 内核500问你能答对多少? 【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/111938348) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4869137)** * **[|- 鸿蒙内核源码分析(物理内存篇) | 伙伴算法是在卖标准猪肉块吗?【 CSDN ](https://blog.csdn.net/kuangyufei/article/details/111765600) [| OSCHINA 】](https://my.oschina.net/u/3751245/blog/4842408)** @@ -117,12 +115,10 @@ 2. [新建 Issue](https://gitee.com/weharmony/kernel_liteos_a_note/issues) -- ### **鸿蒙内核源码分析 官方公众号** +- ### **喜欢关注官方公众号** ![在这里插入图片描述](./zzz/pic/other/wxcode.png) - 感谢关注,您的支持是注者最大的动力. - 作者邮箱:weharmony@126.com --- diff --git a/kernel/base/core/los_process.c b/kernel/base/core/los_process.c index 3ca76f13..2f6d39ad 100644 --- a/kernel/base/core/los_process.c +++ b/kernel/base/core/los_process.c @@ -125,7 +125,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsTaskSchedQueueEnqueue(LosTaskCB *taskCB, UINT16 sta LOS_ASSERT(!(taskCB->taskStatus & OS_TASK_STATUS_READY));// 只有非就绪状态任务才能入队 processCB = OS_PCB_FROM_PID(taskCB->processID);// 通过一个任务得到这个任务所在的进程 - if (!(processCB->processStatus & OS_PROCESS_STATUS_READY)) {//task状态为就绪状态 + if (!(processCB->processStatus & OS_PROCESS_STATUS_READY)) {//task状态没有就绪状态标签 if (((processCB->policy == LOS_SCHED_RR) && (processCB->timeSlice != 0)) ||//调度方式为抢断且时间片没用完 ((processCB->processStatus & OS_PROCESS_STATUS_RUNNING) && (processCB->policy == LOS_SCHED_FIFO))) {//或处于运行的FIFO调度方式的task OS_PROCESS_PRI_QUEUE_ENQUEUE_HEAD(processCB);//进程入g_priQueueList就绪队列头部 @@ -139,7 +139,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsTaskSchedQueueEnqueue(LosTaskCB *taskCB, UINT16 sta LOS_ASSERT((UINTPTR)processCB->pendList.pstNext); if ((processCB->timeSlice == 0) && (processCB->policy == LOS_SCHED_RR)) {//没有时间片且采用抢占式调度算法的情况 OS_PROCESS_PRI_QUEUE_DEQUEUE(processCB);//进程先出队列 - OS_PROCESS_PRI_QUEUE_ENQUEUE(processCB);//进程再入队列,区别是排到了最后.这可是队列前面还有很多人等着被调度呢. + OS_PROCESS_PRI_QUEUE_ENQUEUE(processCB);//进程再入队列,区别是排到了最后.队列前面还有很多进程在等着被调度. } } @@ -362,29 +362,29 @@ STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosPro return; } - +//回收指定进程的资源 LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB) { - if (!(processCB->processStatus & (OS_PROCESS_STATUS_INIT | OS_PROCESS_STATUS_RUNNING))) { - PRINT_ERR("The process(%d) has no permission to release process(%d) resources!\n", + if (!(processCB->processStatus & (OS_PROCESS_STATUS_INIT | OS_PROCESS_STATUS_RUNNING))) {//1.初始化阶段并没有使用到资源,所以不用回收 + PRINT_ERR("The process(%d) has no permission to release process(%d) resources!\n",//2.正在运行的进程不能回收 OsCurrProcessGet()->processID, processCB->processID); } #ifdef LOSCFG_FS_VFS - if (OsProcessIsUserMode(processCB)) {//用户模式下 - delete_files(processCB, processCB->files);//删除文件 + if (OsProcessIsUserMode(processCB)) {//用户进程 + delete_files(processCB, processCB->files);//删除与用户进程相关的文件 } processCB->files = NULL; #endif -#ifdef LOSCFG_SECURITY_CAPABILITY +#ifdef LOSCFG_SECURITY_CAPABILITY //安全开关 if (processCB->user != NULL) { - (VOID)LOS_MemFree(m_aucSysMem1, processCB->user); + (VOID)LOS_MemFree(m_aucSysMem1, processCB->user);//删除用户 processCB->user = NULL; } #endif - OsSwtmrRecycle(processCB->processID);//软件定时器回收 + OsSwtmrRecycle(processCB->processID);//回收进程使用的定时器 processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID; #ifdef LOSCFG_SECURITY_VID @@ -395,13 +395,13 @@ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB) #endif #if (LOSCFG_KERNEL_LITEIPC == YES) - if (OsProcessIsUserMode(processCB)) {//用户模式下 - LiteIpcPoolDelete(&(processCB->ipcInfo));//删除进程IPC + if (OsProcessIsUserMode(processCB)) {//用户进程 + LiteIpcPoolDelete(&(processCB->ipcInfo));//删除进程对lite IPC的开销 (VOID)memset_s(&(processCB->ipcInfo), sizeof(ProcIpcInfo), 0, sizeof(ProcIpcInfo)); } #endif } -//回收僵死状态进程流程 +//回收僵死状态进程的资源 LITE_OS_SEC_TEXT STATIC VOID OsRecycleZombiesProcess(LosProcessCB *childCB, ProcessGroup **group) { OsExitProcessGroup(childCB, group);//退出进程组 @@ -420,7 +420,7 @@ LITE_OS_SEC_TEXT STATIC VOID OsRecycleZombiesProcess(LosProcessCB *childCB, Proc OsInsertPCBToFreeList(childCB);//直接插到freeList中去,可用于重新分配了。 } } - +//当一个进程自然退出的时候,它的孩子进程要怎么处理 STATIC VOID OsDealAliveChildProcess(LosProcessCB *processCB) { UINT32 parentID; @@ -429,13 +429,13 @@ STATIC VOID OsDealAliveChildProcess(LosProcessCB *processCB) LOS_DL_LIST *nextList = NULL; LOS_DL_LIST *childHead = NULL; - if (!LOS_ListEmpty(&processCB->childrenList)) { + if (!LOS_ListEmpty(&processCB->childrenList)) {//如果存在孩子进程 childHead = processCB->childrenList.pstNext; LOS_ListDelete(&(processCB->childrenList)); - if (OsProcessIsUserMode(processCB)) { - parentID = g_userInitProcess; + if (OsProcessIsUserMode(processCB)) {//是用户模式吗? + parentID = g_userInitProcess;//指定1号进程父ID } else { - parentID = g_kernelInitProcess; + parentID = g_kernelInitProcess;//指定2号进程为父ID } for (nextList = childHead; ;) { @@ -474,9 +474,9 @@ STATIC VOID OsProcessNaturalExit(LosTaskCB *runTask, UINT32 status) LOS_ASSERT(!(processCB->threadScheduleMap != 0));//断言没有任务需要调度了,当前task是最后一个了 LOS_ASSERT(processCB->processStatus & OS_PROCESS_STATUS_RUNNING);//断言必须为正在运行的进程 - OsChildProcessResourcesFree(processCB);// + OsChildProcessResourcesFree(processCB);//释放孩子进程的资源 -#ifdef LOSCFG_KERNEL_CPUP +#ifdef LOSCFG_KERNEL_CPUP OsCpupClean(processCB->processID); #endif @@ -495,7 +495,7 @@ STATIC VOID OsProcessNaturalExit(LosTaskCB *runTask, UINT32 status) OsDealAliveChildProcess(processCB); - processCB->processStatus |= OS_PROCESS_STATUS_ZOMBIES; + processCB->processStatus |= OS_PROCESS_STATUS_ZOMBIES;//贴上僵死进程的标签 (VOID)OsKill(processCB->parentProcessID, SIGCHLD, OS_KERNEL_KILL_PERMISSION); LOS_ListHeadInsert(&g_processRecyleList, &processCB->pendList); @@ -526,10 +526,10 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsProcessInit(VOID) for (index = 0; index < g_processMaxNum; index++) {//进程池循环创建 g_processCBArray[index].processID = index;//进程ID[0-g_processMaxNum]赋值 - g_processCBArray[index].processStatus = OS_PROCESS_FLAG_UNUSED;// 默认都是白纸一张,臣妾干净着呢 + g_processCBArray[index].processStatus = OS_PROCESS_FLAG_UNUSED;// 默认都是白纸一张,贴上未使用标签 LOS_ListTailInsert(&g_freeProcess, &g_processCBArray[index].pendList);//注意g_freeProcess挂的是pendList节点,所以使用要通过OS_PCB_FROM_PENDLIST找到进程实体. } - // ????? 为啥用户模式的根进程 选1 ,内核模式的根进程选2 + g_userInitProcess = 1; /* 1: The root process ID of the user-mode process is fixed at 1 *///用户模式的根进程 LOS_ListDelete(&g_processCBArray[g_userInitProcess].pendList);// 清空g_userInitProcess pend链表 diff --git a/kernel/base/core/los_tick.c b/kernel/base/core/los_tick.c index 84f57da1..29bab680 100644 --- a/kernel/base/core/los_tick.c +++ b/kernel/base/core/los_tick.c @@ -47,16 +47,16 @@ extern "C" { #endif /* __cplusplus */ LITE_OS_SEC_BSS volatile UINT64 g_tickCount[LOSCFG_KERNEL_CORE_NUM] = {0};//tick计数器,系统一旦启动,一直在++, 为防止溢出,这是一个 UINT64 的变量 -LITE_OS_SEC_DATA_INIT UINT32 g_sysClock;//系统时钟 +LITE_OS_SEC_DATA_INIT UINT32 g_sysClock;//系统时钟,是绝大部分部件工作的时钟源,也是其他所有外设的时钟的来源 LITE_OS_SEC_DATA_INIT UINT32 g_tickPerSecond;//每秒Tick数,鸿蒙默认是每秒100次,即:10ms -LITE_OS_SEC_BSS DOUBLE g_cycle2NsScale; +LITE_OS_SEC_BSS DOUBLE g_cycle2NsScale; //周期转纳秒级 /* spinlock for task module */ LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_tickSpin); //节拍器自旋锁 /* * Description : Tick interruption handler - *///系统时钟中断处理函数 ,鸿蒙是 10ms触发一次 + *///节拍中断处理函数 ,鸿蒙默认10ms触发一次 LITE_OS_SEC_TEXT VOID OsTickHandler(VOID) { UINT32 intSave; diff --git a/kernel/base/include/los_process_pri.h b/kernel/base/include/los_process_pri.h index 9db4998f..768bac61 100644 --- a/kernel/base/include/los_process_pri.h +++ b/kernel/base/include/los_process_pri.h @@ -314,9 +314,9 @@ STATIC INLINE BOOL OsProcessIsDead(const LosProcessCB *processCB)//查下进程 #define OS_USER_TASK_SYSCALL_SATCK_SIZE 0x3000 //用户通过系统调用的栈大小 12K ,这时是运行在内核模式下 #define OS_USER_TASK_STACK_SIZE 0x100000 //用户任务运行在用户空间的栈大小 1M -#define OS_KERNEL_MODE 0x0U //内核态模式 -#define OS_USER_MODE 0x1U //用户态模式 -STATIC INLINE BOOL OsProcessIsUserMode(const LosProcessCB *processCB)//进程处于用户态? +#define OS_KERNEL_MODE 0x0U //内核模式 +#define OS_USER_MODE 0x1U //用户模式 +STATIC INLINE BOOL OsProcessIsUserMode(const LosProcessCB *processCB)//用户模式进程 { return (processCB->processMode == OS_USER_MODE); } diff --git a/platform/hw/arm/timer/arm_generic/arm_generic_timer.c b/platform/hw/arm/timer/arm_generic/arm_generic_timer.c index 53e7847a..89d5c332 100644 --- a/platform/hw/arm/timer/arm_generic/arm_generic_timer.c +++ b/platform/hw/arm/timer/arm_generic/arm_generic_timer.c @@ -1,199 +1,199 @@ -/* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "los_hw_pri.h" -#include "los_tick_pri.h" -#include "los_sys_pri.h" -#include "gic_common.h" - -#define STRING_COMB(x, y, z) x ## y ## z - -#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE -#define TIMER_REG(reg) STRING_COMB(TIMER_REG_, CNTPS, reg) -#else -#define TIMER_REG(reg) STRING_COMB(TIMER_REG_, CNTP, reg) -#endif -#define TIMER_REG_CTL TIMER_REG(_CTL) /* 32 bits */ -#define TIMER_REG_TVAL TIMER_REG(_TVAL) /* 32 bits */ -#define TIMER_REG_CVAL TIMER_REG(_CVAL) /* 64 bits */ -#define TIMER_REG_CT TIMER_REG(CT) /* 64 bits */ - -#ifdef __LP64__ - -#define TIMER_REG_CNTFRQ cntfrq_el0 - -/* CNTP AArch64 registers */ -#define TIMER_REG_CNTP_CTL cntp_ctl_el0 -#define TIMER_REG_CNTP_TVAL cntp_tval_el0 -#define TIMER_REG_CNTP_CVAL cntp_cval_el0 -#define TIMER_REG_CNTPCT cntpct_el0 - -/* CNTPS AArch64 registers */ -#define TIMER_REG_CNTPS_CTL cntps_ctl_el1 -#define TIMER_REG_CNTPS_TVAL cntps_tval_el1 -#define TIMER_REG_CNTPS_CVAL cntps_cval_el1 -#define TIMER_REG_CNTPSCT cntpct_el0 - -#define READ_TIMER_REG32(reg) AARCH64_SYSREG_READ(reg) -#define READ_TIMER_REG64(reg) AARCH64_SYSREG_READ(reg) -#define WRITE_TIMER_REG32(reg, val) AARCH64_SYSREG_WRITE(reg, (UINT64)(val)) -#define WRITE_TIMER_REG64(reg, val) AARCH64_SYSREG_WRITE(reg, val) - -#else /* Aarch32 */ - -#define TIMER_REG_CNTFRQ CP15_REG(c14, 0, c0, 0) - -/* CNTP AArch32 registers */ -#define TIMER_REG_CNTP_CTL CP15_REG(c14, 0, c2, 1) -#define TIMER_REG_CNTP_TVAL CP15_REG(c14, 0, c2, 0) -#define TIMER_REG_CNTP_CVAL CP15_REG64(c14, 2) -#define TIMER_REG_CNTPCT CP15_REG64(c14, 0) - -/* CNTPS AArch32 registers are banked and accessed though CNTP */ -#define CNTPS CNTP - -#define READ_TIMER_REG32(reg) ARM_SYSREG_READ(reg) -#define READ_TIMER_REG64(reg) ARM_SYSREG64_READ(reg) -#define WRITE_TIMER_REG32(reg, val) ARM_SYSREG_WRITE(reg, val) -#define WRITE_TIMER_REG64(reg, val) ARM_SYSREG64_WRITE(reg, val) - -#endif - -#define OS_CYCLE_PER_TICK (g_sysClock / LOSCFG_BASE_CORE_TICK_PER_SECOND) //每个tick多少周期 - -UINT32 HalClockFreqRead(VOID) -{ - return READ_TIMER_REG32(TIMER_REG_CNTFRQ); -} - -VOID HalClockFreqWrite(UINT32 freq) -{ - WRITE_TIMER_REG32(TIMER_REG_CNTFRQ, freq); -} - -STATIC_INLINE VOID TimerCtlWrite(UINT32 cntpCtl) -{ - WRITE_TIMER_REG32(TIMER_REG_CTL, cntpCtl); -} - -STATIC_INLINE UINT64 TimerCvalRead(VOID) -{ - return READ_TIMER_REG64(TIMER_REG_CVAL); -} - -STATIC_INLINE VOID TimerCvalWrite(UINT64 cval) -{ - WRITE_TIMER_REG64(TIMER_REG_CVAL, cval); -} - -STATIC_INLINE VOID TimerTvalWrite(UINT32 tval) -{ - WRITE_TIMER_REG32(TIMER_REG_TVAL, tval); -} - -UINT64 HalClockGetCycles(VOID) -{ - UINT64 cntpct; - - cntpct = READ_TIMER_REG64(TIMER_REG_CT); - return cntpct; -} -//节拍回调函数 -LITE_OS_SEC_TEXT VOID OsTickEntry(VOID) -{ - TimerCtlWrite(0); - - OsTickHandler();//节拍处理主体函数 - - /* //使用最近的 cval生成下一个tick的计时是绝对和准确的。 - * use last cval to generate the next tick's timing is - * absolute and accurate. DO NOT use tval to drive the - * generic time in which case tick will be slower. - *///不要使用tval来产生时间,在这种情况下,滴答声会变慢 - TimerCvalWrite(TimerCvalRead() + OS_CYCLE_PER_TICK); - TimerCtlWrite(1); -} - -LITE_OS_SEC_TEXT_INIT VOID HalClockInit(VOID) -{ - UINT32 ret; - - g_sysClock = HalClockFreqRead();//读时间 - ret = LOS_HwiCreate(OS_TICK_INT_NUM, MIN_INTERRUPT_PRIORITY, 0, OsTickEntry, 0); - if (ret != LOS_OK) { - PRINT_ERR("%s, %d create tick irq failed, ret:0x%x\n", __FUNCTION__, __LINE__, ret); - } -} - -LITE_OS_SEC_TEXT_INIT VOID HalClockStart(VOID) -{ - HalIrqUnmask(OS_TICK_INT_NUM); - - /* triggle the first tick */ - TimerCtlWrite(0); - TimerTvalWrite(OS_CYCLE_PER_TICK); - TimerCtlWrite(1); -} - -VOID HalDelayUs(UINT32 usecs) -{ - UINT64 cycles = (UINT64)usecs * HalClockFreqRead() / OS_SYS_US_PER_SECOND; - UINT64 deadline = HalClockGetCycles() + cycles; - - while (HalClockGetCycles() < deadline) { - __asm__ volatile ("nop"); - } -} - -UINT64 hi_sched_clock(VOID) -{ - return LOS_CurrNanosec(); -} - -UINT32 HalClockGetTickTimerCycles(VOID) -{ - UINT64 cval = TimerCvalRead(); - UINT64 cycles = HalClockGetCycles(); - - return (UINT32)((cval > cycles) ? (cval - cycles) : 0); -} - -VOID HalClockTickTimerReload(UINT32 cycles) -{ - HalIrqMask(OS_TICK_INT_NUM); - HalIrqClear(OS_TICK_INT_NUM); - - TimerCtlWrite(0); - TimerCvalWrite(HalClockGetCycles() + cycles); - TimerCtlWrite(1); - - HalIrqUnmask(OS_TICK_INT_NUM); -} +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_hw_pri.h" +#include "los_tick_pri.h" +#include "los_sys_pri.h" +#include "gic_common.h" + +#define STRING_COMB(x, y, z) x ## y ## z + +#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE +#define TIMER_REG(reg) STRING_COMB(TIMER_REG_, CNTPS, reg) +#else +#define TIMER_REG(reg) STRING_COMB(TIMER_REG_, CNTP, reg) +#endif +#define TIMER_REG_CTL TIMER_REG(_CTL) /* 32 bits */ +#define TIMER_REG_TVAL TIMER_REG(_TVAL) /* 32 bits */ +#define TIMER_REG_CVAL TIMER_REG(_CVAL) /* 64 bits */ +#define TIMER_REG_CT TIMER_REG(CT) /* 64 bits */ + +#ifdef __LP64__ + +#define TIMER_REG_CNTFRQ cntfrq_el0 + +/* CNTP AArch64 registers */ +#define TIMER_REG_CNTP_CTL cntp_ctl_el0 +#define TIMER_REG_CNTP_TVAL cntp_tval_el0 +#define TIMER_REG_CNTP_CVAL cntp_cval_el0 +#define TIMER_REG_CNTPCT cntpct_el0 + +/* CNTPS AArch64 registers */ +#define TIMER_REG_CNTPS_CTL cntps_ctl_el1 +#define TIMER_REG_CNTPS_TVAL cntps_tval_el1 +#define TIMER_REG_CNTPS_CVAL cntps_cval_el1 +#define TIMER_REG_CNTPSCT cntpct_el0 + +#define READ_TIMER_REG32(reg) AARCH64_SYSREG_READ(reg) +#define READ_TIMER_REG64(reg) AARCH64_SYSREG_READ(reg) +#define WRITE_TIMER_REG32(reg, val) AARCH64_SYSREG_WRITE(reg, (UINT64)(val)) +#define WRITE_TIMER_REG64(reg, val) AARCH64_SYSREG_WRITE(reg, val) + +#else /* Aarch32 */ + +#define TIMER_REG_CNTFRQ CP15_REG(c14, 0, c0, 0) + +/* CNTP AArch32 registers */ +#define TIMER_REG_CNTP_CTL CP15_REG(c14, 0, c2, 1) +#define TIMER_REG_CNTP_TVAL CP15_REG(c14, 0, c2, 0) +#define TIMER_REG_CNTP_CVAL CP15_REG64(c14, 2) +#define TIMER_REG_CNTPCT CP15_REG64(c14, 0) + +/* CNTPS AArch32 registers are banked and accessed though CNTP */ +#define CNTPS CNTP + +#define READ_TIMER_REG32(reg) ARM_SYSREG_READ(reg) +#define READ_TIMER_REG64(reg) ARM_SYSREG64_READ(reg) +#define WRITE_TIMER_REG32(reg, val) ARM_SYSREG_WRITE(reg, val) +#define WRITE_TIMER_REG64(reg, val) ARM_SYSREG64_WRITE(reg, val) + +#endif + +#define OS_CYCLE_PER_TICK (g_sysClock / LOSCFG_BASE_CORE_TICK_PER_SECOND) //每个tick多少周期 + +UINT32 HalClockFreqRead(VOID) +{ + return READ_TIMER_REG32(TIMER_REG_CNTFRQ); +} + +VOID HalClockFreqWrite(UINT32 freq) +{ + WRITE_TIMER_REG32(TIMER_REG_CNTFRQ, freq); +} +//写时间控制寄存器 +STATIC_INLINE VOID TimerCtlWrite(UINT32 cntpCtl) +{ + WRITE_TIMER_REG32(TIMER_REG_CTL, cntpCtl); +} + +STATIC_INLINE UINT64 TimerCvalRead(VOID) +{ + return READ_TIMER_REG64(TIMER_REG_CVAL); +} + +STATIC_INLINE VOID TimerCvalWrite(UINT64 cval) +{ + WRITE_TIMER_REG64(TIMER_REG_CVAL, cval); +} + +STATIC_INLINE VOID TimerTvalWrite(UINT32 tval) +{ + WRITE_TIMER_REG32(TIMER_REG_TVAL, tval); +} + +UINT64 HalClockGetCycles(VOID) +{ + UINT64 cntpct; + + cntpct = READ_TIMER_REG64(TIMER_REG_CT); + return cntpct; +} +//节拍回调函数 +LITE_OS_SEC_TEXT VOID OsTickEntry(VOID) +{ + TimerCtlWrite(0); + + OsTickHandler();//节拍处理主体函数 + + /* //使用最近的 cval生成下一个tick的计时是绝对和准确的。 + * use last cval to generate the next tick's timing is + * absolute and accurate. DO NOT use tval to drive the + * generic time in which case tick will be slower. + *///不要使用tval来产生时间,在这种情况下,滴答声会变慢 + TimerCvalWrite(TimerCvalRead() + OS_CYCLE_PER_TICK); + TimerCtlWrite(1); +} + +LITE_OS_SEC_TEXT_INIT VOID HalClockInit(VOID) +{ + UINT32 ret; + + g_sysClock = HalClockFreqRead();//读硬时钟频率 + ret = LOS_HwiCreate(OS_TICK_INT_NUM, MIN_INTERRUPT_PRIORITY, 0, OsTickEntry, 0);//创建硬时钟中断 + if (ret != LOS_OK) {//29号中断,暂时使用安全物理计时器 + PRINT_ERR("%s, %d create tick irq failed, ret:0x%x\n", __FUNCTION__, __LINE__, ret); + } +} + +LITE_OS_SEC_TEXT_INIT VOID HalClockStart(VOID) +{ + HalIrqUnmask(OS_TICK_INT_NUM);//取消屏蔽29号中断 + + /* triggle the first tick */ + TimerCtlWrite(0);// + TimerTvalWrite(OS_CYCLE_PER_TICK);//设置节拍周期 + TimerCtlWrite(1); +} + +VOID HalDelayUs(UINT32 usecs) +{ + UINT64 cycles = (UINT64)usecs * HalClockFreqRead() / OS_SYS_US_PER_SECOND; + UINT64 deadline = HalClockGetCycles() + cycles; + + while (HalClockGetCycles() < deadline) { + __asm__ volatile ("nop"); + } +} + +UINT64 hi_sched_clock(VOID) +{ + return LOS_CurrNanosec(); +} + +UINT32 HalClockGetTickTimerCycles(VOID) +{ + UINT64 cval = TimerCvalRead(); + UINT64 cycles = HalClockGetCycles(); + + return (UINT32)((cval > cycles) ? (cval - cycles) : 0); +} + +VOID HalClockTickTimerReload(UINT32 cycles) +{ + HalIrqMask(OS_TICK_INT_NUM);//先屏蔽时钟中断 + HalIrqClear(OS_TICK_INT_NUM);//清除中断位 + + TimerCtlWrite(0); + TimerCvalWrite(HalClockGetCycles() + cycles); + TimerCtlWrite(1); + + HalIrqUnmask(OS_TICK_INT_NUM);//取消屏蔽时钟中断 +} diff --git a/platform/hw/arm/timer/arm_private/arm_private_timer.c b/platform/hw/arm/timer/arm_private/arm_private_timer.c index 47d4cf60..aa5efcef 100644 --- a/platform/hw/arm/timer/arm_private/arm_private_timer.c +++ b/platform/hw/arm/timer/arm_private/arm_private_timer.c @@ -33,19 +33,19 @@ #include "los_hwi.h" #include "los_tick_pri.h" -#define OS_CYCLE_PER_TICK (TIMER_FREQ / LOSCFG_BASE_CORE_TICK_PER_SECOND) +#define OS_CYCLE_PER_TICK (TIMER_FREQ / LOSCFG_BASE_CORE_TICK_PER_SECOND) typedef struct { - UINT32 load; /* Private Timer Load Register */ - UINT32 count; /* Private Timer Counter Register */ - UINT32 control; /* Private Timer Control Register */ - UINT32 intStatus; /* Private Timer Interrupt Status Register */ + UINT32 load; /* Private Timer Load Register */ //专用定时器加载寄存器 + UINT32 count; /* Private Timer Counter Register */ //专用定时器计数寄存器 + UINT32 control; /* Private Timer Control Register */ //专用定时器控制寄存器 + UINT32 intStatus; /* Private Timer Interrupt Status Register */ //专用定时器中断状态寄存器 } PrivateTimer; -typedef struct { - UINT32 low; /* Global Timer Counter Registers, low bits */ +typedef struct {//全局计数器 + UINT32 low; /* Global Timer Counter Registers, low bits */ //需用64位来表示,所以需要高低位 UINT32 high; /* Global Timer Counter Registers, high bits */ - UINT32 control; /* Global Timer Control Register */ + UINT32 control; /* Global Timer Control Register */ UINT32 intStatus; /* Global Timer Interrupt Status Register */ UINT32 compareLow; /* Comparator Value Registers, low bits */ UINT32 compareHigh; /* Comparator Value Registers, high bits */ diff --git a/platform/hw/hisoc/timer/timer.c b/platform/hw/hisoc/timer/timer.c index 4836fda7..206f24f4 100644 --- a/platform/hw/hisoc/timer/timer.c +++ b/platform/hw/hisoc/timer/timer.c @@ -1,408 +1,408 @@ -/* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "los_timer_pri.h" -#include "los_tick_pri.h" -#include "los_sys_pri.h" -#include "los_hwi.h" -#include "hisoc/sys_ctrl.h" -#include "los_swtmr.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -STATIC_ASSERT(LOSCFG_KERNEL_SMP != YES, "hisoc timer does not suppot on SMP mode!"); -STATIC_ASSERT(LOSCFG_BASE_CORE_TICK_HW_TIME == YES, "hisoc timer needs to turn on hw time!"); - -#define TIMER_ENABLE_BIT 7 -#define TIMER_COUNTING_MODE_BIT 6 -#define TIMER_INTERRUPT_ENABLE_BIT 5 -#define TIMER_FREQUENCY_DIV_BIT 3 -#define TIMER_SIZE_SELECT_BIT 1 -#define TIMER_ONESHOT_BIT 0 - -#define READ_TIMER (*(volatile UINT32 *)(TIMER_TICK_REG_BASE + TIMER_VALUE)) -#define US_PER_MS 1000 -#define MS_PER_S 1000 - -STATIC UINT32 g_timeStamp __attribute__((section(".data.init"))); -STATIC UINT32 g_lastDec __attribute__((section(".data.init"))); - -STATIC volatile UINT64 g_schedClockNanosec = 0; -STATIC volatile UINT64 g_schedClockCycle = 0; -STATIC volatile UINT32 g_timeClkLast = 0; -STATIC UINT16 g_swtmrID; - -#ifdef LOSCFG_KERNEL_TICKLESS -VOID HalClockTickTimerReload(UINT32 period) -{ - UINT32 cyclesPerTick; - cyclesPerTick = g_sysClock / LOSCFG_BASE_CORE_TICK_PER_SECOND; - - WRITE_UINT32(period, TIMER_TICK_REG_BASE + TIMER_LOAD); - WRITE_UINT32(cyclesPerTick, TIMER_TICK_REG_BASE + TIMER_BGLOAD); - - HalClockIrqClear(); - HalIrqClear(NUM_HAL_INTERRUPT_TIMER); -} -#endif - -VOID ResetTimerMasked(VOID) -{ - g_lastDec = READ_TIMER; - g_timeStamp = 0; -} - -UINT32 GetTimerMasked(VOID) -{ - UINT32 now = READ_TIMER; - - if (g_lastDec >= now) { - /* not roll back */ - g_timeStamp += g_lastDec - now; - } else { - /* rollback */ - g_timeStamp += g_lastDec + (g_sysClock / LOSCFG_BASE_CORE_TICK_PER_SECOND) - now; - } - - g_lastDec = now; - return g_timeStamp; -} - -UINT32 TimeClockRead(VOID) -{ - UINT32 value; - - READ_UINT32(value, TIMER_TIME_REG_BASE + TIMER_VALUE); - value = TIMER_MAXLOAD - value; - - return value; -} - -UINT32 ArchTimerRollback(VOID) -{ - UINT32 flag; - - READ_UINT32(flag, TIMER_TICK_REG_BASE + TIMER_RIS); - return flag; -} - -/* this func is start timer2 for start time */ -VOID HalClockInitStart(VOID) -{ - UINT32 temp; - /* - * enable timer2 here, - * but only time0 is used for system clock. - */ - READ_UINT32(temp, SYS_CTRL_REG_BASE + REG_SC_CTRL); - temp |= TIMER2_ENABLE; - WRITE_UINT32(temp, SYS_CTRL_REG_BASE + REG_SC_CTRL); - - /* init the timestamp and lastdec value */ - ResetTimerMasked(); - - /* disable timer2 */ - WRITE_UINT32(0x0, TIMER2_REG_BASE + TIMER_CONTROL); - /* set init value as period */ - WRITE_UINT32(TIMER_MAXLOAD, TIMER2_REG_BASE + TIMER_LOAD); - - /* - * Timing mode: 32bits [bit 1 set as 1] - * ticking with 1/256 clock frequency [bit 3 set as 1, bit 2 set as 0] - * timing circulary [bit 6 set as 1] - * timer enabled [bit 7 set as 1] - */ - temp = (1U << TIMER_ENABLE_BIT) | (1U << TIMER_COUNTING_MODE_BIT) | - (1U << TIMER_FREQUENCY_DIV_BIT) | (1U << TIMER_SIZE_SELECT_BIT); - WRITE_UINT32(temp, TIMER2_REG_BASE + TIMER_CONTROL); -} - -UINT32 GetTimer2Value(VOID) -{ - UINT32 temp; - - READ_UINT32(temp, TIMER2_REG_BASE + TIMER_VALUE); - return temp; -} - -UINT32 HalClockGetTickTimerCycles(VOID) -{ - UINT32 temp; - - READ_UINT32(temp, TIMER_TICK_REG_BASE + TIMER_VALUE); - return temp; -} - -/* get the system ms clock since the system start */ -UINT32 HiGetMsClock(VOID) -{ - const UINT32 t32 = TIMER_MAXLOAD - GetTimer2Value(); - UINT64 t64 = (UINT64)t32 << 0x8; /* Timer2 is divided by 256, left shift 8 to recover sys clock */ - UINT64 temp = OS_TIME_TIMER_CLOCK / MS_PER_S; - - return (UINT32)(t64 / temp); -} - -VOID HalClockInit(VOID) -{ - UINT32 temp; - UINT32 period = g_sysClock / LOSCFG_BASE_CORE_TICK_PER_SECOND; - /* - * enable time0, timer1 here, - * but only time0 is used for system clock. - */ - READ_UINT32(temp, SYS_CTRL_REG_BASE + REG_SC_CTRL); - temp |= TIMER_TICK_ENABLE | TIMER_TIME_ENABLE; - WRITE_UINT32(temp, SYS_CTRL_REG_BASE + REG_SC_CTRL); - - /* disable first */ - WRITE_UINT32(0x0, TIMER_TICK_REG_BASE + TIMER_CONTROL); - - /* set init value as period */ - WRITE_UINT32(period, TIMER_TICK_REG_BASE + TIMER_LOAD); - - /* - * Timing mode: 32bits [bit 1 set as 1] - * ticking with 1/1 clock frequency [bit 3 set as 0, bit 2 set as 0] - * interrupt enabled [bit 5 set as 1] - * timing circulary [bit 6 set as 1] - */ - temp = (1U << 6) | (1U << 5) | (1U << 1); - WRITE_UINT32(temp, TIMER_TICK_REG_BASE + TIMER_CONTROL); - - /* init the timestamp and lastdec value */ - ResetTimerMasked(); - - /* disable timer1 */ - WRITE_UINT32(0x0, TIMER_TIME_REG_BASE + TIMER_CONTROL); - /* set init value as period */ - WRITE_UINT32(0xffffffff, TIMER_TIME_REG_BASE + TIMER_LOAD); - - /* - * Timing mode: 32bits [bit 1 set as 1] - * ticking with 1/1 clock frequency [bit 3 set as 0, bit 2 set as 0] - * timing circulary [bit 6 set as 1] - * timer enabled [bit 7 set as 1] - */ - temp = (1U << 7) | (1U << 6) | (1U << 1); - WRITE_UINT32(temp, TIMER_TIME_REG_BASE + TIMER_CONTROL); - - (void)LOS_HwiCreate(NUM_HAL_INTERRUPT_TIMER, 0xa0, 0, OsTickHandler, 0); -} - -VOID HalClockIrqClear(VOID) -{ - WRITE_UINT32(1, TIMER_TICK_REG_BASE + TIMER_INT_CLR); -} - -VOID HalClockEnable(VOID) -{ - UINT32 val; - val = GET_UINT32(TIMER_TICK_REG_BASE + TIMER_CONTROL); - - /* timer enabled [bit 7 set as 1] */ - val |= 1U << TIMER_ENABLE_BIT; - WRITE_UINT32(val, TIMER_TICK_REG_BASE + TIMER_CONTROL); -} - -/* Delay for some number of micro-seconds */ -UINT32 GetTimer(UINT32 base) -{ - return GetTimerMasked() - base; -} - -VOID HalClockDelayUs(UINT32 usecs) -{ - UINT32 tmo = 0; - UINT32 tmp; - UINT32 intSave = LOS_IntLock(); - - /* part of usecs >= 1ms */ - if (usecs >= US_PER_MS) { - tmo = usecs / US_PER_MS; /* start to normalize for usec to cycles per sec */ - tmo *= (g_sysClock / MS_PER_S); /* largest msecond 1374389 */ - usecs -= (usecs / US_PER_MS * US_PER_MS); /* get value of usecs < 1ms */ - } - - /* part of usecs < 1ms */ - if (usecs) { - tmo += (usecs * (g_sysClock / MS_PER_S)) / US_PER_MS; /* translate us into sys_clock, prevent u32 overflow */ - } - - /* reset "advancing" timestamp to 0, set lastdec value */ - ResetTimerMasked(); - - tmp = GetTimer(0); /* get current timestamp */ - - /* set advancing stamp wake up time */ - tmo += tmp; - - while (GetTimerMasked() < tmo) {} - LOS_IntRestore(intSave); -} - -VOID HalClockFreqWrite(UINT32 freq) -{ - PRINT_WARN("hisoc timer does not support setting frequency\n"); -} - -STATIC UINT32 UpdateTimeClk(UINT32 *timeClk) -{ - UINT32 timeClkNow; - - timeClkNow = TimeClockRead(); - if (timeClkNow >= g_timeClkLast) { - *timeClk = timeClkNow - g_timeClkLast; - } else { - *timeClk = timeClkNow + (TIMER_MAXLOAD - g_timeClkLast); - } - return timeClkNow; -} - -VOID UpdateSchedClock(VOID) -{ - UINT32 timeClk; - UINT32 intSave; - - intSave = LOS_IntLock(); - g_timeClkLast = UpdateTimeClk(&timeClk); - g_schedClockCycle += (UINT64)timeClk; - g_schedClockNanosec += (UINT64)CYCLE_TO_NS(timeClk); - OsAdjTime(); - LOS_IntRestore(intSave); -} - -STATIC UINT64 GetSchedClock(VOID) -{ - UINT32 timeClk; - - (VOID)UpdateTimeClk(&timeClk); - - return (g_schedClockNanosec + (UINT64)CYCLE_TO_NS(timeClk)); -} - -STATIC UINT64 SchedClock(VOID) -{ - UINT32 intSave; - UINT64 timeClk64; - - intSave = LOS_IntLock(); - timeClk64 = GetSchedClock(); - LOS_IntRestore(intSave); - - return timeClk64; -} - -UINT64 hi_sched_clock(VOID) -{ - return SchedClock(); -} - -VOID SchedClockSwtmr(VOID) -{ - UINT32 ret; - ret = LOS_SwtmrCreate(SCHED_CLOCK_INTETRVAL_TICKS, LOS_SWTMR_MODE_PERIOD, - (SWTMR_PROC_FUNC)UpdateSchedClock, &g_swtmrID, 0); - if (ret != LOS_OK) { - PRINT_ERR("LOS_SwtmrCreate error %u\n", ret); - return; - } - ret = LOS_SwtmrStart(g_swtmrID); - if (ret != LOS_OK) { - PRINT_ERR("LOS_SwtmrStart error %u\n", ret); - return; - } -} - -LITE_OS_SEC_TEXT_INIT VOID HalClockStart(VOID) -{ - HalIrqUnmask(NUM_HAL_INTERRUPT_TIMER); - HalClockEnable(); - - /* start adjusting swtmer */ - SchedClockSwtmr(); - - g_cycle2NsScale = ((double)OS_SYS_NS_PER_SECOND / ((long)OS_TIME_TIMER_CLOCK)); -} - -UINT64 HalClockGetCycles(VOID) -{ - UINT32 timeClk; - UINT32 intSave; - UINT64 cycle; - - intSave = LOS_IntLock(); - (VOID)UpdateTimeClk(&timeClk); - cycle = g_schedClockCycle + (UINT64)timeClk; - LOS_IntRestore(intSave); - - return cycle; -} - -VOID HalDelayUs(UINT32 usecs) -{ - UINT32 tmo = 0; - UINT32 tmp; - UINT32 intSave = LOS_IntLock(); - - /* part of usecs >= 1ms */ - if (usecs >= US_PER_MS) { - tmo = usecs / US_PER_MS; /* start to normalize for usec to cycles per sec */ - tmo *= (g_sysClock / MS_PER_S); /* largest msecond 1374389 */ - usecs -= (usecs / US_PER_MS * US_PER_MS); /* get value of usecs < 1ms */ - } - - /* part of usecs < 1ms */ - if (usecs) { - tmo += (usecs * (g_sysClock / MS_PER_S)) / US_PER_MS; /* translate us into sys_clock, prevent u32 overflow */ - } - - /* reset "advancing" timestamp to 0, set lastdec value */ - ResetTimerMasked(); - - tmp = GetTimer(0); /* get current timestamp */ - - /* set advancing stamp wake up time */ - tmo += tmp; - - while (GetTimerMasked() < tmo) {} - LOS_IntRestore(intSave); -} - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_timer_pri.h" +#include "los_tick_pri.h" +#include "los_sys_pri.h" +#include "los_hwi.h" +#include "hisoc/sys_ctrl.h" +#include "los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +STATIC_ASSERT(LOSCFG_KERNEL_SMP != YES, "hisoc timer does not suppot on SMP mode!"); +STATIC_ASSERT(LOSCFG_BASE_CORE_TICK_HW_TIME == YES, "hisoc timer needs to turn on hw time!"); + +#define TIMER_ENABLE_BIT 7 +#define TIMER_COUNTING_MODE_BIT 6 +#define TIMER_INTERRUPT_ENABLE_BIT 5 +#define TIMER_FREQUENCY_DIV_BIT 3 +#define TIMER_SIZE_SELECT_BIT 1 +#define TIMER_ONESHOT_BIT 0 + +#define READ_TIMER (*(volatile UINT32 *)(TIMER_TICK_REG_BASE + TIMER_VALUE)) +#define US_PER_MS 1000 +#define MS_PER_S 1000 + +STATIC UINT32 g_timeStamp __attribute__((section(".data.init"))); +STATIC UINT32 g_lastDec __attribute__((section(".data.init"))); + +STATIC volatile UINT64 g_schedClockNanosec = 0; +STATIC volatile UINT64 g_schedClockCycle = 0; +STATIC volatile UINT32 g_timeClkLast = 0; +STATIC UINT16 g_swtmrID; + +#ifdef LOSCFG_KERNEL_TICKLESS +VOID HalClockTickTimerReload(UINT32 period) +{ + UINT32 cyclesPerTick; + cyclesPerTick = g_sysClock / LOSCFG_BASE_CORE_TICK_PER_SECOND; + + WRITE_UINT32(period, TIMER_TICK_REG_BASE + TIMER_LOAD); + WRITE_UINT32(cyclesPerTick, TIMER_TICK_REG_BASE + TIMER_BGLOAD); + + HalClockIrqClear(); + HalIrqClear(NUM_HAL_INTERRUPT_TIMER); +} +#endif + +VOID ResetTimerMasked(VOID) +{ + g_lastDec = READ_TIMER; + g_timeStamp = 0; +} + +UINT32 GetTimerMasked(VOID) +{ + UINT32 now = READ_TIMER; + + if (g_lastDec >= now) { + /* not roll back */ + g_timeStamp += g_lastDec - now; + } else { + /* rollback */ + g_timeStamp += g_lastDec + (g_sysClock / LOSCFG_BASE_CORE_TICK_PER_SECOND) - now; + } + + g_lastDec = now; + return g_timeStamp; +} + +UINT32 TimeClockRead(VOID) +{ + UINT32 value; + + READ_UINT32(value, TIMER_TIME_REG_BASE + TIMER_VALUE); + value = TIMER_MAXLOAD - value; + + return value; +} + +UINT32 ArchTimerRollback(VOID) +{ + UINT32 flag; + + READ_UINT32(flag, TIMER_TICK_REG_BASE + TIMER_RIS); + return flag; +} + +/* this func is start timer2 for start time */ +VOID HalClockInitStart(VOID) +{ + UINT32 temp; + /* + * enable timer2 here, + * but only time0 is used for system clock. + */ + READ_UINT32(temp, SYS_CTRL_REG_BASE + REG_SC_CTRL); + temp |= TIMER2_ENABLE; + WRITE_UINT32(temp, SYS_CTRL_REG_BASE + REG_SC_CTRL); + + /* init the timestamp and lastdec value */ + ResetTimerMasked(); + + /* disable timer2 */ + WRITE_UINT32(0x0, TIMER2_REG_BASE + TIMER_CONTROL); + /* set init value as period */ + WRITE_UINT32(TIMER_MAXLOAD, TIMER2_REG_BASE + TIMER_LOAD); + + /* + * Timing mode: 32bits [bit 1 set as 1] + * ticking with 1/256 clock frequency [bit 3 set as 1, bit 2 set as 0] + * timing circulary [bit 6 set as 1] + * timer enabled [bit 7 set as 1] + */ + temp = (1U << TIMER_ENABLE_BIT) | (1U << TIMER_COUNTING_MODE_BIT) | + (1U << TIMER_FREQUENCY_DIV_BIT) | (1U << TIMER_SIZE_SELECT_BIT); + WRITE_UINT32(temp, TIMER2_REG_BASE + TIMER_CONTROL); +} + +UINT32 GetTimer2Value(VOID) +{ + UINT32 temp; + + READ_UINT32(temp, TIMER2_REG_BASE + TIMER_VALUE); + return temp; +} + +UINT32 HalClockGetTickTimerCycles(VOID) +{ + UINT32 temp; + + READ_UINT32(temp, TIMER_TICK_REG_BASE + TIMER_VALUE); + return temp; +} + +/* get the system ms clock since the system start */ +UINT32 HiGetMsClock(VOID) +{ + const UINT32 t32 = TIMER_MAXLOAD - GetTimer2Value(); + UINT64 t64 = (UINT64)t32 << 0x8; /* Timer2 is divided by 256, left shift 8 to recover sys clock */ + UINT64 temp = OS_TIME_TIMER_CLOCK / MS_PER_S; + + return (UINT32)(t64 / temp); +} +//硬时钟初始化 +VOID HalClockInit(VOID) +{ + UINT32 temp; + UINT32 period = g_sysClock / LOSCFG_BASE_CORE_TICK_PER_SECOND;//一个TICK的周期数 + /* + * enable time0, timer1 here, + * but only time0 is used for system clock. + */ + READ_UINT32(temp, SYS_CTRL_REG_BASE + REG_SC_CTRL); + temp |= TIMER_TICK_ENABLE | TIMER_TIME_ENABLE; + WRITE_UINT32(temp, SYS_CTRL_REG_BASE + REG_SC_CTRL); + + /* disable first */ + WRITE_UINT32(0x0, TIMER_TICK_REG_BASE + TIMER_CONTROL); + + /* set init value as period */ + WRITE_UINT32(period, TIMER_TICK_REG_BASE + TIMER_LOAD); + + /* + * Timing mode: 32bits [bit 1 set as 1] + * ticking with 1/1 clock frequency [bit 3 set as 0, bit 2 set as 0] + * interrupt enabled [bit 5 set as 1] + * timing circulary [bit 6 set as 1] + */ + temp = (1U << 6) | (1U << 5) | (1U << 1); + WRITE_UINT32(temp, TIMER_TICK_REG_BASE + TIMER_CONTROL); + + /* init the timestamp and lastdec value */ + ResetTimerMasked(); + + /* disable timer1 */ + WRITE_UINT32(0x0, TIMER_TIME_REG_BASE + TIMER_CONTROL); + /* set init value as period */ + WRITE_UINT32(0xffffffff, TIMER_TIME_REG_BASE + TIMER_LOAD); + + /* + * Timing mode: 32bits [bit 1 set as 1] + * ticking with 1/1 clock frequency [bit 3 set as 0, bit 2 set as 0] + * timing circulary [bit 6 set as 1] + * timer enabled [bit 7 set as 1] + */ + temp = (1U << 7) | (1U << 6) | (1U << 1); + WRITE_UINT32(temp, TIMER_TIME_REG_BASE + TIMER_CONTROL); + + (void)LOS_HwiCreate(NUM_HAL_INTERRUPT_TIMER, 0xa0, 0, OsTickHandler, 0); +} + +VOID HalClockIrqClear(VOID) +{ + WRITE_UINT32(1, TIMER_TICK_REG_BASE + TIMER_INT_CLR); +} + +VOID HalClockEnable(VOID) +{ + UINT32 val; + val = GET_UINT32(TIMER_TICK_REG_BASE + TIMER_CONTROL); + + /* timer enabled [bit 7 set as 1] */ + val |= 1U << TIMER_ENABLE_BIT; + WRITE_UINT32(val, TIMER_TICK_REG_BASE + TIMER_CONTROL); +} + +/* Delay for some number of micro-seconds */ +UINT32 GetTimer(UINT32 base) +{ + return GetTimerMasked() - base; +} + +VOID HalClockDelayUs(UINT32 usecs) +{ + UINT32 tmo = 0; + UINT32 tmp; + UINT32 intSave = LOS_IntLock(); + + /* part of usecs >= 1ms */ + if (usecs >= US_PER_MS) { + tmo = usecs / US_PER_MS; /* start to normalize for usec to cycles per sec */ + tmo *= (g_sysClock / MS_PER_S); /* largest msecond 1374389 */ + usecs -= (usecs / US_PER_MS * US_PER_MS); /* get value of usecs < 1ms */ + } + + /* part of usecs < 1ms */ + if (usecs) { + tmo += (usecs * (g_sysClock / MS_PER_S)) / US_PER_MS; /* translate us into sys_clock, prevent u32 overflow */ + } + + /* reset "advancing" timestamp to 0, set lastdec value */ + ResetTimerMasked(); + + tmp = GetTimer(0); /* get current timestamp */ + + /* set advancing stamp wake up time */ + tmo += tmp; + + while (GetTimerMasked() < tmo) {} + LOS_IntRestore(intSave); +} + +VOID HalClockFreqWrite(UINT32 freq) +{ + PRINT_WARN("hisoc timer does not support setting frequency\n"); +} + +STATIC UINT32 UpdateTimeClk(UINT32 *timeClk) +{ + UINT32 timeClkNow; + + timeClkNow = TimeClockRead(); + if (timeClkNow >= g_timeClkLast) { + *timeClk = timeClkNow - g_timeClkLast; + } else { + *timeClk = timeClkNow + (TIMER_MAXLOAD - g_timeClkLast); + } + return timeClkNow; +} + +VOID UpdateSchedClock(VOID) +{ + UINT32 timeClk; + UINT32 intSave; + + intSave = LOS_IntLock(); + g_timeClkLast = UpdateTimeClk(&timeClk); + g_schedClockCycle += (UINT64)timeClk; + g_schedClockNanosec += (UINT64)CYCLE_TO_NS(timeClk); + OsAdjTime(); + LOS_IntRestore(intSave); +} + +STATIC UINT64 GetSchedClock(VOID) +{ + UINT32 timeClk; + + (VOID)UpdateTimeClk(&timeClk); + + return (g_schedClockNanosec + (UINT64)CYCLE_TO_NS(timeClk)); +} + +STATIC UINT64 SchedClock(VOID) +{ + UINT32 intSave; + UINT64 timeClk64; + + intSave = LOS_IntLock(); + timeClk64 = GetSchedClock(); + LOS_IntRestore(intSave); + + return timeClk64; +} + +UINT64 hi_sched_clock(VOID) +{ + return SchedClock(); +} + +VOID SchedClockSwtmr(VOID) +{ + UINT32 ret; + ret = LOS_SwtmrCreate(SCHED_CLOCK_INTETRVAL_TICKS, LOS_SWTMR_MODE_PERIOD, + (SWTMR_PROC_FUNC)UpdateSchedClock, &g_swtmrID, 0); + if (ret != LOS_OK) { + PRINT_ERR("LOS_SwtmrCreate error %u\n", ret); + return; + } + ret = LOS_SwtmrStart(g_swtmrID); + if (ret != LOS_OK) { + PRINT_ERR("LOS_SwtmrStart error %u\n", ret); + return; + } +} + +LITE_OS_SEC_TEXT_INIT VOID HalClockStart(VOID) +{ + HalIrqUnmask(NUM_HAL_INTERRUPT_TIMER); + HalClockEnable(); + + /* start adjusting swtmer */ + SchedClockSwtmr(); + + g_cycle2NsScale = ((double)OS_SYS_NS_PER_SECOND / ((long)OS_TIME_TIMER_CLOCK)); +} + +UINT64 HalClockGetCycles(VOID) +{ + UINT32 timeClk; + UINT32 intSave; + UINT64 cycle; + + intSave = LOS_IntLock(); + (VOID)UpdateTimeClk(&timeClk); + cycle = g_schedClockCycle + (UINT64)timeClk; + LOS_IntRestore(intSave); + + return cycle; +} + +VOID HalDelayUs(UINT32 usecs) +{ + UINT32 tmo = 0; + UINT32 tmp; + UINT32 intSave = LOS_IntLock(); + + /* part of usecs >= 1ms */ + if (usecs >= US_PER_MS) { + tmo = usecs / US_PER_MS; /* start to normalize for usec to cycles per sec */ + tmo *= (g_sysClock / MS_PER_S); /* largest msecond 1374389 */ + usecs -= (usecs / US_PER_MS * US_PER_MS); /* get value of usecs < 1ms */ + } + + /* part of usecs < 1ms */ + if (usecs) { + tmo += (usecs * (g_sysClock / MS_PER_S)) / US_PER_MS; /* translate us into sys_clock, prevent u32 overflow */ + } + + /* reset "advancing" timestamp to 0, set lastdec value */ + ResetTimerMasked(); + + tmp = GetTimer(0); /* get current timestamp */ + + /* set advancing stamp wake up time */ + tmo += tmp; + + while (GetTimerMasked() < tmo) {} + LOS_IntRestore(intSave); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/zzz/git/push.sh b/zzz/git/push.sh index 7299c817..1d88abb8 100644 --- a/zzz/git/push.sh +++ b/zzz/git/push.sh @@ -1,5 +1,5 @@ git add -A -git commit -m '内核哪种任务的优先级是最高的 ?. +git commit -m '初始化硬时钟. 搜索 @note_pic 可查看绘制的全部字符图 搜索 @note_why 是尚未看明白的地方,有看明白的,请Pull Request完善 搜索 @note_thinking 是一些的思考和建议 -- GitLab