1 /*
2 * Copyright (c) 2013-2020, Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 * Copyright (c) 2021 Nuclei Limited. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without modification,
7 * are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright notice, this list of
10 * conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
13 * of conditions and the following disclaimer in the documentation and/or other materials
14 * provided with the distribution.
15 *
16 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
17 * to endorse or promote products derived from this software without specific prior written
18 * permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
30 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include "los_timer.h"
34 #include "los_config.h"
35 #include "los_tick.h"
36 #include "los_reg.h"
37 #include "los_arch_interrupt.h"
38 #include "los_arch_timer.h"
39 #include "nuclei_sdk_hal.h"
40
41 #define configKERNEL_INTERRUPT_PRIORITY 0
42
43 #define SYSTICK_TICK_CONST (SOC_TIMER_FREQ / LOSCFG_BASE_CORE_TICK_PER_SECOND)
44
45 STATIC HWI_PROC_FUNC g_sysTickHandler = (HWI_PROC_FUNC)NULL;
46
47 extern UINT32 g_intCount;
48
49 STATIC UINT32 SysTickStart(HWI_PROC_FUNC handler);
50 STATIC UINT64 SysTickReload(UINT64 nextResponseTime);
51 STATIC UINT64 SysTickCycleGet(UINT32 *period);
52 STATIC VOID SysTickLock(VOID);
53 STATIC VOID SysTickUnlock(VOID);
54
55 STATIC ArchTickTimer g_archTickTimer = {
56 .freq = 0,
57 .irqNum = SysTimer_IRQn,
58 .periodMax = LOSCFG_BASE_CORE_TICK_RESPONSE_MAX,
59 .init = SysTickStart,
60 .getCycle = SysTickCycleGet,
61 .reload = SysTickReload,
62 .lock = SysTickLock,
63 .unlock = SysTickUnlock,
64 .tickHandler = NULL,
65 };
66
SysTickStart(HWI_PROC_FUNC handler)67 STATIC UINT32 SysTickStart(HWI_PROC_FUNC handler)
68 {
69 ArchTickTimer *tick = &g_archTickTimer;
70 tick->freq = OS_SYS_CLOCK;
71
72 SysTick_Config(SYSTICK_TICK_CONST);
73 ECLIC_DisableIRQ(SysTimer_IRQn);
74 ECLIC_SetLevelIRQ(SysTimer_IRQn, configKERNEL_INTERRUPT_PRIORITY);
75 ECLIC_SetShvIRQ(SysTimer_IRQn, ECLIC_NON_VECTOR_INTERRUPT);
76 ECLIC_EnableIRQ(SysTimer_IRQn);
77
78 /* Set SWI interrupt level to lowest level/priority, SysTimerSW as Vector Interrupt */
79 ECLIC_SetShvIRQ(SysTimerSW_IRQn, ECLIC_VECTOR_INTERRUPT);
80 ECLIC_SetLevelIRQ(SysTimerSW_IRQn, configKERNEL_INTERRUPT_PRIORITY);
81 ECLIC_EnableIRQ(SysTimerSW_IRQn);
82 g_intCount = 0;
83
84 g_sysTickHandler = handler;
85
86 return LOS_OK; /* never return */
87 }
88
89 #define ArchTickSysTickHandler eclic_mtip_handler
90
ArchTickSysTickHandler(void)91 void ArchTickSysTickHandler(void)
92 {
93 /* Do systick handler registered in HalTickStart. */
94 if ((void *)g_sysTickHandler != NULL) {
95 g_sysTickHandler();
96 }
97 }
98
SysTickReload(UINT64 nextResponseTime)99 STATIC UINT64 SysTickReload(UINT64 nextResponseTime)
100 {
101 SysTick_Reload(nextResponseTime);
102 return nextResponseTime;
103 }
104
SysTickCycleGet(UINT32 * period)105 STATIC UINT64 SysTickCycleGet(UINT32 *period)
106 {
107 UINT64 ticks;
108 UINT32 intSave = LOS_IntLock();
109 ticks = SysTimer_GetLoadValue();
110 *period = (UINT32)ticks;
111 LOS_IntRestore(intSave);
112 return ticks;
113 }
114
SysTickLock(VOID)115 STATIC VOID SysTickLock(VOID)
116 {
117 SysTimer_Stop();
118 }
119
SysTickUnlock(VOID)120 STATIC VOID SysTickUnlock(VOID)
121 {
122 SysTimer_Start();
123 }
124
ArchSysTickTimerGet(VOID)125 ArchTickTimer *ArchSysTickTimerGet(VOID)
126 {
127 return &g_archTickTimer;
128 }
129
ArchEnterSleep(VOID)130 UINT32 ArchEnterSleep(VOID)
131 {
132 __WFI();
133
134 return LOS_OK;
135 }
136
137