Merge changes from topic "xlnx_error_management" into integration
* changes: plat: send an sgi to communicate to linux plat: xilinx: Error management support
This commit is contained in:
commit
0fd0a6c119
|
@ -117,6 +117,40 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
|
|||
NOTICE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc);
|
||||
}
|
||||
|
||||
static interrupt_type_handler_t type_el3_interrupt_handler;
|
||||
|
||||
int request_intr_type_el3(uint32_t id, interrupt_type_handler_t handler)
|
||||
{
|
||||
/* Validate 'handler'*/
|
||||
if (!handler) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
type_el3_interrupt_handler = handler;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint64_t rdo_el3_interrupt_handler(uint32_t id, uint32_t flags,
|
||||
void *handle, void *cookie)
|
||||
{
|
||||
uint32_t intr_id;
|
||||
interrupt_type_handler_t handler;
|
||||
|
||||
intr_id = plat_ic_get_pending_interrupt_id();
|
||||
/* Currently we support one interrupt */
|
||||
if (intr_id != PLAT_VERSAL_IPI_IRQ) {
|
||||
WARN("Unexpected interrupt call: 0x%x\n", intr_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
handler = type_el3_interrupt_handler;
|
||||
if (handler) {
|
||||
return handler(intr_id, flags, handle, cookie);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
void bl31_platform_setup(void)
|
||||
{
|
||||
/* Initialize the gic cpu and distributor interfaces */
|
||||
|
@ -126,6 +160,15 @@ void bl31_platform_setup(void)
|
|||
|
||||
void bl31_plat_runtime_setup(void)
|
||||
{
|
||||
uint64_t flags = 0;
|
||||
uint64_t rc;
|
||||
|
||||
set_interrupt_rm_flag(flags, NON_SECURE);
|
||||
rc = register_interrupt_type_handler(INTR_TYPE_EL3,
|
||||
rdo_el3_interrupt_handler, flags);
|
||||
if (rc) {
|
||||
panic();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define PLAT_PRIVATE_H
|
||||
|
||||
#include <lib/xlat_tables/xlat_tables.h>
|
||||
#include <bl31/interrupt_mgmt.h>
|
||||
|
||||
void versal_config_setup(void);
|
||||
|
||||
|
@ -22,5 +23,10 @@ void plat_versal_gic_save(void);
|
|||
void plat_versal_gic_resume(void);
|
||||
|
||||
unsigned int versal_calc_core_pos(u_register_t mpidr);
|
||||
/*
|
||||
* Register handler to specific GIC entrance
|
||||
* for INTR_TYPE_EL3 type of interrupt
|
||||
*/
|
||||
int request_intr_type_el3(uint32_t irq, interrupt_type_handler_t fiq_handler);
|
||||
|
||||
#endif /* PLAT_PRIVATE_H */
|
||||
|
|
|
@ -91,11 +91,14 @@
|
|||
*/
|
||||
#define PLAT_VERSAL_G1S_IRQS VERSAL_IRQ_SEC_PHY_TIMER
|
||||
#define PLAT_VERSAL_G0_IRQS VERSAL_IRQ_SEC_PHY_TIMER
|
||||
#define PLAT_VERSAL_IPI_IRQ 62
|
||||
|
||||
#define PLAT_VERSAL_G1S_IRQ_PROPS(grp) \
|
||||
INTR_PROP_DESC(VERSAL_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
|
||||
GIC_INTR_CFG_LEVEL)
|
||||
|
||||
#define PLAT_VERSAL_G0_IRQ_PROPS(grp)
|
||||
#define PLAT_VERSAL_G0_IRQ_PROPS(grp) \
|
||||
INTR_PROP_DESC(PLAT_VERSAL_IPI_IRQ, GIC_HIGHEST_SEC_PRIORITY, grp, \
|
||||
GIC_INTR_CFG_EDGE), \
|
||||
|
||||
#endif /* PLATFORM_DEF_H */
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include "pm_api_sys.h"
|
||||
#include "pm_client.h"
|
||||
#include "pm_defs.h"
|
||||
#include "pm_svc_main.h"
|
||||
#include "../drivers/arm/gic/v3/gicv3_private.h"
|
||||
|
||||
/*********************************************************************
|
||||
* Target module IDs macros
|
||||
|
@ -22,6 +24,7 @@
|
|||
#define LIBPM_MODULE_ID 0x2
|
||||
#define LOADER_MODULE_ID 0x7
|
||||
|
||||
#define MODE 0x80000000
|
||||
/* default shutdown/reboot scope is system(2) */
|
||||
static unsigned int pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM;
|
||||
|
||||
|
@ -861,6 +864,7 @@ enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
|
|||
uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
int ret;
|
||||
|
||||
switch (ioctl_id) {
|
||||
case IOCTL_SET_PLL_FRAC_MODE:
|
||||
|
@ -871,6 +875,15 @@ enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
|
|||
return pm_pll_set_param(arg1, PM_PLL_PARAM_DATA, arg2, flag);
|
||||
case IOCTL_GET_PLL_FRAC_DATA:
|
||||
return pm_pll_get_param(arg1, PM_PLL_PARAM_DATA, value, flag);
|
||||
case IOCTL_SET_SGI:
|
||||
/* Get the sgi number */
|
||||
ret = pm_register_sgi(arg1);
|
||||
if (ret) {
|
||||
return PM_RET_ERROR_ARGS;
|
||||
}
|
||||
gicd_write_irouter(gicv3_driver_data->gicd_base,
|
||||
PLAT_VERSAL_IPI_IRQ, MODE);
|
||||
return PM_RET_SUCCESS;
|
||||
default:
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_IOCTL,
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
#define IOCTL_GET_PLL_FRAC_MODE 9
|
||||
#define IOCTL_SET_PLL_FRAC_DATA 10
|
||||
#define IOCTL_GET_PLL_FRAC_DATA 11
|
||||
#define IOCTL_SET_SGI 25
|
||||
|
||||
/* Parameter ID for PLL IOCTLs */
|
||||
/* Fractional data portion for PLL */
|
||||
|
|
|
@ -13,12 +13,64 @@
|
|||
#include <plat_private.h>
|
||||
#include <stdbool.h>
|
||||
#include <common/runtime_svc.h>
|
||||
#include <plat/common/platform.h>
|
||||
#include "pm_api_sys.h"
|
||||
#include "pm_client.h"
|
||||
#include "pm_ipi.h"
|
||||
#include <drivers/arm/gicv3.h>
|
||||
|
||||
#define XSCUGIC_SGIR_EL1_INITID_SHIFT 24U
|
||||
#define INVALID_SGI 0xFF
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_asgi1r_el1, S3_0_C12_C11_6)
|
||||
|
||||
/* pm_up = true - UP, pm_up = false - DOWN */
|
||||
static bool pm_up;
|
||||
static unsigned int sgi = INVALID_SGI;
|
||||
|
||||
static uint64_t ipi_fiq_handler(uint32_t id, uint32_t flags, void *handle,
|
||||
void *cookie)
|
||||
{
|
||||
int cpu;
|
||||
unsigned int reg;
|
||||
|
||||
(void)plat_ic_acknowledge_interrupt();
|
||||
cpu = plat_my_core_pos() + 1;
|
||||
|
||||
if (sgi != INVALID_SGI) {
|
||||
reg = (cpu | (sgi << XSCUGIC_SGIR_EL1_INITID_SHIFT));
|
||||
write_icc_asgi1r_el1(reg);
|
||||
}
|
||||
|
||||
/* Clear FIQ */
|
||||
plat_ic_end_of_interrupt(id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_register_sgi() - PM register the IPI interrupt
|
||||
*
|
||||
* @sgi - SGI number to be used for communication.
|
||||
* @return On success, the initialization function must return 0.
|
||||
* Any other return value will cause the framework to ignore
|
||||
* the service
|
||||
*
|
||||
* Update the SGI number to be used.
|
||||
*
|
||||
*/
|
||||
int pm_register_sgi(unsigned int sgi_num)
|
||||
{
|
||||
if (sgi != INVALID_SGI) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (sgi_num >= GICV3_MAX_SGI_TARGETS) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sgi = sgi_num;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_setup() - PM service setup
|
||||
|
@ -46,6 +98,18 @@ int pm_setup(void)
|
|||
pm_up = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable IPI IRQ
|
||||
* assume the rich OS is OK to handle callback IRQs now.
|
||||
* Even if we were wrong, it would not enable the IRQ in
|
||||
* the GIC.
|
||||
*/
|
||||
pm_ipi_irq_enable(primary_proc);
|
||||
|
||||
ret = request_intr_type_el3(PLAT_VERSAL_IPI_IRQ, ipi_fiq_handler);
|
||||
if (ret) {
|
||||
WARN("BL31: registering IPI interrupt failed\n");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,4 +14,5 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
|
|||
uint64_t x4, void *cookie, void *handle,
|
||||
uint64_t flags);
|
||||
|
||||
int pm_register_sgi(unsigned int sgi_num);
|
||||
#endif /* PM_SVC_MAIN_H */
|
||||
|
|
Loading…
Reference in New Issue