This commit is contained in:
2025-12-24 17:21:08 +09:00
parent a96323de19
commit 96dc62d8dc
2302 changed files with 455822 additions and 0 deletions

View File

@@ -0,0 +1,417 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright 2018-2023 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/
/*******************************************************************************
* DESCRIPTION : GIC Control Function
******************************************************************************/
/******************************************************************************
* @file gic.h
* - Version : 0.04
* @brief Controls GIC-600 registers and interrupts.
* .
*****************************************************************************/
/******************************************************************************
* History : DD.MM.YYYY Version Description
* : 02.08.2022 0.01 First Release
* : 20.09.2022 0.02 Set ChildrenAsleep of GICR_WAKER to 1 and end processing
* : 31.10.2022 0.03 License notation change.
* : 04.04.2023 0.04 Removed stdio.h.
*****************************************************************************/
#ifndef GIC_H
#define GIC_H
/*******************************************************************************
** Include Section **
*******************************************************************************/
#include <stdint.h>
/*******************************************************************************
** Version Information **
*******************************************************************************/
/*******************************************************************************
** Global Symbols **
*******************************************************************************/
/* GIC base */
#define GICD_BASE (0xF1000000UL)
#define GICR_BASE (GICD_BASE + 0x60000U)
/* Generic Interrupt Controller Distributor (GICD) */
#define GICD_CTLR *((volatile uint32_t *)(GICD_BASE + 0x000U))
#define GICD_IGROUPR(n) *((volatile uint32_t *)(GICD_BASE + 0x080U + 4U*(n)))
#define GICD_ISENABLER(n) *((volatile uint32_t *)(GICD_BASE + 0x100U + 4U*(n)))
#define GICD_ICENABLER(n) *((volatile uint32_t *)(GICD_BASE + 0x180U + 4U*(n)))
#define GICD_ISPENDR(n) *((volatile uint32_t *)(GICD_BASE + 0x200U + 4U*(n)))
#define GICD_ICPENDR(n) *((volatile uint32_t *)(GICD_BASE + 0x280U + 4U*(n)))
#define GICD_IPRIORITYR(n) *((volatile uint32_t *)(GICD_BASE + 0x400U + 4U*(n)))
#define GICD_ICFGR(n) *((volatile uint32_t *)(GICD_BASE + 0xC00U + 4U*(n)))
#define GICD_IGRPMODR(n) *((volatile uint32_t *)(GICD_BASE + 0xD00U + 4U*(n)))
#define GICD_IROUTER(n) *((volatile uint64_t *)(GICD_BASE + 0x6000U + 8U*(n)))
/* Generic Interrupt Controller Redistributor (GICR) */
#define GICR_CTLR *((volatile uint32_t *)(GICR_BASE + 0x0000U))
#define GICR_WAKER *((volatile uint32_t *)(GICR_BASE + 0x0014U))
#define GICR_PWRR *((volatile uint32_t *)(GICR_BASE + 0x0024U))
#define CHILDREN_ASLEEP (1U << 2U)
#define PROCESSOR_SLEEP (1U << 1U)
#define RDPOWER_DOWN (1U << 0U)
/*******************************************************************************
** Global Data Types **
*******************************************************************************/
/*******************************************************************************
** Function Prototypes **
*******************************************************************************/
/*******************************************************************************
** Macro **
*******************************************************************************/
/*******************************************************************************
* Definitions for CPU system register interface to GICv3
******************************************************************************/
/* ICC_SRE_EL3 */
#define ICC_SRE_EN_BIT (8U)
#define ICC_SRE_DIB_BIT (4U)
#define ICC_SRE_DFB_BIT (2U)
#define ICC_SRE_SRE_BIT (1U)
/* SCR_EL3 */
#define SCR_NS_BIT (1U)
/* Affinity Leve mask value */
#define AFFINITY0_MASK (0xFFU)
#define AFFINITY1_MASK (0xFF00U)
#define AFFINITY2_MASK (0xFF0000U)
#define AFFINITY3_MASK (0xFF00000000U)
#define IRM_OFF (0x80000000U)
/* Get ICC_IAR0 */
static inline uint64_t get_ICC_IAR0(void)
{
uint64_t value = 0U;
__asm__ volatile("mrs %0, S3_0_c12_c8_0" : "=r" (value));
return value;
}
/* Set ICC_PMR */
static inline void set_ICC_PMR(uint64_t value)
{
__asm__ volatile ("msr S3_0_C4_C6_0, %0" :: "r" (value));
}
/* Set ICC_IGRPEN0 */
static inline void set_ICC_IGRPEN0(uint64_t value)
{
__asm__ volatile ("msr S3_0_c12_c12_6, %0" :: "r" (value));
}
/* Set ICC_SRE_EL1 */
static inline void set_ICC_SRE_EL1(uint64_t value)
{
__asm__ volatile ("msr S3_0_C12_C12_5, %0" :: "r" (value));
}
/* Get ICC_SRE_EL3 */
static inline uint64_t get_ICC_SRE_EL3(void)
{
uint64_t value = 0U;
__asm__ volatile("mrs %0, S3_6_C12_C12_5" : "=r" (value));
return value;
}
/* Set ICC_SRE_EL3 */
static inline void set_ICC_SRE_EL3(uint64_t value)
{
__asm__ volatile ("msr S3_6_C12_C12_5, %0" :: "r" (value));
}
/* Get MPIDR_EL1 */
static inline uint64_t get_MPIDR_EL1(void)
{
uint64_t value = 0U;
__asm__ volatile("mrs %0, mpidr_el1" : "=r" (value));
return value;
}
/* ISB */
static inline void GIC_isb(void)
{
__asm__ volatile ("isb");
}
/* Enable the interrupt distributor using the GIC's CTLR register */
static inline void GIC_EnableDistributor(void)
{
GICD_CTLR |= 0x31U;
}
/* Disable the interrupt distributor using the GIC's CTLR register */
static inline void GIC_DisableDistributor(void)
{
GICD_CTLR &= 0xFFFFFFFEU;
}
/* Set the interrupt enable from the GIC's ISENABLER register */
static inline void GIC_SetEnable(uint32_t intid, uint32_t value)
{
uint32_t reg = GICD_ISENABLER(intid / 32U);
uint32_t shift = (intid % 32U);
reg &= (~(1U << shift));
reg |= ( (value & 1U) << shift);
GICD_ISENABLER(intid / 32U) = reg;
}
/* Set the interrupt disable from the GIC's ICENABLER register */
static inline void GIC_SetClearEnable(uint32_t intid, uint32_t value)
{
uint32_t reg = GICD_ICENABLER(intid / 32U);
uint32_t shift = (intid % 32U);
reg &= (~(1U << shift));
reg |= ( (value & 1U) << shift);
GICD_ICENABLER(intid / 32U) = reg;
}
/* Sets the interrupt configuration using GIC's ICFGR register */
static inline void GIC_SetConfiguration(uint32_t intid, uint32_t int_config)
{
uint32_t icfgr = GICD_ICFGR(intid / 16U);
uint32_t shift = (intid % 16U) << 1U;
icfgr &= (~(3U << shift));
icfgr |= ( int_config << shift);
GICD_ICFGR(intid / 16U) = icfgr;
}
/* Set the priority for the given interrupt in the GIC's IPRIORITYR register */
static inline void GIC_SetPriority(uint32_t intid, uint32_t priority)
{
uint32_t mask = GICD_IPRIORITYR(intid / 4U);
uint32_t shift = ((intid % 4U) * 8U);
mask &= (~(0xFFU << shift));
mask |= ( (priority & 0xFFU) << shift);
GICD_IPRIORITYR(intid / 4U) = mask;
}
/* Set the interrupt group from the GIC's IGROUPR register */
static inline void GIC_SetGroup(uint32_t intid, uint32_t group)
{
uint32_t igroupr = GICD_IGROUPR(intid / 32U);
uint32_t shift = (intid % 32U);
igroupr &= (~(1U << shift));
igroupr |= ( (group & 1U) << shift);
GICD_IGROUPR(intid / 32U) = igroupr;
}
/* Set the interrupt group from the GIC's IGRPMODR register */
static inline void GIC_SetGrpMode(uint32_t intid, uint32_t mode)
{
uint32_t imode = GICD_IGRPMODR(intid / 32U);
uint32_t shift = (intid % 32U);
imode &= (~(1U << shift));
imode |= ( (mode & 1U) << shift);
GICD_IGRPMODR(intid / 32U) = imode;
}
/* Set the interrupt routing from the GIC's IROUTER register */
static inline void GIC_SetRouter(uint32_t intid)
{
uint64_t affinity = 0U;
/* Get Affinity level */
affinity = get_MPIDR_EL1();
affinity &= (AFFINITY0_MASK | AFFINITY1_MASK | AFFINITY2_MASK | AFFINITY3_MASK);
/* Interrupt routing mode bit OFF */
affinity &= (~(IRM_OFF));
GICD_IROUTER(intid) = affinity;
}
/* Get power register value from the GIC's GICR_PWRR register */
static inline uint32_t GIC_Getpwwr(void)
{
return (GICR_PWRR);
}
/* Set power register value from the GIC's GICR_PWRR register */
static inline void GIC_Setpwwr(uint32_t set_value)
{
GICR_PWRR = set_value;
}
/* Get power management cotrol register from the GIC's GICR_WAKER register */
static inline uint32_t GIC_Getwaker(void)
{
return (GICR_WAKER);
}
/* Set power management cotrol register from the GIC's GICR_WAKER register */
static inline void GIC_Setwaker(uint32_t set_value)
{
GICR_WAKER = set_value;
}
/* Enables the given interrupt using GIC's ISENABLER register */
static inline void GIC_EnableFIQ(uint32_t intid)
{
/* Disable interrupt forwarding */
GIC_DisableDistributor();
/* Set level-sensitive */
GIC_SetConfiguration(intid, 0U);
/* Set priority */
GIC_SetPriority(intid, 0U);
/* Set group 0 (secure) */
GIC_SetGroup(intid, 0U);
/* Set group 0 (secure) */
GIC_SetGrpMode(intid, 0U);
/* Enable distributor */
GIC_EnableDistributor();
/* Enable the SPI interrupt */
GIC_SetEnable(intid, 1U);
/* Set the interrupt routing */
GIC_SetRouter(intid);
}
/* Enable the interrupt redistributor wakeup */
static inline void GIC_WakeupRedistributor(void)
{
uint32_t get_value = 0U;
uint32_t set_value = 0U;
get_value = GIC_Getpwwr();
set_value = get_value & ~(RDPOWER_DOWN);
GIC_Setpwwr(set_value);
get_value = GIC_Getwaker();
set_value = get_value & ~(PROCESSOR_SLEEP);
GIC_Setwaker(set_value);
do
{
get_value = GIC_Getwaker();
}while((get_value & CHILDREN_ASLEEP) == CHILDREN_ASLEEP);
}
/* Enable the CPU's interrupt interface */
static inline void GIC_EnableInterface(void)
{
uint64_t reg = 0U;
uint64_t icc_sre_el3 = 0U;
/* Disable the legacy interrupt bypass */
icc_sre_el3 = ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT | ICC_SRE_EN_BIT | ICC_SRE_SRE_BIT;
reg = get_ICC_SRE_EL3();
set_ICC_SRE_EL3(reg | icc_sre_el3);
set_ICC_SRE_EL1(ICC_SRE_SRE_BIT);
GIC_isb();
set_ICC_IGRPEN0(1U); /* enable interface grp0 */
GIC_isb();
}
/* Disable the CPU's interrupt interface */
static inline void GIC_DisableInterface(uint32_t intid)
{
uint32_t get_value = 0U;
uint32_t set_value = 0U;
/* Clear Enable the SPI interrupt */
GIC_SetClearEnable(intid, 1U);
/* Set ChildrenAsleep of GICR_WAKER to 1 and end processing */
get_value = GIC_Getwaker();
set_value = get_value | PROCESSOR_SLEEP;
GIC_Setwaker(set_value);
do
{
get_value = GIC_Getwaker();
}while((get_value & CHILDREN_ASLEEP) != CHILDREN_ASLEEP);
}
/* Read the CPU's IAR register */
static inline uint32_t GIC_AcknowledgePending(void)
{
return (uint32_t)(get_ICC_IAR0());
}
/* Set the interrupt priority mask using CPU's PMR register */
static inline void GIC_SetInterfacePriorityMask(uint64_t priority)
{
/* Specify F8. 32 priority levels are bit0-2 invalid */
set_ICC_PMR(priority << 3U);
}
/* Initialize and enable the GIC */
static inline void GIC_Enable(void)
{
GIC_WakeupRedistributor();
/* Enable interface */
GIC_EnableInterface();
/* Set priority mask */
GIC_SetInterfacePriorityMask(0xFFUL);
}
/*******************************************************************************
** Function **
*******************************************************************************/
/* Interrupt configuration */
#define Interrupt_Config(void) GIC_Enable(void)
/* Enable */
#define Interrupt_Enable(intid) GIC_EnableFIQ((uint32_t)intid)
/* Disable */
#define Interrupt_Disable(intid) GIC_DisableInterface((uint32_t)intid)
#endif /* GIC_H */
/*******************************************************************************
** End of File **
*******************************************************************************/