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 * 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_timer.h" 33#include "los_config.h" 34#include "los_tick.h" 35#include "los_reg.h" 36#include "los_arch_interrupt.h" 37#include "los_arch_timer.h" 38#include "riscv_hal.h" 39#include "los_debug.h" 40 41STATIC UINT32 SysTickStart(HWI_PROC_FUNC handler); 42STATIC UINT64 SysTickReload(UINT64 nextResponseTime); 43STATIC UINT64 SysTickCycleGet(UINT32 *period); 44STATIC VOID SysTickLock(VOID); 45STATIC VOID SysTickUnlock(VOID); 46 47STATIC ArchTickTimer g_archTickTimer = { 48 .freq = 0, 49 .irqNum = RISCV_MACH_TIMER_IRQ, 50 .periodMax = LOSCFG_BASE_CORE_TICK_RESPONSE_MAX, 51 .init = SysTickStart, 52 .getCycle = SysTickCycleGet, 53 .reload = SysTickReload, 54 .lock = SysTickLock, 55 .unlock = SysTickUnlock, 56 .tickHandler = NULL, 57}; 58 59STATIC UINT32 SysTickStart(HWI_PROC_FUNC handler) 60{ 61 ArchTickTimer *tick = &g_archTickTimer; 62 63 UINT32 period = (UINT32)LOSCFG_BASE_CORE_TICK_RESPONSE_MAX; 64 HwiIrqParam irqParam; 65 irqParam.pDevId = (VOID *)period; 66 67 UINT32 ret = LOS_HwiCreate(RISCV_MACH_TIMER_IRQ, 0x1, 0, handler, &irqParam); 68 if (ret != LOS_OK) { 69 return ret; 70 } 71 72 tick->freq = OS_SYS_CLOCK; 73 74 WRITE_UINT32(0xffffffff, MTIMERCMP + 4); /* The high 4 bits of mtimer */ 75 WRITE_UINT32(period, MTIMERCMP); 76 WRITE_UINT32(0x0, MTIMERCMP + 4); /* The high 4 bits of mtimer */ 77 78 HalIrqEnable(RISCV_MACH_TIMER_IRQ); 79 return LOS_OK; 80} 81 82STATIC UINT64 SysTickReload(UINT64 nextResponseTime) 83{ 84 UINT64 timeMax = (UINT64)LOSCFG_BASE_CORE_TICK_RESPONSE_MAX - 1; 85 UINT64 timer; 86 UINT32 timerL, timerH; 87 READ_UINT32(timerL, MTIMER); 88 READ_UINT32(timerH, MTIMER + MTIMER_HI_OFFSET); 89 timer = OS_COMBINED_64(timerH, timerL); 90 if ((timeMax - nextResponseTime) > timer) { 91 timer += nextResponseTime; 92 } else { 93 timer = timeMax; 94 } 95 96 HalIrqDisable(RISCV_MACH_TIMER_IRQ); 97 WRITE_UINT32(0xffffffff, MTIMERCMP + MTIMER_HI_OFFSET); 98 WRITE_UINT32((UINT32)timer, MTIMERCMP); 99 WRITE_UINT32((UINT32)(timer >> SHIFT_32_BIT), MTIMERCMP + MTIMER_HI_OFFSET); 100 HalIrqEnable(RISCV_MACH_TIMER_IRQ); 101 return nextResponseTime; 102} 103 104STATIC UINT64 SysTickCycleGet(UINT32 *period) 105{ 106 (VOID)period; 107 UINT32 timerL, timerH; 108 109 READ_UINT32(timerL, MTIMER); 110 READ_UINT32(timerH, MTIMER + MTIMER_HI_OFFSET); 111 return OS_COMBINED_64(timerH, timerL); 112} 113 114STATIC VOID SysTickLock(VOID) 115{ 116 HalIrqDisable(RISCV_MACH_TIMER_IRQ); 117} 118 119STATIC VOID SysTickUnlock(VOID) 120{ 121 HalIrqEnable(RISCV_MACH_TIMER_IRQ); 122} 123 124ArchTickTimer *ArchSysTickTimerGet(VOID) 125{ 126 return &g_archTickTimer; 127} 128 129UINT32 ArchEnterSleep(VOID) 130{ 131 wfi(); 132 133 return LOS_OK; 134} 135 136