rt-thread/bsp/phytium/libraries/standalone/drivers/gic/fgic/fgic.c

676 lines
22 KiB
C
Raw Normal View History

/*
* Copyright : (C) 2022 Phytium Information Technology, Inc.
* All Rights Reserved.
*
* This program is OPEN SOURCE software: you can redistribute it and/or modify it
* under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
* either version 1.0 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the Phytium Public License for more details.
*
*
* FilePath: fgic.c
* Date: 2022-03-28 09:30:23
* LastEditTime: 2022-03-28 09:30:24
* Description: This file is for the minimum required function implementations for this driver.
*
* Modify History:
* Ver   Who        Date         Changes
* ----- ------     --------    --------------------------------------
* 1.0 huanghe 2022/4/16 init commit
*/
#include "fgic.h"
#include "fgic_distributor.h"
#include "fgic_cpu_interface.h"
#include "fgic_redistributor.h"
#include "fgic_hw.h"
#include "ftypes.h"
#include "fkernel.h"
#include "fassert.h"
#include "fdebug.h"
#define FGIC_DEBUG_TAG "FGIC"
#define FGIC_ERROR(format, ...) FT_DEBUG_PRINT_E(FGIC_DEBUG_TAG, format, ##__VA_ARGS__)
#define FGIC_DEBUG_I(format, ...) FT_DEBUG_PRINT_I(FGIC_DEBUG_TAG, format, ##__VA_ARGS__)
#define FGIC_DEBUG_W(format, ...) FT_DEBUG_PRINT_W(FGIC_DEBUG_TAG, format, ##__VA_ARGS__)
#define FGIC_DEBUG_E(format, ...) FT_DEBUG_PRINT_E(FGIC_DEBUG_TAG, format, ##__VA_ARGS__)
#define FGIC_SPI_START_ID 32
#define FGIC_PPI_END_ID 31
#define FGIC_SGI_END_ID 15
#define FGIC_GICD_32_PER_REG 32
#define FGIC_GICD_16_PER_REG 16
#define FGIC_GICD_4_PER_REG 4
#define FGIC_INT_DEFAULT_PRI_X4 0xa0a0a0a0 /* 考虑到当前一般程序工作于EL1对于NS 或 S 安全状态 0x80 - 0xff 的优先级都有存在的可能性 */
#define FGIC_CPU_INTERFACE_DEFAULT_FILTER 0xFF
typedef enum
{
GICD_CTLR_RWP_WAIT = 0, /* Use GICD_CTLR for test */
GICR_CTLR_RWP_WAIT, /* Use GICR_CTLR for test */
} WAIT_RWP_MODE;
/**
* @name: FGicWaitRwp
* @msg: Wait for register write pending
* @param {uintptr} ctrl_base is a GICD_CTLR address
* @param {WAIT_RWP_MODE} wait_mode
* @return {*}
*/
static FError FGicWaitRwp(uintptr ctrl_base, WAIT_RWP_MODE wait_mode)
{
u32 rwp_mask;
u32 timeout_cnt = 0;
if (GICD_CTLR_RWP_WAIT == wait_mode)
{
rwp_mask = FGIC_GICD_CTLR_RWP_MASK;
}
else if (GICR_CTLR_RWP_WAIT == wait_mode)
{
rwp_mask = FGIC_GICR_CTLR_RWP_MASK;
}
else
{
FGIC_DEBUG_E(" wait_mode not in WAIT_RWP_MODE.");
return FGIC_CTLR_ERR_TYPE;
}
while (FGIC_READREG32(ctrl_base, 0) & rwp_mask)
{
if (timeout_cnt ++ >= 0xffffff)
{
FGIC_DEBUG_E(" Wait rwp timeout.");
return FGIC_CTLR_ERR_IN_GET;
}
}
return FGIC_SUCCESS;
}
/**
* @name: void FGicDistrubutiorInit(FGic *instance_p)
* @msg: Initialize Distrubutior
* @param {FGic} *instance_p is a pointer to the FGic instance.
*/
void FGicDistrubutiorInit(FGic *instance_p)
{
FASSERT(instance_p);
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
u32 max_ints_mun, int_id, int_index;
uintptr dis_base = instance_p->config.dis_base;
max_ints_mun = instance_p->max_spi_num;
/* Disable the distributor */
FGIC_WRITEREG32(dis_base, FGIC_GICD_CTLR_OFFSET, 0);
FASSERT(FGicWaitRwp(dis_base + FGIC_GICD_CTLR_OFFSET, GICD_CTLR_RWP_WAIT) == FGIC_SUCCESS);
if (instance_p->security == ONE_NS_SECURITY_STATE)
{
/* Make GICD_CTLR.DS = 1 ,Non-secure accesses are permitted to access and modify registers that control Group 0 interrupts */
FGIC_SETBIT(dis_base, FGIC_GICD_CTLR_OFFSET, FGIC_GICD_CTLR_DS_MASK);
FASSERT(FGIC_READREG32(dis_base, FGIC_GICD_CTLR_OFFSET) & FGIC_GICD_CTLR_DS_MASK);
}
/* 关闭所有中断并将中断分组默认为group 1 */
for (int_id = FGIC_SPI_START_ID; int_id < max_ints_mun; int_id += FGIC_GICD_32_PER_REG)
{
int_index = int_id / FGIC_GICD_32_PER_REG;
/* Disables forwarding of the corresponding interrupt. */
FGIC_GICD_ICENABLER_WRITE_N_MASK(dis_base, int_id, FGIC_GICD_ICENABLER_DEFAULT_MASK);
/* Changes the state of the corresponding interrupt from pending to inactive, or from active and pending to active. */
FGIC_GICD_ICPENDR_WRITE_N_MASK(dis_base, int_id, FGIC_GICD_ICPENDR_DEFAULT_MASK);
if (instance_p->security == ONE_NS_SECURITY_STATE)
{
FGIC_GICD_IGROUPR_WRITE_N_MASK(dis_base, int_id, FGIC_GICD_ICPENDR_DEFAULT_MASK);
}
else
{
FGIC_GICD_IGROUPR_WRITE_N_MASK(dis_base, int_id, FGIC_GICD_ICPENDR_DEFAULT_MASK);
}
FGIC_GICD_IGRPMODR_WRITE_N_MASK(dis_base, int_id, FGIC_GICD_IGRPMODR_DEFAULT_MASK);
}
FASSERT(FGicWaitRwp(dis_base + FGIC_GICD_CTLR_OFFSET, GICD_CTLR_RWP_WAIT) == FGIC_SUCCESS);
for (int_id = FGIC_SPI_START_ID; int_id < max_ints_mun; int_id += FGIC_GICD_4_PER_REG)
{
FGIC_GICD_IPRIORITYR_WRITE_N_MASK(dis_base, int_id, FGIC_INT_DEFAULT_PRI_X4);
}
for (int_id = FGIC_SPI_START_ID; int_id < max_ints_mun; int_id += FGIC_GICD_16_PER_REG)
{
FGIC_GICD_ICFGR_WRITE_N_MASK(dis_base, int_id, 0); /* level-sensitive */
}
if (instance_p->security == ONE_NS_SECURITY_STATE)
{
FGIC_GICD_CTLR_WRITE(dis_base, GICD_CTLR_BIT_ARE_S | GICD_CTLR_ENABLE_GRP1_NS);
}
else
{
FGIC_GICD_CTLR_WRITE(dis_base, GICD_CTLR_BIT_ARE_NS | GICD_CTLR_ENABLE_GRP1_NS);
}
}
/**
* @name: FError FGicRedistrubutiorInit(FGic *instance_p)
* @msg: Initialize Redistrubutior
* @param {FGic} *instance_p is a pointer to the FGic instance.
* @return {FError} FGIC_SUCCESS is success ,FGIC_ERR_IN_TIMEOUT is timeout
*/
FError FGicRedistrubutiorInit(FGic *instance_p)
{
FASSERT(instance_p);
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
s32 int_id ;
u32 timeout = 0;
uintptr redis_base = instance_p->redis_base;
uintptr sgi_base = instance_p->redis_base + FGIC_GICR_SGI_BASE_OFFSET;
/* Clear processor sleep and wait till childasleep is cleard */
FGIC_GICR_WAKER_CLEAR_BIT(redis_base, FGIC_GICR_WAKER_PROCESSOR_SLEEP_MASK);
while (FGIC_GICR_WAKER_READ(redis_base) & FGIC_GICR_WAKER_CHILDREN_ASLEEP_MASK)
{
timeout++;
if (timeout >= 0xfffffff)
{
return FGIC_ERR_IN_TIMEOUT;
}
}
FASSERT(FGicWaitRwp(redis_base, GICR_CTLR_RWP_WAIT) == FGIC_SUCCESS);
FGIC_GICR_ICENABLER0_WRITE(sgi_base, FGIC_GICR_ICENABLER0_DEFAULT_MASK); /* Disable all sgi ppi */
/* Clear pending */
FGIC_GICR_ICPENDR0_WRITE(sgi_base, FGIC_GICR_ICPENDR0_DEFAULT_MASK);
/* Set sgi ppi route to different security group */
if (instance_p->security == ONE_NS_SECURITY_STATE)
{
FGIC_GICR_IGROUPR0_WRITE(sgi_base, FGIC_GICR_IGROUPR0_DEFAULT_MASK);
}
else
{
FGIC_GICR_IGROUPR0_WRITE(sgi_base, FGIC_GICR_IGROUPR0_DEFAULT_MASK);
}
FGIC_GICR_IGRPMODR0_WRITE(sgi_base, FGIC_GICR_IGRPMODR0_DEFAULT_MASK);
/* 默认所有优先级为0xa0 */
for (int_id = 0; int_id < FGIC_SPI_START_ID; int_id += FGIC_GICD_4_PER_REG)
{
FGIC_GICR_IPRIORITYR_WRITE(sgi_base, int_id, FGIC_INT_DEFAULT_PRI_X4);
}
FGIC_GICR_ICFGR0_WRITE(sgi_base, 0); /* set level-sensitive */
FGIC_GICR_ICFGR1_WRITE(sgi_base, 0);
return FGIC_SUCCESS;
}
/**
* @name: void FGicCpuInterfaceInit(void)
* @msg: Initialize Cpu interface of current core
*/
void FGicCpuInterfaceInit(void)
{
u32 reg;
reg = FGicGetICC_SRE_EL1();
if (!(reg & GICC_SRE_SRE))
{
reg |= (GICC_SRE_SRE | GICC_SRE_DFB | GICC_SRE_DIB);
FGicSetICC_SRE_EL1(reg);
reg = FGicGetICC_SRE_EL1();
FASSERT(reg & GICC_SRE_SRE);
}
FGicSetICC_PMR(FGIC_CPU_INTERFACE_DEFAULT_FILTER);
FGicEnableGroup1_EL1();
FGicSetICC_CTLR_EL1(GICC_CTLR_CBPR); /* ICC_BPR0_EL1 determines the preemption group for both Group 0 and Group 1 interrupts. */
}
/**
* @name: FError FGicCfgInitialize(FGic *instance_p, const FGicConfig *input_config_p , uintptr redis_base)
* @msg: Initialize the GIC driver instance based on the incoming configuration
* @param {FGic} *instance_p is a pointer to the FGic instance.
* @param {FGicConfig} *input_config_p Configuration items that need to be applied in the instance
* @param {uintptr} redis_base is the redistributor adress of current core
* @return {*}
*/
FError FGicCfgInitialize(FGic *instance_p, const FGicConfig *input_config_p, uintptr redis_base)
{
u32 max_ints_mun;
uintptr dis_base;
FASSERT(instance_p && input_config_p);
instance_p->config = *input_config_p;
instance_p->redis_base = redis_base ;
instance_p->is_ready = FT_COMPONENT_IS_READY;
dis_base = instance_p->config.dis_base;
max_ints_mun = FGIC_READREG32(dis_base, FGIC_GICD_TYPER_OFFSET);
max_ints_mun &= FGIC_GICD_TYPER_ITLINESNUMBER_MASK ;
max_ints_mun = ((max_ints_mun + 1) << 5) - 1; /* If the value of this field is N, the maximum SPI INTID is 32(N+1) minus 1. */
instance_p->max_spi_num = max_ints_mun;
return FGIC_SUCCESS;
}
/**
* @name: FError FGicIntEnable(FGic *instance_p,s32 int_id)
* @msg: Enables the interrupt function based on the interrupt number
* @param {FGic} *instance_p is a pointer to the FGic instance.
* @param {s32} int_id is interrupt id
* @return {*}
*/
FError FGicIntEnable(FGic *instance_p, s32 int_id)
{
FASSERT(instance_p);
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
if (int_id > instance_p->max_spi_num)
{
FGIC_DEBUG_E("int_id is over max spi num for FGicIntEnable.");
return FGIC_CTLR_ERR_NUM;
}
if (int_id <= FGIC_PPI_END_ID)
{
uintptr redis_base = instance_p->redis_base;
FGicEnablePrivateInt(redis_base, int_id);
}
else
{
uintptr dis_base = instance_p->config.dis_base;
FGicEnableSPI(dis_base, int_id);
}
return FGIC_SUCCESS ;
}
/**
* @name: FError FGicIntEnable(FGic *instance_p,s32 int_id)
* @msg: Disable the interrupt function based on the interrupt number
* @param {FGic} *instance_p is a pointer to the FGic instance.
* @param {s32} int_id is interrupt id
*/
FError FGicIntDisable(FGic *instance_p, s32 int_id)
{
FASSERT(instance_p);
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
if (int_id > instance_p->max_spi_num)
{
FGIC_DEBUG_E("int_id is over max spi num for FGicIntDisable.");
return FGIC_CTLR_ERR_NUM;
}
if (int_id <= FGIC_PPI_END_ID)
{
uintptr redis_base = instance_p->redis_base;
FGicDisablePrivateInt(redis_base, int_id);
}
else
{
uintptr dis_base = instance_p->config.dis_base;
FGicDisableSPI(dis_base, int_id);
}
return FGIC_SUCCESS ;
}
/**
* @name: FError FGicSetPriority(FGic *instance_p,s32 int_id,u32 priority)
* @msg: Sets the current interrupt priority value based on the interrupt number
* @param {FGic} *instance_p is a pointer to the FGic instance.
* @param {s32} int_id is interrupt id
* @param {u32} priority is priority value ,valid bit is bit[0:7]
* @return {*}
*/
FError FGicSetPriority(FGic *instance_p, s32 int_id, u32 priority)
{
FASSERT(instance_p);
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
if (int_id > instance_p->max_spi_num)
{
FGIC_DEBUG_E("int_id is over max spi num for FGicSetPriority.");
return FGIC_CTLR_ERR_IN_GET;
}
if (int_id <= FGIC_PPI_END_ID)
{
uintptr redis_base = instance_p->redis_base;
FGicSetPrivatePriority(redis_base, int_id, priority);
}
else
{
uintptr dis_base = instance_p->config.dis_base;
FGicSetSpiPriority(dis_base, int_id, priority);
}
return FGIC_SUCCESS ;
}
/**
* @name: u32 FGicGetPriority(FGic *instance_p,s32 int_id)
* @msg: Gets the current interrupt priority value based on the interrupt number
* @param {FGic} *instance_p is a pointer to the FGic instance
* @param {s32} int_id is interrupt id
* @return {u32} priority value ,valid bit is bit[0:7]
*/
u32 FGicGetPriority(FGic *instance_p, s32 int_id)
{
u32 priority;
FASSERT(instance_p);
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
if (int_id > instance_p->max_spi_num)
{
FGIC_DEBUG_E("int_id is over max spi num for FGicGetPriority.");
return (u32)FGIC_CTLR_ERR_IN_GET;
}
if (int_id <= FGIC_PPI_END_ID)
{
uintptr redis_base = instance_p->redis_base;
priority = FGicGetPrivatePriority(redis_base, int_id);
}
else
{
uintptr dis_base = instance_p->config.dis_base;
priority = FGicGetSpiPriority(dis_base, int_id);
}
return priority ;
}
/**
* @name: FError FGicSetTriggerLevel(FGic *instance_p,s32 int_id,TRIGGER_LEVEL trigger_way)
* @msg: Sets the interrupt triggering mode based on the current interrupt number
* @param {FGic} *instance_p is a pointer to the FGic instance
* @param {s32} int_id is interrupt id
* @param {TRIGGER_LEVEL} trigger_way is trigger mode
* @return {*}
*/
FError FGicSetTriggerLevel(FGic *instance_p, s32 int_id, TRIGGER_LEVEL trigger_way)
{
FASSERT(instance_p);
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
if (int_id > instance_p->max_spi_num)
{
FGIC_DEBUG_E("int_id is over max spi num for FGicSetTriggerLevel.");
return FGIC_CTLR_ERR_IN_SET;
}
if (int_id <= FGIC_SGI_END_ID)
{
uintptr redis_base = instance_p->redis_base;
FGicSetSgiLevel(redis_base, int_id, trigger_way);
}
else if (int_id <= FGIC_PPI_END_ID)
{
uintptr redis_base = instance_p->redis_base;
FGicSetPpiLevel(redis_base, int_id, trigger_way);
}
else
{
uintptr dis_base = instance_p->config.dis_base;
FGicSetSpiLevel(dis_base, int_id, trigger_way);
}
return FGIC_SUCCESS ;
}
/**
* @name: u32 FGicGetTriggerLevel(FGic *instance_p,s32 int_id)
* @msg: Gets the interrupt triggering mode based on the current interrupt number
* @param {FGic} *instance_p is a pointer to the FGic instance
* @param {s32} int_id is interrupt id
* @return {u32} triggering mode
*/
u32 FGicGetTriggerLevel(FGic *instance_p, s32 int_id)
{
u32 trigger_way;
FASSERT(instance_p);
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
if (int_id > instance_p->max_spi_num)
{
FGIC_DEBUG_E("int_id is over max spi num for FGicGetTriggerLevel.");
return (u32)FGIC_CTLR_ERR_IN_GET;
}
if (int_id <= FGIC_SGI_END_ID)
{
uintptr redis_base = instance_p->redis_base;
trigger_way = FGicGetSgiLevel(redis_base, int_id);
}
else if (int_id <= FGIC_PPI_END_ID)
{
uintptr redis_base = instance_p->redis_base;
trigger_way = FGicGetPpiLevel(redis_base, int_id);
}
else
{
uintptr dis_base = instance_p->config.dis_base;
trigger_way = FGicGetSpiLevel(dis_base, int_id);
}
return trigger_way ;
}
/**
* @name: FGicSetSpiAffinityRouting
* @msg: Set intermediate routing information for a specific SPI interrupt
* @param {FGic} *instance_p is a pointer to the FGic instance.
* @param {u32} int_id is interrupt vector for spi
* @param {SPI_ROUTING_MODE} route_mode is the interrupt routing mode.
* @param {u64} affinity is the affinity level format is
* |--------[bit39-32]-------[bit23-16]-------------[bit15-8]--------[bit7-0]
* |--------Affinity level3-----Affinity level2-----Affinity level1---Affinity level0
* @return {*}
*/
FError FGicSetSpiAffinityRouting(FGic *instance_p, s32 int_id, SPI_ROUTING_MODE route_mode, u64 affinity)
{
FASSERT(instance_p);
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
uintptr dis_base = instance_p->config.dis_base;
if ((int_id > instance_p->max_spi_num) || (int_id <= FGIC_PPI_END_ID))
{
FGIC_DEBUG_E("int_id %d is out of range.", int_id);
return FGIC_CTLR_ERR_IN_SET;
}
FGicSetSpiRoute(dis_base, int_id, route_mode, affinity);
return FGIC_SUCCESS;
}
/**
* @name: FGicGetAffinityRouting
* @msg: Get intermediate routing information for a specific SPI interrupt
* @param {FGic} *instance_p is a pointer to the FGic instance.
* @param {u32} int_id is interrupt vector for spi
* @param {SPI_ROUTING_MODE} *route_mode_p is a pointer to get interrupt routing mode.
* @param {u64} *affinity_p is pointer to get affinity level ,format is
* |--------[bit39-32]-------[bit23-16]-------------[bit15-8]--------[bit7-0]
* |--------Affinity level3-----Affinity level2-----Affinity level1---Affinity level0
* @return {FError}
*/
FError FGicGetAffinityRouting(FGic *instance_p, s32 int_id, SPI_ROUTING_MODE *route_mode_p, u64 *affinity_p)
{
FASSERT(instance_p);
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
FASSERT(route_mode_p != NULL);
FASSERT(affinity_p != NULL);
uintptr dis_base = instance_p->config.dis_base;
u64 reg;
if ((int_id > instance_p->max_spi_num) || (int_id <= FGIC_PPI_END_ID))
{
FGIC_DEBUG_E("int_id %d is out of range.", int_id);
return (u32)FGIC_CTLR_ERR_IN_GET;
}
reg = FGicGetSpiRoute(dis_base, int_id);
*route_mode_p = reg & SPI_ROUTING_TO_ANY;
*affinity_p = reg & FGIC_GICD_IROUTER_AFFINITY_MASK;
return FGIC_SUCCESS;
}
/**
* @name: FGicGenerateSgi
* @msg: This interface is used for software generated interrupts
* @param {FGic} *instance_p is a pointer to the FGic instance.
* @param {u32} int_id is interrupt vector for spi
* @param {u32} target_list is the set of PEs for which SGI interrupts will be generated. Each bit corresponds to the PE within a cluster with an Affinity 0 value equal to the bit number.
* @param {SGI_ROUTING_MODE} routing_mode is Interrupt Routing Mode.
* @param {u64} affinity is the affinity level ,format is
* |--------[bit55-48]-------[bit39-32]-------------[bit23-16]
* |--------Affinity level3-----Affinity level2-----Affinity level1
* @return {*}
*/
FError FGicGenerateSgi(FGic *instance_p, s32 int_id, u32 target_list, SGI_ROUTING_MODE routing_mode, u64 affinity)
{
FASSERT(instance_p);
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
if (int_id > FGIC_SGI_END_ID)
{
FGIC_DEBUG_E("int_id %d is out of range.", int_id);
return FGIC_CTLR_ERR_IN_SET;
}
FGicSetICC_SGI1R((int_id & FGIC_ICC_SGI1R_INTID_MASK) << 24, target_list, routing_mode, affinity);
return FGIC_SUCCESS;
}
/**
* @name: FGicDeactionInterrupt
* @msg: Deactive Interruption of the current active state
* @param {FGic} *instance_p is a pointer to the FGic instance.
* @param {s32} int_id is interrupt id
*/
void FGicDeactionInterrupt(FGic *instance_p, s32 int_id)
{
FASSERT(instance_p);
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
FGicSetICC_EOIR1(int_id);
}
/**
* @name: FGicAcknowledgeInt
* @msg: Acknowledge pending interrupt
* @param {FGic} *instance_p is a pointer to the FGic instance.
* @return {s32} interrupt id
*/
s32 FGicAcknowledgeInt(FGic *instance_p)
{
FASSERT(instance_p);
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
return FGicGetICC_APR1();
}
/**
* @name: FGicSetPriorityFilter
* @msg: By setting the parameter of ICC_PMR, the interrupt range that the interrupt controller can respond to is determined
* @param {FGic} *instance_p is a pointer to the FGic instance.
* @param {u32} priority_mask . If the priority of an interrupt is lower than the value indicated by this field, the interface signals the interrupt to the PE.
* The reference values of priority_mask are as follows
* |priority_mask---------------256-------254--------252------248-------240
* |Implemented priority bits---[7:0]----[7:1]------[7:2]-----[7:3]-----[7:4]
* |priority the growing steps--any-----even value----4---------8--------16
*/
void FGicSetPriorityFilter(FGic *instance_p, u32 priority_mask)
{
FASSERT(instance_p);
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
FGicSetICC_PMR(priority_mask);
}
/**
* @name: FGicGetPriorityFilter
* @msg: Gets the current priority filtering value
* @param {FGic} *instance_p is a pointer to the FGic instance.
* @return {u32} Priority Mask for the CPU interface . If the priority of an interrupt is lower than the value
* indicated by this field, the interface signals the interrupt to the PE.
* The reference values of priority_mask are as follows
* |return value----------------256-------254--------252------248-------240
* |Implemented priority bits---[7:0]----[7:1]------[7:2]-----[7:3]-----[7:4]
* |priority the growing steps--any-----even value----4---------8--------16
*/
u32 FGicGetPriorityFilter(FGic *instance_p)
{
FASSERT(instance_p);
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
return FGicGetICC_PMR();
}
/**
* @name: FGicGetPriorityGroup
* @msg: Get Binary point value
* @param {FGic} *instance_p is a pointer to the FGic instance.
* @return {u32} The relationship between Binary point value and grouping is as follows
* |return value----------------0-------1--------2------3-------4------5------6-------7
* |Group priority field------[---]----[7:1]---[7:2]--[7:3]---[7:4]---[7:5]---[7:6]---[7]
* |Subpriority field---------[---]-----[0]----[1:0]--[2:0]---[3:0]---[4:0]---[5:0]---[6:0]
*/
u32 FGicGetPriorityGroup(FGic *instance_p)
{
FASSERT(instance_p);
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
return FGicGetICC_BPR1();
}
/**
* @name: FGicSetPriorityGroup
* @msg: Sets the value of the current group priority
* @param {FGic} *instance_p is a pointer to the FGic instance.
* @param {u32} binary_point : The value of this field controls how the 8-bit interrupt priority field is split into a group priority field
* The relationship between binary_point value and grouping is as follows
* |binary_point----------------0-------1--------2------3-------4------5------6-------7
* |Group priority field------[---]----[7:1]---[7:2]--[7:3]---[7:4]---[7:5]---[7:6]---[7]
* |Subpriority field---------[---]-----[0]----[1:0]--[2:0]---[3:0]---[4:0]---[5:0]---[6:0]
*/
void FGicSetPriorityGroup(FGic *instance_p, u32 binary_point)
{
FASSERT(instance_p);
FASSERT(instance_p->is_ready == FT_COMPONENT_IS_READY);
FGicSetICC_BPR1(binary_point);
}