Move generic ipi_mb functions to common files
ipi_mb functions can be used for other Xilinx platform. Move it to common file from platform specific files. Signed-off-by: Tejas Patel <tejas.patel@xilinx.com> Reviewed-by: Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com> Signed-off-by: Jolly Shah <jollys@xilinx.com>
This commit is contained in:
parent
b8e39f49e6
commit
63436bde92
|
@ -11,6 +11,26 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
/*********************************************************************
|
||||
* IPI mailbox status macros
|
||||
********************************************************************/
|
||||
#define IPI_MB_STATUS_IDLE 0
|
||||
#define IPI_MB_STATUS_SEND_PENDING 1
|
||||
#define IPI_MB_STATUS_RECV_PENDING 2
|
||||
|
||||
/*********************************************************************
|
||||
* IPI mailbox call is secure or not macros
|
||||
********************************************************************/
|
||||
#define IPI_MB_CALL_NOTSECURE 0
|
||||
#define IPI_MB_CALL_SECURE 1
|
||||
|
||||
/*********************************************************************
|
||||
* IPI secure check
|
||||
********************************************************************/
|
||||
#define IPI_SECURE_MASK 0x1U
|
||||
#define IPI_IS_SECURE(I) ((ipi_table[(I)].secure_only & \
|
||||
IPI_SECURE_MASK) ? 1 : 0)
|
||||
|
||||
/*********************************************************************
|
||||
* Struct definitions
|
||||
********************************************************************/
|
||||
|
@ -22,4 +42,36 @@ struct ipi_config {
|
|||
unsigned char secure_only;
|
||||
};
|
||||
|
||||
/*********************************************************************
|
||||
* IPI APIs declarations
|
||||
********************************************************************/
|
||||
|
||||
/* Initialize IPI configuration table */
|
||||
void ipi_config_table_init(const struct ipi_config *ipi_table,
|
||||
uint32_t total_ipi);
|
||||
|
||||
/* Validate IPI mailbox access */
|
||||
int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure);
|
||||
|
||||
/* Open the IPI mailbox */
|
||||
void ipi_mb_open(uint32_t local, uint32_t remote);
|
||||
|
||||
/* Release the IPI mailbox */
|
||||
void ipi_mb_release(uint32_t local, uint32_t remote);
|
||||
|
||||
/* Enquire IPI mailbox status */
|
||||
int ipi_mb_enquire_status(uint32_t local, uint32_t remote);
|
||||
|
||||
/* Trigger notification on the IPI mailbox */
|
||||
void ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking);
|
||||
|
||||
/* Ack IPI mailbox notification */
|
||||
void ipi_mb_ack(uint32_t local, uint32_t remote);
|
||||
|
||||
/* Disable IPI mailbox notification interrupt */
|
||||
void ipi_mb_disable_irq(uint32_t local, uint32_t remote);
|
||||
|
||||
/* Enable IPI mailbox notification interrupt */
|
||||
void ipi_mb_enable_irq(uint32_t local, uint32_t remote);
|
||||
|
||||
#endif /* IPI_H */
|
||||
|
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Xilinx IPI agent registers access management
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <common/runtime_svc.h>
|
||||
#include <lib/bakery_lock.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <ipi.h>
|
||||
#include <plat_ipi.h>
|
||||
#include <plat_private.h>
|
||||
|
||||
/*********************************************************************
|
||||
* Macros definitions
|
||||
********************************************************************/
|
||||
|
||||
/* IPI registers offsets macros */
|
||||
#define IPI_TRIG_OFFSET 0x00U
|
||||
#define IPI_OBR_OFFSET 0x04U
|
||||
#define IPI_ISR_OFFSET 0x10U
|
||||
#define IPI_IMR_OFFSET 0x14U
|
||||
#define IPI_IER_OFFSET 0x18U
|
||||
#define IPI_IDR_OFFSET 0x1CU
|
||||
|
||||
/* IPI register start offset */
|
||||
#define IPI_REG_BASE(I) (ipi_table[(I)].ipi_reg_base)
|
||||
|
||||
/* IPI register bit mask */
|
||||
#define IPI_BIT_MASK(I) (ipi_table[(I)].ipi_bit_mask)
|
||||
|
||||
/* IPI configuration table */
|
||||
const static struct ipi_config *ipi_table;
|
||||
|
||||
/* Total number of IPI */
|
||||
static uint32_t ipi_total;
|
||||
|
||||
/**
|
||||
* ipi_config_init() - Initialize IPI configuration data
|
||||
*
|
||||
* @ipi_config_table - IPI configuration table
|
||||
* @ipi_total - Total number of IPI available
|
||||
*
|
||||
*/
|
||||
void ipi_config_table_init(const struct ipi_config *ipi_config_table,
|
||||
uint32_t total_ipi)
|
||||
{
|
||||
ipi_table = ipi_config_table;
|
||||
ipi_total = total_ipi;
|
||||
}
|
||||
|
||||
/* is_ipi_mb_within_range() - verify if IPI mailbox is within range
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
* return - 1 if within range, 0 if not
|
||||
*/
|
||||
static inline int is_ipi_mb_within_range(uint32_t local, uint32_t remote)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
if (remote >= ipi_total || local >= ipi_total)
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipi_mb_validate() - validate IPI mailbox access
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
* @is_secure - indicate if the requester is from secure software
|
||||
*
|
||||
* return - 0 success, negative value for errors
|
||||
*/
|
||||
int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!is_ipi_mb_within_range(local, remote))
|
||||
ret = -EINVAL;
|
||||
else if (IPI_IS_SECURE(local) && !is_secure)
|
||||
ret = -EPERM;
|
||||
else if (IPI_IS_SECURE(remote) && !is_secure)
|
||||
ret = -EPERM;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipi_mb_open() - Open IPI mailbox.
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
*/
|
||||
void ipi_mb_open(uint32_t local, uint32_t remote)
|
||||
{
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
}
|
||||
|
||||
/**
|
||||
* ipi_mb_release() - Open IPI mailbox.
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
*/
|
||||
void ipi_mb_release(uint32_t local, uint32_t remote)
|
||||
{
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
}
|
||||
|
||||
/**
|
||||
* ipi_mb_enquire_status() - Enquire IPI mailbox status
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
* return - 0 idle, positive value for pending sending or receiving,
|
||||
* negative value for errors
|
||||
*/
|
||||
int ipi_mb_enquire_status(uint32_t local, uint32_t remote)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t status;
|
||||
|
||||
status = mmio_read_32(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
|
||||
if (status & IPI_BIT_MASK(remote))
|
||||
ret |= IPI_MB_STATUS_SEND_PENDING;
|
||||
status = mmio_read_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
|
||||
if (status & IPI_BIT_MASK(remote))
|
||||
ret |= IPI_MB_STATUS_RECV_PENDING;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ipi_mb_notify() - Trigger IPI mailbox notification
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
* @is_blocking - if to trigger the notification in blocking mode or not.
|
||||
*
|
||||
* It sets the remote bit in the IPI agent trigger register.
|
||||
*
|
||||
*/
|
||||
void ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking)
|
||||
{
|
||||
uint32_t status;
|
||||
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_TRIG_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
if (is_blocking) {
|
||||
do {
|
||||
status = mmio_read_32(IPI_REG_BASE(local) +
|
||||
IPI_OBR_OFFSET);
|
||||
} while (status & IPI_BIT_MASK(remote));
|
||||
}
|
||||
}
|
||||
|
||||
/* ipi_mb_ack() - Ack IPI mailbox notification from the other end
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
* It will clear the remote bit in the isr register.
|
||||
*
|
||||
*/
|
||||
void ipi_mb_ack(uint32_t local, uint32_t remote)
|
||||
{
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
}
|
||||
|
||||
/* ipi_mb_disable_irq() - Disable IPI mailbox notification interrupt
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
* It will mask the remote bit in the idr register.
|
||||
*
|
||||
*/
|
||||
void ipi_mb_disable_irq(uint32_t local, uint32_t remote)
|
||||
{
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
}
|
||||
|
||||
/* ipi_mb_enable_irq() - Enable IPI mailbox notification interrupt
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
* It will mask the remote bit in the idr register.
|
||||
*
|
||||
*/
|
||||
void ipi_mb_enable_irq(uint32_t local, uint32_t remote)
|
||||
{
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_IER_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
}
|
|
@ -28,50 +28,10 @@
|
|||
#define IPI_ID_PL3 10U
|
||||
|
||||
/*********************************************************************
|
||||
* IPI mailbox status macros
|
||||
* Platform specific IPI API declarations
|
||||
********************************************************************/
|
||||
#define IPI_MB_STATUS_IDLE 0
|
||||
#define IPI_MB_STATUS_SEND_PENDING 1
|
||||
#define IPI_MB_STATUS_RECV_PENDING 2
|
||||
|
||||
/*********************************************************************
|
||||
* IPI mailbox call is secure or not macros
|
||||
********************************************************************/
|
||||
#define IPI_MB_CALL_NOTSECURE 0
|
||||
#define IPI_MB_CALL_SECURE 1
|
||||
|
||||
/*********************************************************************
|
||||
* IPI APIs declarations
|
||||
********************************************************************/
|
||||
/* Configure IPI table for zynqmp */
|
||||
void zynqmp_ipi_config_table_init(void);
|
||||
|
||||
/* Initialize IPI configuration table */
|
||||
void ipi_config_table_init(const struct ipi_config *ipi_table,
|
||||
uint32_t total_ipi);
|
||||
|
||||
/* Validate IPI mailbox access */
|
||||
int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure);
|
||||
|
||||
/* Open the IPI mailbox */
|
||||
void ipi_mb_open(uint32_t local, uint32_t remote);
|
||||
|
||||
/* Release the IPI mailbox */
|
||||
void ipi_mb_release(uint32_t local, uint32_t remote);
|
||||
|
||||
/* Enquire IPI mailbox status */
|
||||
int ipi_mb_enquire_status(uint32_t local, uint32_t remote);
|
||||
|
||||
/* Trigger notification on the IPI mailbox */
|
||||
void ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking);
|
||||
|
||||
/* Ack IPI mailbox notification */
|
||||
void ipi_mb_ack(uint32_t local, uint32_t remote);
|
||||
|
||||
/* Disable IPI mailbox notification interrupt */
|
||||
void ipi_mb_disable_irq(uint32_t local, uint32_t remote);
|
||||
|
||||
/* Enable IPI mailbox notification interrupt */
|
||||
void ipi_mb_enable_irq(uint32_t local, uint32_t remote);
|
||||
|
||||
#endif /* PLAT_IPI_H */
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include <common/runtime_svc.h>
|
||||
#include <lib/bakery_lock.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <ipi.h>
|
||||
#include <plat_ipi.h>
|
||||
#include <plat_private.h>
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \
|
|||
plat/arm/common/arm_common.c \
|
||||
plat/arm/common/arm_gicv2.c \
|
||||
plat/common/plat_gicv2.c \
|
||||
plat/xilinx/common/ipi.c \
|
||||
plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S \
|
||||
plat/xilinx/zynqmp/aarch64/zynqmp_common.c
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include <arch_helpers.h>
|
||||
#include <lib/bakery_lock.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <ipi.h>
|
||||
#include <plat_ipi.h>
|
||||
#include <plat_private.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
|
|
@ -20,38 +20,6 @@
|
|||
#include <plat_ipi.h>
|
||||
#include <plat_private.h>
|
||||
|
||||
/*********************************************************************
|
||||
* Macros definitions
|
||||
********************************************************************/
|
||||
|
||||
/* IPI registers base address */
|
||||
#define IPI_REGS_BASE 0xFF300000U
|
||||
|
||||
/* IPI registers offsets macros */
|
||||
#define IPI_TRIG_OFFSET 0x00U
|
||||
#define IPI_OBR_OFFSET 0x04U
|
||||
#define IPI_ISR_OFFSET 0x10U
|
||||
#define IPI_IMR_OFFSET 0x14U
|
||||
#define IPI_IER_OFFSET 0x18U
|
||||
#define IPI_IDR_OFFSET 0x1CU
|
||||
|
||||
/* IPI register start offset */
|
||||
#define IPI_REG_BASE(I) (ipi_table[(I)].ipi_reg_base)
|
||||
|
||||
/* IPI register bit mask */
|
||||
#define IPI_BIT_MASK(I) (ipi_table[(I)].ipi_bit_mask)
|
||||
|
||||
/* IPI secure check */
|
||||
#define IPI_SECURE_MASK 0x1U
|
||||
#define IPI_IS_SECURE(I) ((ipi_table[(I)].secure_only & \
|
||||
IPI_SECURE_MASK) ? 1 : 0)
|
||||
|
||||
/* IPI configuration table */
|
||||
const static struct ipi_config *ipi_table;
|
||||
|
||||
/* Total number of IPI */
|
||||
static uint32_t ipi_total;
|
||||
|
||||
/* Zynqmp ipi configuration table */
|
||||
const static struct ipi_config zynqmp_ipi_table[] = {
|
||||
/* APU IPI */
|
||||
|
@ -130,174 +98,3 @@ void zynqmp_ipi_config_table_init(void)
|
|||
{
|
||||
ipi_config_table_init(zynqmp_ipi_table, ARRAY_SIZE(zynqmp_ipi_table));
|
||||
}
|
||||
|
||||
/**
|
||||
* ipi_config_table_init() - Initialize IPI configuration data
|
||||
*
|
||||
* @ipi_config_table - IPI configuration table
|
||||
* @ipi_total - Total number of IPI available
|
||||
*
|
||||
*/
|
||||
void ipi_config_table_init(const struct ipi_config *ipi_config_table,
|
||||
uint32_t total_ipi)
|
||||
{
|
||||
ipi_table = ipi_config_table;
|
||||
ipi_total = total_ipi;
|
||||
}
|
||||
|
||||
/* is_ipi_mb_within_range() - verify if IPI mailbox is within range
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
* return - 1 if within range, 0 if not
|
||||
*/
|
||||
static inline int is_ipi_mb_within_range(uint32_t local, uint32_t remote)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
if (remote >= ipi_total || local >= ipi_total)
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipi_mb_validate() - validate IPI mailbox access
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
* @is_secure - indicate if the requester is from secure software
|
||||
*
|
||||
* return - 0 success, negative value for errors
|
||||
*/
|
||||
int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!is_ipi_mb_within_range(local, remote))
|
||||
ret = -EINVAL;
|
||||
else if (IPI_IS_SECURE(local) && !is_secure)
|
||||
ret = -EPERM;
|
||||
else if (IPI_IS_SECURE(remote) && !is_secure)
|
||||
ret = -EPERM;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipi_mb_open() - Open IPI mailbox.
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
*/
|
||||
void ipi_mb_open(uint32_t local, uint32_t remote)
|
||||
{
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
}
|
||||
|
||||
/**
|
||||
* ipi_mb_release() - Open IPI mailbox.
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
*/
|
||||
void ipi_mb_release(uint32_t local, uint32_t remote)
|
||||
{
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
}
|
||||
|
||||
/**
|
||||
* ipi_mb_enquire_status() - Enquire IPI mailbox status
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
* return - 0 idle, positive value for pending sending or receiving,
|
||||
* negative value for errors
|
||||
*/
|
||||
int ipi_mb_enquire_status(uint32_t local, uint32_t remote)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t status;
|
||||
|
||||
status = mmio_read_32(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
|
||||
if (status & IPI_BIT_MASK(remote))
|
||||
ret |= IPI_MB_STATUS_SEND_PENDING;
|
||||
status = mmio_read_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
|
||||
if (status & IPI_BIT_MASK(remote))
|
||||
ret |= IPI_MB_STATUS_RECV_PENDING;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ipi_mb_notify() - Trigger IPI mailbox notification
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
* @is_blocking - if to trigger the notification in blocking mode or not.
|
||||
*
|
||||
* It sets the remote bit in the IPI agent trigger register.
|
||||
*
|
||||
*/
|
||||
void ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking)
|
||||
{
|
||||
uint32_t status;
|
||||
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_TRIG_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
if (is_blocking) {
|
||||
do {
|
||||
status = mmio_read_32(IPI_REG_BASE(local) +
|
||||
IPI_OBR_OFFSET);
|
||||
} while (status & IPI_BIT_MASK(remote));
|
||||
}
|
||||
}
|
||||
|
||||
/* ipi_mb_ack() - Ack IPI mailbox notification from the other end
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
* It will clear the remote bit in the isr register.
|
||||
*
|
||||
*/
|
||||
void ipi_mb_ack(uint32_t local, uint32_t remote)
|
||||
{
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
}
|
||||
|
||||
/* ipi_mb_disable_irq() - Disable IPI mailbox notification interrupt
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
* It will mask the remote bit in the idr register.
|
||||
*
|
||||
*/
|
||||
void ipi_mb_disable_irq(uint32_t local, uint32_t remote)
|
||||
{
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
}
|
||||
|
||||
/* ipi_mb_enable_irq() - Enable IPI mailbox notification interrupt
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
* It will mask the remote bit in the idr register.
|
||||
*
|
||||
*/
|
||||
void ipi_mb_enable_irq(uint32_t local, uint32_t remote)
|
||||
{
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_IER_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue