CIDU Functions
General
- __STATIC_FORCEINLINE uint32_t CIDU_GetCoreNum (void)
- __STATIC_FORCEINLINE uint32_t CIDU_GetIntNum (void)
-
CIDU_BASE __CIDU_BASEADDR
-
CIDU_RECEIVE_INTERRUPT_EN(core_id) (0x1U << core_id)
-
CIDU_CORE_INT_STATUS_OFS 0x0
-
CIDU_SEMAPHORE_OFS 0x80
-
CIDU_ICI_SHADOW_OFS 0x3FFC
-
CIDU_INT_INDICATOR_OFS 0x4000
-
CIDU_INT_MASK_OFS 0x8000
-
CIDU_CORE_NUM_OFS 0xC084
-
CIDU_INT_NUM_OFS 0xC090
-
CIDU_CORE_INT_STATUS_ADDR(n) (unsigned long)((CIDU_BASE) + (CIDU_CORE_INT_STATUS_OFS) + ((n) << 2))
-
CIDU_SEMAPHORE_ADDR(n) (unsigned long)((CIDU_BASE) + (CIDU_SEMAPHORE_OFS) + ((n) << 2))
-
CIDU_ICI_SHADOW_ADDR (unsigned long)((CIDU_BASE) + (CIDU_ICI_SHADOW_OFS))
-
CIDU_INT_INDICATOR_ADDR(n) (unsigned long)((CIDU_BASE) + (CIDU_INT_INDICATOR_OFS) + ((n) << 2))
-
CIDU_INT_MASK_ADDR(n) (unsigned long)((CIDU_BASE) + (CIDU_INT_MASK_OFS) + ((n) << 2))
-
CIDU_CORE_NUM_ADDR (unsigned long)((CIDU_BASE) + (CIDU_CORE_NUM_OFS))
-
CIDU_INT_NUM_ADDR (unsigned long)((CIDU_BASE) + (CIDU_INT_NUM_OFS))
-
CIDU_ICI_SEND_CORE_ID_POS 16
- group CIDU Functions
Functions that manage external interrupts, inter core interrupts and semaphores.
Nuclei provide Cluster Interrupt Distribution Unit (CIDU) for scenarios that a SMP system is designed for real time application or both Linux and real time application, and Nuclei processor core can optionally support CIDU. The CIDU is used to distribute external interrupts to the core’s ECLIC, also it provides Inter Core Interrupt (ICI) and Semaphores Mechanism. Its features are as follows:
Support up to 16 Cores in one cluster
Support up to 4096 external interrupts sources
Support up to 16 Inter Core Interrupts
Support 32 Semaphores
Defines
-
CIDU_BASE __CIDU_BASEADDR
-
CIDU_RECEIVE_INTERRUPT_EN(core_id) (0x1U << core_id)
Indicates the core can receive corresponding interrupt.
-
CIDU_CORE_INT_STATUS_OFS 0x0
Core n Inter Core Interrupt status register base offset.
-
CIDU_SEMAPHORE_OFS 0x80
Semaphore n register base offset.
-
CIDU_ICI_SHADOW_OFS 0x3FFC
ICI Interrupt source core ID and target core ID register offset.
-
CIDU_INT_INDICATOR_OFS 0x4000
External interrupt n indicator register base offset.
-
CIDU_INT_MASK_OFS 0x8000
External interrupt n mask (mask interrupt n to cores or not when interrupt n indicator on)register base offset.
-
CIDU_CORE_NUM_OFS 0xC084
Static configuration core num register offset.
-
CIDU_INT_NUM_OFS 0xC090
Static configuration external interrupt number register offset.
-
CIDU_CORE_INT_STATUS_ADDR(n) (unsigned long)((CIDU_BASE) + (CIDU_CORE_INT_STATUS_OFS) + ((n) << 2))
Core n Inter Core Interrupt status register address.
-
CIDU_SEMAPHORE_ADDR(n) (unsigned long)((CIDU_BASE) + (CIDU_SEMAPHORE_OFS) + ((n) << 2))
Semaphore n register address.
-
CIDU_ICI_SHADOW_ADDR (unsigned long)((CIDU_BASE) + (CIDU_ICI_SHADOW_OFS))
ICI Interrupt source core ID and target core ID register address.
-
CIDU_INT_INDICATOR_ADDR(n) (unsigned long)((CIDU_BASE) + (CIDU_INT_INDICATOR_OFS) + ((n) << 2))
External interrupt n indicator register address.
-
CIDU_INT_MASK_ADDR(n) (unsigned long)((CIDU_BASE) + (CIDU_INT_MASK_OFS) + ((n) << 2))
External interrupt n mask (mask interrupt n to cores or not when interrupt n indicator on)register address.
-
CIDU_CORE_NUM_ADDR (unsigned long)((CIDU_BASE) + (CIDU_CORE_NUM_OFS))
Static configuration core num register address.
-
CIDU_INT_NUM_ADDR (unsigned long)((CIDU_BASE) + (CIDU_INT_NUM_OFS))
Static configuration external interrupt number register address.
-
CIDU_ICI_SEND_CORE_ID_POS 16
Functions
- __STATIC_FORCEINLINE uint32_t CIDU_GetCoreNum (void)
Get core number in the cluster.
Indicate the static configuration core num in the cluster.
Remark
In a Nulcei multi-core system, each core has an identifiable serial number, the serial number starts from 0 and is continuous, also the number is static.
CORE_NUM register is read only.
- Returns:
core number configured
- __STATIC_FORCEINLINE uint32_t CIDU_GetIntNum (void)
Get external interrupt number.
Indicate the static configuration external interrupt number
Remark
INT_NUM register is read only.
- Returns:
interrupt number configured
External Interrupt Distribution Functions
- __STATIC_FORCEINLINE void CIDU_BroadcastExtInterrupt (uint32_t int_id, uint32_t to_cores)
- __STATIC_FORCEINLINE uint32_t CIDU_GetBroadcastModeStatus (uint32_t int_id)
- __STATIC_FORCEINLINE long CIDU_SetFirstClaimMode (uint32_t int_id, uint32_t core_id)
- __STATIC_FORCEINLINE void CIDU_ResetFirstClaimMode (uint32_t int_id)
- __STATIC_FORCEINLINE uint32_t CIDU_GetClaimStatus (uint32_t int_id)
- group External Interrupt Distribution Functions
Functions that distribute external interrupts to cores.
Functions
- __STATIC_FORCEINLINE void CIDU_BroadcastExtInterrupt (uint32_t int_id, uint32_t to_cores)
Broadcast external interrupt to cores.
This function broadcasts external interrupt which id is int_id to some/all target cores
Remark
External IRQn ID(int_id) is from the hard-wired persperctive, which has an offset mapped to the ECLIC IRQn, see Interrupt Number Definition in <Device.h>
By default on reset, only core 0 can receive interrupt which id is int_id
- Parameters:
int_id – [in] external interrupt id
to_cores – [in] target cores which can receive interrupt, use bitwise inclusive or of CIDU_RECEIVE_INTERRUPT_EN(core_id)
- __STATIC_FORCEINLINE uint32_t CIDU_GetBroadcastModeStatus (uint32_t int_id)
get broadcast mode status
Just query the INTn_INDICATOR register value
Remark
External IRQn ID(int_id) is from the hard-wired persperctive, which has an offset mapped to the ECLIC IRQn, see Interrupt Number Definition in <Device.h>
By default on reset, only core 0 can receive interrupt which id is int_id
- Parameters:
int_id – [in] external interrupt id
- Returns:
INTn_INDICATOR register value
- __STATIC_FORCEINLINE long CIDU_SetFirstClaimMode (uint32_t int_id, uint32_t core_id)
Let the first coming core to first claim the interrupt.
In external interrupt broadcast mode, make the first coming core to claim this interrupt and then can handle it.
Remark
External IRQn ID(int_id) is from the hard-wired persperctive, which has an offset mapped to the ECLIC IRQn, see Interrupt Number Definition in <Device.h>.
If it fails to claim the interrupt, it should quit the interrupt n’s handler of all cores
When a core claims the interrupt successfully and has handled it, it must call CIDU_ResetFirstClaimMode to reset the claim.
See also
CIDU_BroadcastExtInterrupt
CIDU_ResetFirstClaimMode
- Parameters:
int_id – [in] external interrupt id
core_id – [in] core id that receive the interrupt
- Returns:
-1 if it fails to claim the interrupt, else it can continue to handle the interrupt
- __STATIC_FORCEINLINE void CIDU_ResetFirstClaimMode (uint32_t int_id)
Reset the claim mode mask.
Reset the claim mode mask by Writing the reset value (all 1) to it
Remark
External IRQn ID(int_id) is from the hard-wired persperctive, which has an offset mapped to the ECLIC IRQn, see Interrupt Number Definition in <Device.h>
When a core claims the interrupt successfully and handle it, it must call CIDU_ResetFirstClaimMode to reset the claim
See also
CIDU_SetFirstClaimMode
- Parameters:
int_id – [in] external interrupt id
- __STATIC_FORCEINLINE uint32_t CIDU_GetClaimStatus (uint32_t int_id)
Get the claim mask status.
Get the claim mode staus, each bit[n] indicates whether core n has claimed interrupt successfully, 1 means yes, 0 means no.
Remark
External IRQn ID(int_id) is from the hard-wired persperctive, which has an offset mapped to the ECLIC IRQn, see Interrupt Number Definition in <Device.h>
See also
CIDU_ResetFirstClaimMode
CIDU_SetFirstClaimMode
- Parameters:
int_id – [in] external interrupt id
- Returns:
claim mode register INTn_MASK value
Inter Core Interrupt Functions
- __STATIC_FORCEINLINE void CIDU_TriggerInterCoreInt (uint32_t send_core_id, uint32_t recv_core_id)
- __STATIC_FORCEINLINE uint32_t CIDU_QueryCoreIntSenderMask (uint32_t recv_core_id)
- __STATIC_FORCEINLINE void CIDU_ClearInterCoreIntReq (uint32_t send_core_id, uint32_t recv_core_id)
- group Inter Core Interrupt Functions
Functions that implement Inter Core Interrupt mechanism.
Inter Core Interrupt (ICI) means that one core can send interrupt to another core in a multi-core cluster. CIDU ICI belongs to Internal Interrupt.
CIDU ICI Interrupt ID is fixed to 16.
Functions
- __STATIC_FORCEINLINE void CIDU_TriggerInterCoreInt (uint32_t send_core_id, uint32_t recv_core_id)
Trigger interrupt to another core in a multi-core cluster.
When called by core send_core_id, CIDU will trigger ICI to core recv_core_id automatically. and core recv_core_id could query CIDU_GetCoreIntSenderId to know the sender.
Remark
The core recv_core_id need to call CIDU_ClearInterCoreIntReq to clear the corresponding bit/bits of its own COREn_INT_STATUS.
It supports that multiple cores call CIDU_TriggerInterCoreInt simultaneously.
See also
CIDU_GetCoreIntSenderId
CIDU_ClearInterCoreIntReq
- Parameters:
send_core_id – [in] the core id which want to send the inter core interrupt
recv_core_id – [in] the core id which will receive the inter core interrupt
- __STATIC_FORCEINLINE uint32_t CIDU_QueryCoreIntSenderMask (uint32_t recv_core_id)
Core recv_core_id queries out who sends inter core interrupt to itself.
In the ISR of ICI, receive core can query if bit[n] of this return value is 1, core n sends the current ICI, if bit[m] is 1, then core m also sends, etc.
Remark
If the ICI ISR has finished the job, should call CIDU_ClearInterCoreIntReq to clear the IRQ
- Parameters:
recv_core_id – [in] the core id which receives the inter core interrupt
- Returns:
Value that shows sender core’s ID n whose bitn is 1
- __STATIC_FORCEINLINE void CIDU_ClearInterCoreIntReq (uint32_t send_core_id, uint32_t recv_core_id)
Clear the corresponding bit/bits of ICI request triggered by sender core.
Core recv_core_id write 1 to clear the bit send_core_id of the core recv_core_id’s COREn_INT_STATUS.
Remark
If the ICI ISR has finished the job of send_core_id_n’s ICI, then clear bit send_core_id_n; if it has finished send_core_id_n and send_core_id_m’s, then should clear both the bits, etc.
- Parameters:
send_core_id – [in] the core id which wants to send the inter core interrupt
recv_core_id – [in] the core id which will receive the inter core interrupt
Semaphore Functions
- __STATIC_FORCEINLINE uint32_t CIDU_GetSemaphoreStatus (uint32_t semph_n)
- __STATIC_FORCEINLINE long CIDU_CheckSemaphoreAcquired (uint32_t semph_n, uint32_t core_id)
- __STATIC_FORCEINLINE long CIDU_AcquireSemaphore (uint32_t semph_n, uint32_t core_id)
- __STATIC_FORCEINLINE void CIDU_AcquireSemaphore_Block (uint32_t semph_n, uint32_t core_id)
- __STATIC_FORCEINLINE void CIDU_ReleaseSemaphore (uint32_t semph_n)
- group Semaphore Functions
Functions that configure and use semaphores
Semaphore is very useful for multi-core cluster without SMP enable.
All Cores in the cluster agree on using SEMAPHORE_n register to protect a critical resource (an UART device for example).
If Core n wants to access the critical resource, it should try to own the SEMPAPHORE_n register, or else it can’t access the critical resource.
When the Core n owns the register SEMPAPHORE_n and finishes the job related the critical resource, then it should release the register by writing all 1 to it.
Functions
- __STATIC_FORCEINLINE uint32_t CIDU_GetSemaphoreStatus (uint32_t semph_n)
Get SEMAPHOREn’s value.
Just query the semaphore n’s value
- Parameters:
semph_n – [in] the semaphore id used to protect a critical resource
- Returns:
register SEMAPHOREn_STATUS value
- __STATIC_FORCEINLINE long CIDU_CheckSemaphoreAcquired (uint32_t semph_n, uint32_t core_id)
check SEMAPHOREn’s acquired status
Query that whether SEMAPHOREn has been acquired by one core successfully.
Remark
When the core n owns the register SEMPAPHORE_n and finishes the job related the critical resource, it should call CIDU_ReleaseSemaphore to release it.
See also
CIDU_GetSemaphoreStatus
CIDU_ReleaseSemaphore
- Parameters:
semph_n – [in] the semaphore id used to protect a critical resource
core_id – [in] the core id that wants to access the critical resource
- Returns:
0 if core_id has acquired this semaphore successfully, or else -1 if failed
- __STATIC_FORCEINLINE long CIDU_AcquireSemaphore (uint32_t semph_n, uint32_t core_id)
Acquire the SEMAPHOREn.
Acuqire the SEMAPHOREn, and check the acquired status
Remark
When the core n owns the register SEMPAPHORE_n and finishes the job related the critical resource, it should call CIDU_ReleaseSemaphore to release it.
See also
CIDU_CheckSemaphoreAcquired
CIDU_ReleaseSemaphore
- Parameters:
semph_n – [in] the semaphore id used to protect a critical resource
core_id – [in] the core id that wants to access the critical resource
- Returns:
0 if core_id has acquired this semaphore successfully, or else -1 if failed
- __STATIC_FORCEINLINE void CIDU_AcquireSemaphore_Block (uint32_t semph_n, uint32_t core_id)
Keep acquiring the SEMAPHOREn until it has acquired this semaphore successfully.
Query that whether SEMAPHOREn has been owned by one core successfully, if not, keep trying.
Remark
Core n will block here acquiring, so take care that core should release the semaphore when related job done.
See also
CIDU_AcquireSemaphore
CIDU_ReleaseSemaphore
- Parameters:
semph_n – [in] the semaphore id used to protect a critical resource
core_id – [in] the core id that wants to access the critical resource
- __STATIC_FORCEINLINE void CIDU_ReleaseSemaphore (uint32_t semph_n)
Release the SEMAPHOREn.
Release the SEMAPHOREn by writing all 1 to SEMAPHOREn register.
Remark
When the core finishes the job related to the critical resource, it should release the corresponding semaphore.
See also
CIDU_AcquireSemaphore_Block
- Parameters:
semph_n – [in] the semaphore id used to protect a critical resource