1d6aed566Sopenharmony_ci/* 2d6aed566Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 3d6aed566Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4d6aed566Sopenharmony_ci * you may not use this file except in compliance with the License. 5d6aed566Sopenharmony_ci * You may obtain a copy of the License at 6d6aed566Sopenharmony_ci * 7d6aed566Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8d6aed566Sopenharmony_ci * 9d6aed566Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10d6aed566Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11d6aed566Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d6aed566Sopenharmony_ci * See the License for the specific language governing permissions and 13d6aed566Sopenharmony_ci * limitations under the License. 14d6aed566Sopenharmony_ci */ 15d6aed566Sopenharmony_ci 16d6aed566Sopenharmony_ci#include "plic.h" 17d6aed566Sopenharmony_ci#include "soc.h" 18d6aed566Sopenharmony_ci#include "los_reg.h" 19d6aed566Sopenharmony_ci#include "los_arch_interrupt.h" 20d6aed566Sopenharmony_ci#include "los_debug.h" 21d6aed566Sopenharmony_ci 22d6aed566Sopenharmony_ci#ifdef __cplusplus 23d6aed566Sopenharmony_ci#if __cplusplus 24d6aed566Sopenharmony_ciextern "C" { 25d6aed566Sopenharmony_ci#endif 26d6aed566Sopenharmony_ci#endif 27d6aed566Sopenharmony_ci 28d6aed566Sopenharmony_ciSTATIC VOID OsMachineExternalInterrupt(VOID *arg) 29d6aed566Sopenharmony_ci{ 30d6aed566Sopenharmony_ci volatile UINT32 *plicReg = (volatile UINT32 *)(PLIC_REG_BASE + 0x4); 31d6aed566Sopenharmony_ci UINT32 irqNum, saveIrqNum; 32d6aed566Sopenharmony_ci 33d6aed566Sopenharmony_ci READ_UINT32(irqNum, plicReg); 34d6aed566Sopenharmony_ci saveIrqNum = irqNum; 35d6aed566Sopenharmony_ci 36d6aed566Sopenharmony_ci if ((irqNum >= OS_RISCV_CUSTOM_IRQ_VECTOR_CNT) || (irqNum == 0)) { 37d6aed566Sopenharmony_ci HalHwiDefaultHandler((VOID *)irqNum); 38d6aed566Sopenharmony_ci } 39d6aed566Sopenharmony_ci 40d6aed566Sopenharmony_ci irqNum += RISCV_SYS_MAX_IRQ; 41d6aed566Sopenharmony_ci 42d6aed566Sopenharmony_ci g_hwiForm[irqNum].pfnHook(g_hwiForm[irqNum].uwParam); 43d6aed566Sopenharmony_ci 44d6aed566Sopenharmony_ci WRITE_UINT32(saveIrqNum, plicReg); 45d6aed566Sopenharmony_ci} 46d6aed566Sopenharmony_ci 47d6aed566Sopenharmony_ci#define OS_PLIC_MAX ((OS_RISCV_CUSTOM_IRQ_VECTOR_CNT >> 5) + 1) 48d6aed566Sopenharmony_ci 49d6aed566Sopenharmony_ciVOID PlicIrqInit(VOID) 50d6aed566Sopenharmony_ci{ 51d6aed566Sopenharmony_ci volatile UINT32 *plicPrioReg = (volatile UINT32 *)PLIC_PRIO_BASE; 52d6aed566Sopenharmony_ci volatile UINT32 *plicEnReg = (volatile UINT32 *)PLIC_ENABLE_BASE; 53d6aed566Sopenharmony_ci volatile UINT32 *plicReg = (volatile UINT32 *)PLIC_REG_BASE; 54d6aed566Sopenharmony_ci INT32 i; 55d6aed566Sopenharmony_ci UINT32 ret; 56d6aed566Sopenharmony_ci 57d6aed566Sopenharmony_ci for (i = 0; i < OS_PLIC_MAX; i++) { 58d6aed566Sopenharmony_ci WRITE_UINT32(0x0, plicEnReg); 59d6aed566Sopenharmony_ci plicEnReg++; 60d6aed566Sopenharmony_ci } 61d6aed566Sopenharmony_ci 62d6aed566Sopenharmony_ci for (i = 0; i < OS_RISCV_CUSTOM_IRQ_VECTOR_CNT; i++) { 63d6aed566Sopenharmony_ci WRITE_UINT32(0x0, plicPrioReg); 64d6aed566Sopenharmony_ci plicPrioReg++; 65d6aed566Sopenharmony_ci } 66d6aed566Sopenharmony_ci 67d6aed566Sopenharmony_ci WRITE_UINT32(0, plicReg); 68d6aed566Sopenharmony_ci 69d6aed566Sopenharmony_ci ret = LOS_HwiCreate(RISCV_MACH_EXT_IRQ, 0x1, 0, OsMachineExternalInterrupt, 0); 70d6aed566Sopenharmony_ci if (ret != LOS_OK) { 71d6aed566Sopenharmony_ci PRINT_ERR("Create machine external failed! ret : 0x%x\n", ret); 72d6aed566Sopenharmony_ci } 73d6aed566Sopenharmony_ci} 74d6aed566Sopenharmony_ci 75d6aed566Sopenharmony_ciVOID PlicIrqSetPrio(UINT32 vector, UINT32 pri) 76d6aed566Sopenharmony_ci{ 77d6aed566Sopenharmony_ci volatile UINT32 *plicReg = (volatile UINT32 *)PLIC_PRIO_BASE; 78d6aed566Sopenharmony_ci 79d6aed566Sopenharmony_ci plicReg += (vector - RISCV_SYS_MAX_IRQ); 80d6aed566Sopenharmony_ci WRITE_UINT32(pri, plicReg); 81d6aed566Sopenharmony_ci} 82d6aed566Sopenharmony_ci 83d6aed566Sopenharmony_ciVOID PlicIrqEnable(UINT32 vector) 84d6aed566Sopenharmony_ci{ 85d6aed566Sopenharmony_ci UINT32 irqValue; 86d6aed566Sopenharmony_ci UINT32 locIrq = vector - RISCV_SYS_MAX_IRQ; 87d6aed566Sopenharmony_ci volatile UINT32 *plicReg = (volatile UINT32 *)PLIC_ENABLE_BASE; 88d6aed566Sopenharmony_ci 89d6aed566Sopenharmony_ci plicReg += (locIrq >> 5); /* 5: The PLIC interrupt controls the bit width */ 90d6aed566Sopenharmony_ci READ_UINT32(irqValue, plicReg); 91d6aed566Sopenharmony_ci irqValue |= (1 << (locIrq & 31)); /* 31: plic irq mask */ 92d6aed566Sopenharmony_ci WRITE_UINT32(irqValue, plicReg); 93d6aed566Sopenharmony_ci} 94d6aed566Sopenharmony_ci 95d6aed566Sopenharmony_ciVOID PlicIrqDisable(UINT32 vector) 96d6aed566Sopenharmony_ci{ 97d6aed566Sopenharmony_ci UINT32 irqValue; 98d6aed566Sopenharmony_ci UINT32 locIrq = vector - RISCV_SYS_MAX_IRQ; 99d6aed566Sopenharmony_ci volatile UINT32 *plicReg = (volatile UINT32 *)PLIC_ENABLE_BASE; 100d6aed566Sopenharmony_ci 101d6aed566Sopenharmony_ci plicReg += (locIrq >> 5); /* 5: The PLIC interrupt controls the bit width */ 102d6aed566Sopenharmony_ci READ_UINT32(irqValue, plicReg); 103d6aed566Sopenharmony_ci irqValue &= ~(1 << (locIrq & 31)); /* 31: plic irq mask */ 104d6aed566Sopenharmony_ci WRITE_UINT32(irqValue, plicReg); 105d6aed566Sopenharmony_ci} 106d6aed566Sopenharmony_ci 107d6aed566Sopenharmony_ci#ifdef __cplusplus 108d6aed566Sopenharmony_ci#if __cplusplus 109d6aed566Sopenharmony_ci} 110d6aed566Sopenharmony_ci#endif /* __cplusplus */ 111d6aed566Sopenharmony_ci#endif /* __cplusplus */ 112d6aed566Sopenharmony_ci 113