From 195705d11f19de09967ae6ea25678da0fdde6f43 Mon Sep 17 00:00:00 2001 From: Ville Juven Date: Thu, 17 Mar 2022 10:22:00 +0200 Subject: [PATCH] MPFS: Create centralized module for PLIC address handling Reduce complexity and copy-paste amount by implementing a module to handle calculating PLIC offsets. --- arch/risc-v/src/mpfs/Make.defs | 1 + arch/risc-v/src/mpfs/hardware/mpfs_plic.h | 1 + arch/risc-v/src/mpfs/mpfs_irq.c | 81 +++----------- arch/risc-v/src/mpfs/mpfs_irq_dispatch.c | 15 +-- arch/risc-v/src/mpfs/mpfs_plic.c | 130 ++++++++++++++++++++++ arch/risc-v/src/mpfs/mpfs_plic.h | 73 ++++++++++++ 6 files changed, 222 insertions(+), 79 deletions(-) create mode 100644 arch/risc-v/src/mpfs/mpfs_plic.c create mode 100644 arch/risc-v/src/mpfs/mpfs_plic.h diff --git a/arch/risc-v/src/mpfs/Make.defs b/arch/risc-v/src/mpfs/Make.defs index aebaac16a0..5a6ecdfcf4 100755 --- a/arch/risc-v/src/mpfs/Make.defs +++ b/arch/risc-v/src/mpfs/Make.defs @@ -56,6 +56,7 @@ CHIP_CSRCS += mpfs_irq.c mpfs_irq_dispatch.c CHIP_CSRCS += mpfs_lowputc.c mpfs_serial.c CHIP_CSRCS += mpfs_start.c mpfs_timerisr.c CHIP_CSRCS += mpfs_gpio.c mpfs_systemreset.c +CHIP_CSRCS += mpfs_plic.c ifeq ($(CONFIG_MPFS_DMA),y) CHIP_CSRCS += mpfs_dma.c diff --git a/arch/risc-v/src/mpfs/hardware/mpfs_plic.h b/arch/risc-v/src/mpfs/hardware/mpfs_plic.h index e805d31beb..11513b7161 100755 --- a/arch/risc-v/src/mpfs/hardware/mpfs_plic.h +++ b/arch/risc-v/src/mpfs/hardware/mpfs_plic.h @@ -37,6 +37,7 @@ #define MPFS_PLIC_I51 (MPFS_PLIC_BASE + 0x001014) #define MPFS_HART_MIE_OFFSET (0x100) +#define MPFS_HART_SIE_OFFSET (0x80) #define MPFS_PLIC_H0_MIE0 (MPFS_PLIC_BASE + 0x002000) #define MPFS_PLIC_H0_MIE1 (MPFS_PLIC_BASE + 0x002004) diff --git a/arch/risc-v/src/mpfs/mpfs_irq.c b/arch/risc-v/src/mpfs/mpfs_irq.c index 80080c102f..3fb8c17666 100755 --- a/arch/risc-v/src/mpfs/mpfs_irq.c +++ b/arch/risc-v/src/mpfs/mpfs_irq.c @@ -35,6 +35,7 @@ #include "riscv_internal.h" #include "mpfs.h" +#include "mpfs_plic.h" /**************************************************************************** * Public Data @@ -62,39 +63,18 @@ void up_irqinitialize(void) /* Disable all global interrupts for current hart */ - uintptr_t hart_id = riscv_mhartid(); + uintptr_t iebase = mpfs_plic_get_iebase(); - uint32_t *miebase; - if (hart_id == 0) - { - miebase = (uint32_t *)MPFS_PLIC_H0_MIE0; - } - else - { - miebase = (uint32_t *)(MPFS_PLIC_H1_MIE0 + - (hart_id - 1) * MPFS_HART_MIE_OFFSET); - } - - putreg32(0x0, miebase + 0); - putreg32(0x0, miebase + 1); - putreg32(0x0, miebase + 2); - putreg32(0x0, miebase + 3); - putreg32(0x0, miebase + 4); - putreg32(0x0, miebase + 5); + putreg32(0x0, iebase + 0); + putreg32(0x0, iebase + 4); + putreg32(0x0, iebase + 8); + putreg32(0x0, iebase + 12); + putreg32(0x0, iebase + 16); + putreg32(0x0, iebase + 20); /* Clear pendings in PLIC (for current hart) */ - uintptr_t claim_address; - if (hart_id == 0) - { - claim_address = MPFS_PLIC_H0_MCLAIM; - } - else - { - claim_address = MPFS_PLIC_H1_MCLAIM + - ((hart_id - 1) * MPFS_PLIC_NEXTHART_OFFSET); - } - + uintptr_t claim_address = mpfs_plic_get_claimbase(); uint32_t val = getreg32(claim_address); putreg32(val, claim_address); @@ -116,18 +96,7 @@ void up_irqinitialize(void) /* Set irq threshold to 0 (permits all global interrupts) */ - uint32_t *threshold_address; - if (hart_id == 0) - { - threshold_address = (uint32_t *)MPFS_PLIC_H0_MTHRESHOLD; - } - else - { - threshold_address = (uint32_t *)(MPFS_PLIC_H1_MTHRESHOLD + - ((hart_id - 1) * - MPFS_PLIC_NEXTHART_OFFSET)); - } - + uintptr_t threshold_address = mpfs_plic_get_thresholdbase(); putreg32(0, threshold_address); /* currents_regs is non-NULL only while processing an interrupt */ @@ -180,22 +149,11 @@ void up_disable_irq(int irq) /* Clear enable bit for the irq */ - uintptr_t hart_id = riscv_mhartid(); - uintptr_t miebase; - - if (hart_id == 0) - { - miebase = MPFS_PLIC_H0_MIE0; - } - else - { - miebase = MPFS_PLIC_H1_MIE0 + - ((hart_id - 1) * MPFS_HART_MIE_OFFSET); - } + uintptr_t iebase = mpfs_plic_get_iebase(); if (0 <= extirq && extirq <= NR_IRQS - MPFS_IRQ_EXT_START) { - modifyreg32(miebase + (4 * (extirq / 32)), 1 << (extirq % 32), 0); + modifyreg32(iebase + (4 * (extirq / 32)), 1 << (extirq % 32), 0); } else { @@ -234,22 +192,11 @@ void up_enable_irq(int irq) /* Set enable bit for the irq */ - uintptr_t hart_id = riscv_mhartid(); - uintptr_t miebase; - - if (hart_id == 0) - { - miebase = MPFS_PLIC_H0_MIE0; - } - else - { - miebase = MPFS_PLIC_H1_MIE0 + - ((hart_id - 1) * MPFS_HART_MIE_OFFSET); - } + uintptr_t iebase = mpfs_plic_get_iebase(); if (0 <= extirq && extirq <= NR_IRQS - MPFS_IRQ_EXT_START) { - modifyreg32(miebase + (4 * (extirq / 32)), 0, 1 << (extirq % 32)); + modifyreg32(iebase + (4 * (extirq / 32)), 0, 1 << (extirq % 32)); } else { diff --git a/arch/risc-v/src/mpfs/mpfs_irq_dispatch.c b/arch/risc-v/src/mpfs/mpfs_irq_dispatch.c index 486e2efc8b..c6c4be7cde 100755 --- a/arch/risc-v/src/mpfs/mpfs_irq_dispatch.c +++ b/arch/risc-v/src/mpfs/mpfs_irq_dispatch.c @@ -38,6 +38,8 @@ #include "hardware/mpfs_memorymap.h" #include "hardware/mpfs_plic.h" +#include "mpfs_plic.h" + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -71,18 +73,7 @@ void *riscv_dispatch_irq(uint64_t vector, uint64_t *regs) /* Firstly, check if the irq is machine external interrupt */ - uintptr_t hart_id = riscv_mhartid(); - uintptr_t claim_address; - - if (hart_id == 0) - { - claim_address = MPFS_PLIC_H0_MCLAIM; - } - else - { - claim_address = MPFS_PLIC_H1_MCLAIM + - ((hart_id - 1) * MPFS_PLIC_NEXTHART_OFFSET); - } + uintptr_t claim_address = mpfs_plic_get_claimbase(); if (irq == RISCV_IRQ_MEXT) { diff --git a/arch/risc-v/src/mpfs/mpfs_plic.c b/arch/risc-v/src/mpfs/mpfs_plic.c new file mode 100644 index 0000000000..98277ae05b --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_plic.c @@ -0,0 +1,130 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_plic.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "mpfs.h" +#include "mpfs_plic.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mpfs_plic_get_iebase + * + * Description: + * Context aware way to query PLIC interrupt enable base address + * + * Returned Value: + * Interrupt enable base address + * + ****************************************************************************/ + +uintptr_t mpfs_plic_get_iebase(void) +{ + uintptr_t iebase; + uintptr_t hart_id = riscv_mhartid(); + + if (hart_id == 0) + { + iebase = MPFS_PLIC_H0_MIE0; + } + else + { + iebase = MPFS_PLIC_H1_MIE0 + (hart_id - 1) * MPFS_HART_MIE_OFFSET; + } + + return iebase; +} + +/**************************************************************************** + * Name: mpfs_plic_get_claimbase + * + * Description: + * Context aware way to query PLIC interrupt claim base address + * + * Returned Value: + * Interrupt enable claim address + * + ****************************************************************************/ + +uintptr_t mpfs_plic_get_claimbase(void) +{ + uintptr_t claim_address; + uintptr_t hart_id = riscv_mhartid(); + + if (hart_id == 0) + { + claim_address = MPFS_PLIC_H0_MCLAIM; + } + else + { + claim_address = MPFS_PLIC_H1_MCLAIM + + (hart_id - 1) * MPFS_PLIC_NEXTHART_OFFSET; + } + + return claim_address; +} + +/**************************************************************************** + * Name: mpfs_plic_get_thresholdbase + * + * Description: + * Context aware way to query PLIC interrupt threshold base address + * + * Returned Value: + * Interrupt enable threshold address + * + ****************************************************************************/ + +uintptr_t mpfs_plic_get_thresholdbase(void) +{ + uintptr_t threshold_address; + uintptr_t hart_id = riscv_mhartid(); + + if (hart_id == 0) + { + threshold_address = MPFS_PLIC_H0_MTHRESHOLD; + } + else + { + threshold_address = MPFS_PLIC_H1_MTHRESHOLD + + (hart_id - 1) * MPFS_PLIC_NEXTHART_OFFSET; + } + + return threshold_address; +} diff --git a/arch/risc-v/src/mpfs/mpfs_plic.h b/arch/risc-v/src/mpfs/mpfs_plic.h new file mode 100644 index 0000000000..76d1d38294 --- /dev/null +++ b/arch/risc-v/src/mpfs/mpfs_plic.h @@ -0,0 +1,73 @@ +/**************************************************************************** + * arch/risc-v/src/mpfs/mpfs_plic.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISC_V_SRC_MPFS_MPFS_PLIC_H +#define __ARCH_RISC_V_SRC_MPFS_MPFS_PLIC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: mpfs_plic_get_iebase + * + * Description: + * Context aware way to query PLIC interrupt enable base address + * + * Returned Value: + * Interrupt enable base address + * + ****************************************************************************/ + +uintptr_t mpfs_plic_get_iebase(void); + +/**************************************************************************** + * Name: mpfs_plic_get_claimbase + * + * Description: + * Context aware way to query PLIC interrupt claim base address + * + * Returned Value: + * Interrupt enable claim address + * + ****************************************************************************/ + +uintptr_t mpfs_plic_get_claimbase(void); + +/**************************************************************************** + * Name: mpfs_plic_get_thresholdbase + * + * Description: + * Context aware way to query PLIC interrupt threshold base address + * + * Returned Value: + * Interrupt enable threshold address + * + ****************************************************************************/ + +uintptr_t mpfs_plic_get_thresholdbase(void); + +#endif /* __ARCH_RISC_V_SRC_MPFS_MPFS_PLIC_H */