Merge pull request #1477 from dp-arm/dp/css-ap-core

CSS: Add support for SCMI AP core config protocol
This commit is contained in:
Dimitris Papastamos 2018-07-13 15:23:29 +01:00 committed by GitHub
commit 9ceda8b907
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 156 additions and 7 deletions

View File

@ -171,7 +171,6 @@ int arm_validate_psci_entrypoint(uintptr_t entrypoint);
int arm_validate_ns_entrypoint(uintptr_t entrypoint);
void arm_system_pwr_domain_save(void);
void arm_system_pwr_domain_resume(void);
void arm_program_trusted_mailbox(uintptr_t address);
int arm_psci_read_mem_protect(int *enabled);
int arm_nor_psci_write_mem_protect(int val);
void arm_nor_psci_do_static_mem_protect(void);
@ -250,6 +249,7 @@ void plat_arm_pwrc_setup(void);
void plat_arm_interconnect_init(void);
void plat_arm_interconnect_enter_coherency(void);
void plat_arm_interconnect_exit_coherency(void);
void plat_arm_program_trusted_mailbox(uintptr_t address);
#if ARM_PLAT_MT
unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr);

View File

@ -144,7 +144,7 @@ void bl1_plat_prepare_exit(entry_point_info_t *ep_info)
* in order to release secondary CPUs from their holding pen and make
* them jump there.
*/
arm_program_trusted_mailbox(ep_info->pc);
plat_arm_program_trusted_mailbox(ep_info->pc);
dsbsy();
sev();
#endif

View File

@ -166,7 +166,7 @@ BL1_SOURCES += drivers/arm/sp805/sp805.c \
plat/arm/common/arm_err.c \
plat/arm/common/arm_io_storage.c
ifdef EL3_PAYLOAD_BASE
# Need the arm_program_trusted_mailbox() function to release secondary CPUs from
# Need the plat_arm_program_trusted_mailbox() function to release secondary CPUs from
# their holding pen
BL1_SOURCES += plat/arm/common/arm_pm.c
endif

View File

@ -14,8 +14,9 @@
#include <platform_def.h>
#include <psci.h>
/* Allow ARM Standard platforms to override this function */
/* Allow ARM Standard platforms to override these functions */
#pragma weak plat_arm_psci_override_pm_ops
#pragma weak plat_arm_program_trusted_mailbox
#if ARM_RECOM_STATE_ID_ENC
extern unsigned int arm_pm_idle_states[];
@ -189,11 +190,11 @@ void arm_system_pwr_domain_resume(void)
}
/*******************************************************************************
* Private function to program the mailbox for a cpu before it is released
* ARM platform function to program the mailbox for a cpu before it is released
* from reset. This function assumes that the Trusted mail box base is within
* the ARM_SHARED_RAM region
******************************************************************************/
void arm_program_trusted_mailbox(uintptr_t address)
void plat_arm_program_trusted_mailbox(uintptr_t address)
{
uintptr_t *mailbox = (void *) PLAT_ARM_TRUSTED_MAILBOX_BASE;
@ -218,6 +219,6 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint,
*psci_ops = plat_arm_psci_override_pm_ops(&plat_arm_psci_pm_ops);
/* Setup mailbox with entry point. */
arm_program_trusted_mailbox(sec_entrypoint);
plat_arm_program_trusted_mailbox(sec_entrypoint);
return 0;
}

View File

@ -32,6 +32,7 @@ BL31_SOURCES += plat/arm/css/drivers/scp/css_pm_scpi.c \
plat/arm/css/drivers/scpi/css_scpi.c
else
BL31_SOURCES += plat/arm/css/drivers/scp/css_pm_scmi.c \
plat/arm/css/drivers/scmi/scmi_ap_core_proto.c \
plat/arm/css/drivers/scmi/scmi_common.c \
plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c \
plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c \

View File

