1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "los_hw_pri.h"
33 #include "los_tick_pri.h"
34 #include "los_sys_pri.h"
35 #include "gic_common.h"
36
37 #define STRING_COMB(x, y, z) x ## y ## z
38
39 #ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE
40 #define TIMER_REG(reg) STRING_COMB(TIMER_REG_, CNTPS, reg)
41 #else
42 #define TIMER_REG(reg) STRING_COMB(TIMER_REG_, CNTP, reg)
43 #endif
44 #define TIMER_REG_CTL TIMER_REG(_CTL) /* 32 bits */
45 #define TIMER_REG_TVAL TIMER_REG(_TVAL) /* 32 bits */
46 #define TIMER_REG_CVAL TIMER_REG(_CVAL) /* 64 bits */
47 #define TIMER_REG_CT TIMER_REG(CT) /* 64 bits */
48
49 #ifdef __LP64__
50
51 #define TIMER_REG_CNTFRQ cntfrq_el0
52
53 /* CNTP AArch64 registers */
54 #define TIMER_REG_CNTP_CTL cntp_ctl_el0
55 #define TIMER_REG_CNTP_TVAL cntp_tval_el0
56 #define TIMER_REG_CNTP_CVAL cntp_cval_el0
57 #define TIMER_REG_CNTPCT cntpct_el0
58
59 /* CNTPS AArch64 registers */
60 #define TIMER_REG_CNTPS_CTL cntps_ctl_el1
61 #define TIMER_REG_CNTPS_TVAL cntps_tval_el1
62 #define TIMER_REG_CNTPS_CVAL cntps_cval_el1
63 #define TIMER_REG_CNTPSCT cntpct_el0
64
65 #define READ_TIMER_REG32(reg) AARCH64_SYSREG_READ(reg)
66 #define READ_TIMER_REG64(reg) AARCH64_SYSREG_READ(reg)
67 #define WRITE_TIMER_REG32(reg, val) AARCH64_SYSREG_WRITE(reg, (UINT64)(val))
68 #define WRITE_TIMER_REG64(reg, val) AARCH64_SYSREG_WRITE(reg, val)
69
70 #else /* Aarch32 */
71
72 #define TIMER_REG_CNTFRQ CP15_REG(c14, 0, c0, 0)
73
74 /* CNTP AArch32 registers */
75 #define TIMER_REG_CNTP_CTL CP15_REG(c14, 0, c2, 1)
76 #define TIMER_REG_CNTP_TVAL CP15_REG(c14, 0, c2, 0)
77 #define TIMER_REG_CNTP_CVAL CP15_REG64(c14, 2)
78 #define TIMER_REG_CNTPCT CP15_REG64(c14, 0)
79
80 /* CNTPS AArch32 registers are banked and accessed though CNTP */
81 #define CNTPS CNTP
82
83 #define READ_TIMER_REG32(reg) ARM_SYSREG_READ(reg)
84 #define READ_TIMER_REG64(reg) ARM_SYSREG64_READ(reg)
85 #define WRITE_TIMER_REG32(reg, val) ARM_SYSREG_WRITE(reg, val)
86 #define WRITE_TIMER_REG64(reg, val) ARM_SYSREG64_WRITE(reg, val)
87
88 #endif
89
HalClockFreqRead(VOID)90 UINT32 HalClockFreqRead(VOID)
91 {
92 return READ_TIMER_REG32(TIMER_REG_CNTFRQ);
93 }
94
HalClockFreqWrite(UINT32 freq)95 VOID HalClockFreqWrite(UINT32 freq)
96 {
97 WRITE_TIMER_REG32(TIMER_REG_CNTFRQ, freq);
98 }
99
TimerCtlWrite(UINT32 cntpCtl)100 STATIC_INLINE VOID TimerCtlWrite(UINT32 cntpCtl)
101 {
102 WRITE_TIMER_REG32(TIMER_REG_CTL, cntpCtl);
103 }
104
TimerCvalRead(VOID)105 STATIC_INLINE UINT64 TimerCvalRead(VOID)
106 {
107 return READ_TIMER_REG64(TIMER_REG_CVAL);
108 }
109
TimerCvalWrite(UINT64 cval)110 STATIC_INLINE VOID TimerCvalWrite(UINT64 cval)
111 {
112 WRITE_TIMER_REG64(TIMER_REG_CVAL, cval);
113 }
114
TimerTvalWrite(UINT32 tval)115 STATIC_INLINE VOID TimerTvalWrite(UINT32 tval)
116 {
117 WRITE_TIMER_REG32(TIMER_REG_TVAL, tval);
118 }
119
HalClockGetCycles(VOID)120 UINT64 HalClockGetCycles(VOID)
121 {
122 UINT64 cntpct;
123
124 cntpct = READ_TIMER_REG64(TIMER_REG_CT);
125 return cntpct;
126 }
127
HalClockInit(VOID)128 LITE_OS_SEC_TEXT_INIT VOID HalClockInit(VOID)
129 {
130 UINT32 ret;
131
132 g_sysClock = HalClockFreqRead();
133 ret = LOS_HwiCreate(OS_TICK_INT_NUM, MIN_INTERRUPT_PRIORITY, 0, OsTickHandler, 0);
134 if (ret != LOS_OK) {
135 PRINT_ERR("%s, %d create tick irq failed, ret:0x%x\n", __FUNCTION__, __LINE__, ret);
136 }
137 }
138
HalClockStart(VOID)139 LITE_OS_SEC_TEXT_INIT VOID HalClockStart(VOID)
140 {
141 HalIrqUnmask(OS_TICK_INT_NUM);
142
143 /* triggle the first tick */
144 TimerCtlWrite(0);
145 TimerTvalWrite(OS_CYCLE_PER_TICK);
146 TimerCtlWrite(1);
147 }
148
HalDelayUs(UINT32 usecs)149 VOID HalDelayUs(UINT32 usecs)
150 {
151 UINT64 cycles = (UINT64)usecs * g_sysClock / OS_SYS_US_PER_SECOND;
152 UINT64 deadline = HalClockGetCycles() + cycles;
153
154 while (HalClockGetCycles() < deadline) {
155 __asm__ volatile ("nop");
156 }
157 }
158
hi_sched_clock(VOID)159 DEPRECATED UINT64 hi_sched_clock(VOID)
160 {
161 return LOS_CurrNanosec();
162 }
163
HalClockGetTickTimerCycles(VOID)164 UINT32 HalClockGetTickTimerCycles(VOID)
165 {
166 UINT64 cval = TimerCvalRead();
167 UINT64 cycles = HalClockGetCycles();
168
169 return (UINT32)((cval > cycles) ? (cval - cycles) : 0);
170 }
171
HalClockTickTimerReload(UINT64 cycles)172 UINT64 HalClockTickTimerReload(UINT64 cycles)
173 {
174 HalIrqMask(OS_TICK_INT_NUM);
175 HalIrqClear(OS_TICK_INT_NUM);
176
177 TimerCtlWrite(0);
178 TimerCvalWrite(HalClockGetCycles() + cycles);
179 TimerCtlWrite(1);
180
181 HalIrqUnmask(OS_TICK_INT_NUM);
182 return cycles;
183 }
184