@ -12,6 +12,7 @@
#include <stdint.h>
/* Supported SCMI Protocol Versions */
#define SCMI_AP_CORE_PROTO_VER MAKE_SCMI_VERSION(1, 0)
#define SCMI_PWR_DMN_PROTO_VER MAKE_SCMI_VERSION(1, 0)
#define SCMI_SYS_PWR_PROTO_VER MAKE_SCMI_VERSION(1, 0)
@ -29,6 +30,8 @@
/* SCMI Protocol identifiers */
#define SCMI_PWR_DMN_PROTO_ID 0x11
#define SCMI_SYS_PWR_PROTO_ID 0x12
/* The AP core protocol is a CSS platform-specific extension */
#define SCMI_AP_CORE_PROTO_ID 0x90
/* Mandatory messages IDs for all SCMI protocols */
#define SCMI_PROTO_VERSION_MSG 0x0
@ -43,6 +46,10 @@
#define SCMI_SYS_PWR_STATE_SET_MSG 0x3
#define SCMI_SYS_PWR_STATE_GET_MSG 0x4
/* SCMI AP core protocol message IDs */
#define SCMI_AP_CORE_RESET_ADDR_SET_MSG 0x3
#define SCMI_AP_CORE_RESET_ADDR_GET_MSG 0x4
/* Helper macros for system power management protocol commands */
/*
@ -73,6 +80,13 @@
#define SCMI_SYS_PWR_POWER_UP 0x3
#define SCMI_SYS_PWR_SUSPEND 0x4
/*
* Macros to describe the bit-fields of the `attribute` of AP core protocol
* AP_CORE_RESET_ADDR set/get messages.
*/
#define SCMI_AP_CORE_LOCK_ATTR_SHIFT 0x0
#define SCMI_AP_CORE_LOCK_ATTR (1U << SCMI_AP_CORE_LOCK_ATTR_SHIFT)
/* SCMI Error code definitions */
#define SCMI_E_QUEUED 1
#define SCMI_E_SUCCESS 0
@ -133,4 +147,8 @@ int scmi_pwr_state_get(void *p, uint32_t domain_id, uint32_t *scmi_pwr_state);
int scmi_sys_pwr_state_set(void *p, uint32_t flags, uint32_t system_state);
int scmi_sys_pwr_state_get(void *p, uint32_t *system_state);
/* SCMI AP core configuration protocol commands. */
int scmi_ap_core_set_reset_addr(void *p, uint64_t reset_addr, uint32_t attr);
int scmi_ap_core_get_reset_addr(void *p, uint64_t *reset_addr, uint32_t *attr);
#endif /* __CSS_SCMI_H__ */

View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <assert.h>
#include <debug.h>
#include "scmi.h"
#include "scmi_private.h"
/*
* API to set the SCMI AP core reset address and attributes
*/
int scmi_ap_core_set_reset_addr(void *p, uint64_t reset_addr, uint32_t attr)
{
mailbox_mem_t *mbx_mem;
int token = 0, ret;
scmi_channel_t *ch = (scmi_channel_t *)p;
validate_scmi_channel(ch);
scmi_get_channel(ch);
mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
mbx_mem->msg_header = SCMI_MSG_CREATE(SCMI_AP_CORE_PROTO_ID,
SCMI_AP_CORE_RESET_ADDR_SET_MSG, token);
mbx_mem->len = SCMI_AP_CORE_RESET_ADDR_SET_MSG_LEN;
mbx_mem->flags = SCMI_FLAG_RESP_POLL;
SCMI_PAYLOAD_ARG3(mbx_mem->payload, reset_addr & 0xffffffff,
reset_addr >> 32, attr);
scmi_send_sync_command(ch);
/* Get the return values */
SCMI_PAYLOAD_RET_VAL1(mbx_mem->payload, ret);
assert(mbx_mem->len == SCMI_AP_CORE_RESET_ADDR_SET_RESP_LEN);
assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header));
scmi_put_channel(ch);
return ret;
}
/*
* API to get the SCMI AP core reset address and attributes
*/
int scmi_ap_core_get_reset_addr(void *p, uint64_t *reset_addr, uint32_t *attr)
{
mailbox_mem_t *mbx_mem;
int token = 0, ret;
scmi_channel_t *ch = (scmi_channel_t *)p;
uint32_t lo_addr, hi_addr;
validate_scmi_channel(ch);
scmi_get_channel(ch);
mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
mbx_mem->msg_header = SCMI_MSG_CREATE(SCMI_AP_CORE_PROTO_ID,
SCMI_AP_CORE_RESET_ADDR_GET_MSG, token);
mbx_mem->len = SCMI_AP_CORE_RESET_ADDR_GET_MSG_LEN;
mbx_mem->flags = SCMI_FLAG_RESP_POLL;
scmi_send_sync_command(ch);
/* Get the return values */
SCMI_PAYLOAD_RET_VAL4(mbx_mem->payload, ret, lo_addr, hi_addr, *attr);
*reset_addr = lo_addr | (uint64_t)hi_addr << 32;
assert(mbx_mem->len == SCMI_AP_CORE_RESET_ADDR_GET_RESP_LEN);
assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header));
scmi_put_channel(ch);
return ret;
}

View File

@ -18,6 +18,12 @@
#define SCMI_PROTO_MSG_ATTR_MSG_LEN 8
#define SCMI_PROTO_MSG_ATTR_RESP_LEN 12
#define SCMI_AP_CORE_RESET_ADDR_SET_MSG_LEN 16
#define SCMI_AP_CORE_RESET_ADDR_SET_RESP_LEN 8
#define SCMI_AP_CORE_RESET_ADDR_GET_MSG_LEN 4
#define SCMI_AP_CORE_RESET_ADDR_GET_RESP_LEN 20
#define SCMI_PWR_STATE_SET_MSG_LEN 16
#define SCMI_PWR_STATE_SET_RESP_LEN 8
@ -113,6 +119,11 @@
(val3) = mmio_read_32((uintptr_t)&payld_arr[2]); \
} while (0)
#define SCMI_PAYLOAD_RET_VAL4(payld_arr, val1, val2, val3, val4) do { \
SCMI_PAYLOAD_RET_VAL3(payld_arr, val1, val2, val3); \
(val4) = mmio_read_32((uintptr_t)&payld_arr[3]); \
} while (0)
/*
* Private data structure for representing the mailbox memory layout. Refer
* the SCMI specification for more details.

View File

@ -306,6 +306,28 @@ static scmi_channel_plat_info_t plat_css_scmi_plat_info = {
.ring_doorbell = &mhu_ring_doorbell,
};
static int scmi_ap_core_init(scmi_channel_t *ch)
{
#if PROGRAMMABLE_RESET_ADDRESS
uint32_t version;
int ret;
ret = scmi_proto_version(ch, SCMI_AP_CORE_PROTO_ID, &version);
if (ret != SCMI_E_SUCCESS) {
WARN("SCMI AP core protocol version message failed\n");
return -1;
}
if (!is_scmi_version_compatible(SCMI_AP_CORE_PROTO_VER, version)) {
WARN("SCMI AP core protocol version 0x%x incompatible with driver version 0x%x\n",
version, SCMI_AP_CORE_PROTO_VER);
return -1;
}
INFO("SCMI AP core protocol version 0x%x detected\n", version);
#endif
return 0;
}
void plat_arm_pwrc_setup(void)
{
channel.info = &plat_css_scmi_plat_info;
@ -315,6 +337,10 @@ void plat_arm_pwrc_setup(void)
ERROR("SCMI Initialization failed\n");
panic();
}
if (scmi_ap_core_init(&channel) < 0) {
ERROR("SCMI AP core protocol initialization failed\n");
panic();
}
}
/******************************************************************************
@ -386,3 +412,18 @@ int css_system_reset2(int is_vendor, int reset_type, u_register_t cookie)
*/
return 0;
}
#if PROGRAMMABLE_RESET_ADDRESS
void plat_arm_program_trusted_mailbox(uintptr_t address)
{
int ret;
assert(scmi_handle);
ret = scmi_ap_core_set_reset_addr(scmi_handle, address,
SCMI_AP_CORE_LOCK_ATTR);
if (ret != SCMI_E_SUCCESS) {
ERROR("CSS: Failed to program reset address: %d\n", ret);
panic();
}
}
#endif