diff --git a/drivers/arm/css/mhu/css_mhu.c b/drivers/arm/css/mhu/css_mhu.c new file mode 100644 index 0000000..b7faf7e --- /dev/null +++ b/drivers/arm/css/mhu/css_mhu.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include +#include +#include +#include +#include + +/* SCP MHU secure channel registers */ +#define SCP_INTR_S_STAT 0x200 +#define SCP_INTR_S_SET 0x208 +#define SCP_INTR_S_CLEAR 0x210 + +/* CPU MHU secure channel registers */ +#define CPU_INTR_S_STAT 0x300 +#define CPU_INTR_S_SET 0x308 +#define CPU_INTR_S_CLEAR 0x310 + +ARM_INSTANTIATE_LOCK; + +/* Weak definition may be overridden in specific CSS based platform */ +#pragma weak plat_arm_pwrc_setup + + +/* + * Slot 31 is reserved because the MHU hardware uses this register bit to + * indicate a non-secure access attempt. The total number of available slots is + * therefore 31 [30:0]. + */ +#define MHU_MAX_SLOT_ID 30 + +void mhu_secure_message_start(unsigned int slot_id) +{ + assert(slot_id <= MHU_MAX_SLOT_ID); + + arm_lock_get(); + + /* Make sure any previous command has finished */ + while (mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) & + (1 << slot_id)) + ; +} + +void mhu_secure_message_send(unsigned int slot_id) +{ + assert(slot_id <= MHU_MAX_SLOT_ID); + assert(!(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) & + (1 << slot_id))); + + /* Send command to SCP */ + mmio_write_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_SET, 1 << slot_id); +} + +uint32_t mhu_secure_message_wait(void) +{ + /* Wait for response from SCP */ + uint32_t response; + while (!(response = mmio_read_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_STAT))) + ; + + return response; +} + +void mhu_secure_message_end(unsigned int slot_id) +{ + assert(slot_id <= MHU_MAX_SLOT_ID); + + /* + * Clear any response we got by writing one in the relevant slot bit to + * the CLEAR register + */ + mmio_write_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_CLEAR, 1 << slot_id); + + arm_lock_release(); +} + +void __init mhu_secure_init(void) +{ + arm_lock_init(); + + /* + * The STAT register resets to zero. Ensure it is in the expected state, + * as a stale or garbage value would make us think it's a message we've + * already sent. + */ + assert(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) == 0); +} + +void __init plat_arm_pwrc_setup(void) +{ + mhu_secure_init(); +} diff --git a/drivers/arm/css/mhu/css_mhu_doorbell.c b/drivers/arm/css/mhu/css_mhu_doorbell.c new file mode 100644 index 0000000..8858742 --- /dev/null +++ b/drivers/arm/css/mhu/css_mhu_doorbell.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info) +{ + MHU_RING_DOORBELL(plat_info->db_reg_addr, + plat_info->db_modify_mask, + plat_info->db_preserve_mask); + return; +} + +void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info) +{ + /* wake receiver */ + MHU_V2_ACCESS_REQUEST(MHUV2_BASE_ADDR); + + /* wait for receiver to acknowledge its ready */ + while (MHU_V2_IS_ACCESS_READY(MHUV2_BASE_ADDR) == 0) + ; + + MHU_RING_DOORBELL(plat_info->db_reg_addr, + plat_info->db_modify_mask, + plat_info->db_preserve_mask); + + /* clear the access request for the receiver */ + MHU_V2_CLEAR_REQUEST(MHUV2_BASE_ADDR); + + return; +} diff --git a/drivers/arm/css/scmi/scmi_ap_core_proto.c b/drivers/arm/css/scmi/scmi_ap_core_proto.c new file mode 100644 index 0000000..2caccc2 --- /dev/null +++ b/drivers/arm/css/scmi/scmi_ap_core_proto.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +#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; +} diff --git a/drivers/arm/css/scmi/scmi_common.c b/drivers/arm/css/scmi/scmi_common.c new file mode 100644 index 0000000..e2c353d --- /dev/null +++ b/drivers/arm/css/scmi/scmi_common.c @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +#include "scmi_private.h" + +#if HW_ASSISTED_COHERENCY +#define scmi_lock_init(lock) +#define scmi_lock_get(lock) spin_lock(lock) +#define scmi_lock_release(lock) spin_unlock(lock) +#else +#define scmi_lock_init(lock) bakery_lock_init(lock) +#define scmi_lock_get(lock) bakery_lock_get(lock) +#define scmi_lock_release(lock) bakery_lock_release(lock) +#endif + + +/* + * Private helper function to get exclusive access to SCMI channel. + */ +void scmi_get_channel(scmi_channel_t *ch) +{ + assert(ch->lock); + scmi_lock_get(ch->lock); + + /* Make sure any previous command has finished */ + assert(SCMI_IS_CHANNEL_FREE( + ((mailbox_mem_t *)(ch->info->scmi_mbx_mem))->status)); +} + +/* + * Private helper function to transfer ownership of channel from AP to SCP. + */ +void scmi_send_sync_command(scmi_channel_t *ch) +{ + mailbox_mem_t *mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem); + + SCMI_MARK_CHANNEL_BUSY(mbx_mem->status); + + /* + * Ensure that any write to the SCMI payload area is seen by SCP before + * we write to the doorbell register. If these 2 writes were reordered + * by the CPU then SCP would read stale payload data + */ + dmbst(); + + ch->info->ring_doorbell(ch->info); + /* + * Ensure that the write to the doorbell register is ordered prior to + * checking whether the channel is free. + */ + dmbsy(); + + /* Wait for channel to be free */ + while (!SCMI_IS_CHANNEL_FREE(mbx_mem->status)) + ; + + /* + * Ensure that any read to the SCMI payload area is done after reading + * mailbox status. If these 2 reads were reordered then the CPU would + * read invalid payload data + */ + dmbld(); +} + +/* + * Private helper function to release exclusive access to SCMI channel. + */ +void scmi_put_channel(scmi_channel_t *ch) +{ + /* Make sure any previous command has finished */ + assert(SCMI_IS_CHANNEL_FREE( + ((mailbox_mem_t *)(ch->info->scmi_mbx_mem))->status)); + + assert(ch->lock); + scmi_lock_release(ch->lock); +} + +/* + * API to query the SCMI protocol version. + */ +int scmi_proto_version(void *p, uint32_t proto_id, uint32_t *version) +{ + 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(proto_id, SCMI_PROTO_VERSION_MSG, + token); + mbx_mem->len = SCMI_PROTO_VERSION_MSG_LEN; + mbx_mem->flags = SCMI_FLAG_RESP_POLL; + + scmi_send_sync_command(ch); + + /* Get the return values */ + SCMI_PAYLOAD_RET_VAL2(mbx_mem->payload, ret, *version); + assert(mbx_mem->len == SCMI_PROTO_VERSION_RESP_LEN); + assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header)); + + scmi_put_channel(ch); + + return ret; +} + +/* + * API to query the protocol message attributes for a SCMI protocol. + */ +int scmi_proto_msg_attr(void *p, uint32_t proto_id, + uint32_t command_id, 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(proto_id, + SCMI_PROTO_MSG_ATTR_MSG, token); + mbx_mem->len = SCMI_PROTO_MSG_ATTR_MSG_LEN; + mbx_mem->flags = SCMI_FLAG_RESP_POLL; + SCMI_PAYLOAD_ARG1(mbx_mem->payload, command_id); + + scmi_send_sync_command(ch); + + /* Get the return values */ + SCMI_PAYLOAD_RET_VAL2(mbx_mem->payload, ret, *attr); + assert(mbx_mem->len == SCMI_PROTO_MSG_ATTR_RESP_LEN); + assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header)); + + scmi_put_channel(ch); + + return ret; +} + +/* + * SCMI Driver initialization API. Returns initialized channel on success + * or NULL on error. The return type is an opaque void pointer. + */ +void *scmi_init(scmi_channel_t *ch) +{ + uint32_t version; + int ret; + + assert(ch && ch->info); + assert(ch->info->db_reg_addr); + assert(ch->info->db_modify_mask); + assert(ch->info->db_preserve_mask); + assert(ch->info->ring_doorbell != NULL); + + assert(ch->lock); + + scmi_lock_init(ch->lock); + + ch->is_initialized = 1; + + ret = scmi_proto_version(ch, SCMI_PWR_DMN_PROTO_ID, &version); + if (ret != SCMI_E_SUCCESS) { + WARN("SCMI power domain protocol version message failed"); + goto error; + } + + if (!is_scmi_version_compatible(SCMI_PWR_DMN_PROTO_VER, version)) { + WARN("SCMI power domain protocol version 0x%x incompatible with driver version 0x%x", + version, SCMI_PWR_DMN_PROTO_VER); + goto error; + } + + VERBOSE("SCMI power domain protocol version 0x%x detected\n", version); + + ret = scmi_proto_version(ch, SCMI_SYS_PWR_PROTO_ID, &version); + if ((ret != SCMI_E_SUCCESS)) { + WARN("SCMI system power protocol version message failed"); + goto error; + } + + if (!is_scmi_version_compatible(SCMI_SYS_PWR_PROTO_VER, version)) { + WARN("SCMI system power management protocol version 0x%x incompatible with driver version 0x%x", + version, SCMI_SYS_PWR_PROTO_VER); + goto error; + } + + VERBOSE("SCMI system power management protocol version 0x%x detected\n", + version); + + INFO("SCMI driver initialized\n"); + + return (void *)ch; + +error: + ch->is_initialized = 0; + return NULL; +} diff --git a/drivers/arm/css/scmi/scmi_private.h b/drivers/arm/css/scmi/scmi_private.h new file mode 100644 index 0000000..6530573 --- /dev/null +++ b/drivers/arm/css/scmi/scmi_private.h @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SCMI_PRIVATE_H +#define SCMI_PRIVATE_H + +#include + +/* + * SCMI power domain management protocol message and response lengths. It is + * calculated as sum of length in bytes of the message header (4) and payload + * area (the number of bytes of parameters or return values in the payload). + */ +#define SCMI_PROTO_VERSION_MSG_LEN 4 +#define SCMI_PROTO_VERSION_RESP_LEN 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 + +#define SCMI_PWR_STATE_GET_MSG_LEN 8 +#define SCMI_PWR_STATE_GET_RESP_LEN 12 + +#define SCMI_SYS_PWR_STATE_SET_MSG_LEN 12 +#define SCMI_SYS_PWR_STATE_SET_RESP_LEN 8 + +#define SCMI_SYS_PWR_STATE_GET_MSG_LEN 4 +#define SCMI_SYS_PWR_STATE_GET_RESP_LEN 12 + +/* SCMI message header format bit field */ +#define SCMI_MSG_ID_SHIFT 0 +#define SCMI_MSG_ID_WIDTH 8 +#define SCMI_MSG_ID_MASK ((1 << SCMI_MSG_ID_WIDTH) - 1) + +#define SCMI_MSG_TYPE_SHIFT 8 +#define SCMI_MSG_TYPE_WIDTH 2 +#define SCMI_MSG_TYPE_MASK ((1 << SCMI_MSG_TYPE_WIDTH) - 1) + +#define SCMI_MSG_PROTO_ID_SHIFT 10 +#define SCMI_MSG_PROTO_ID_WIDTH 8 +#define SCMI_MSG_PROTO_ID_MASK ((1 << SCMI_MSG_PROTO_ID_WIDTH) - 1) + +#define SCMI_MSG_TOKEN_SHIFT 18 +#define SCMI_MSG_TOKEN_WIDTH 10 +#define SCMI_MSG_TOKEN_MASK ((1 << SCMI_MSG_TOKEN_WIDTH) - 1) + + +/* SCMI mailbox flags */ +#define SCMI_FLAG_RESP_POLL 0 +#define SCMI_FLAG_RESP_INT 1 + +/* SCMI power domain protocol `POWER_STATE_SET` message flags */ +#define SCMI_PWR_STATE_SET_FLAG_SYNC 0 +#define SCMI_PWR_STATE_SET_FLAG_ASYNC 1 + +/* + * Helper macro to create an SCMI message header given protocol, message id + * and token. + */ +#define SCMI_MSG_CREATE(_protocol, _msg_id, _token) \ + ((((_protocol) & SCMI_MSG_PROTO_ID_MASK) << SCMI_MSG_PROTO_ID_SHIFT) | \ + (((_msg_id) & SCMI_MSG_ID_MASK) << SCMI_MSG_ID_SHIFT) | \ + (((_token) & SCMI_MSG_TOKEN_MASK) << SCMI_MSG_TOKEN_SHIFT)) + +/* Helper macro to get the token from a SCMI message header */ +#define SCMI_MSG_GET_TOKEN(_msg) \ + (((_msg) >> SCMI_MSG_TOKEN_SHIFT) & SCMI_MSG_TOKEN_MASK) + +/* SCMI Channel Status bit fields */ +#define SCMI_CH_STATUS_RES0_MASK 0xFFFFFFFE +#define SCMI_CH_STATUS_FREE_SHIFT 0 +#define SCMI_CH_STATUS_FREE_WIDTH 1 +#define SCMI_CH_STATUS_FREE_MASK ((1 << SCMI_CH_STATUS_FREE_WIDTH) - 1) + +/* Helper macros to check and write the channel status */ +#define SCMI_IS_CHANNEL_FREE(status) \ + (!!(((status) >> SCMI_CH_STATUS_FREE_SHIFT) & SCMI_CH_STATUS_FREE_MASK)) + +#define SCMI_MARK_CHANNEL_BUSY(status) do { \ + assert(SCMI_IS_CHANNEL_FREE(status)); \ + (status) &= ~(SCMI_CH_STATUS_FREE_MASK << \ + SCMI_CH_STATUS_FREE_SHIFT); \ + } while (0) + +/* Helper macros to copy arguments to the mailbox payload */ +#define SCMI_PAYLOAD_ARG1(payld_arr, arg1) \ + mmio_write_32((uintptr_t)&payld_arr[0], arg1) + +#define SCMI_PAYLOAD_ARG2(payld_arr, arg1, arg2) do { \ + SCMI_PAYLOAD_ARG1(payld_arr, arg1); \ + mmio_write_32((uintptr_t)&payld_arr[1], arg2); \ + } while (0) + +#define SCMI_PAYLOAD_ARG3(payld_arr, arg1, arg2, arg3) do { \ + SCMI_PAYLOAD_ARG2(payld_arr, arg1, arg2); \ + mmio_write_32((uintptr_t)&payld_arr[2], arg3); \ + } while (0) + +/* Helper macros to read return values from the mailbox payload */ +#define SCMI_PAYLOAD_RET_VAL1(payld_arr, val1) \ + (val1) = mmio_read_32((uintptr_t)&payld_arr[0]) + +#define SCMI_PAYLOAD_RET_VAL2(payld_arr, val1, val2) do { \ + SCMI_PAYLOAD_RET_VAL1(payld_arr, val1); \ + (val2) = mmio_read_32((uintptr_t)&payld_arr[1]); \ + } while (0) + +#define SCMI_PAYLOAD_RET_VAL3(payld_arr, val1, val2, val3) do { \ + SCMI_PAYLOAD_RET_VAL2(payld_arr, val1, val2); \ + (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. + */ +typedef struct mailbox_mem { + uint32_t res_a; /* Reserved */ + volatile uint32_t status; + uint64_t res_b; /* Reserved */ + uint32_t flags; + volatile uint32_t len; + uint32_t msg_header; + uint32_t payload[]; +} mailbox_mem_t; + + +/* Private APIs for use within SCMI driver */ +void scmi_get_channel(scmi_channel_t *ch); +void scmi_send_sync_command(scmi_channel_t *ch); +void scmi_put_channel(scmi_channel_t *ch); + +static inline void validate_scmi_channel(scmi_channel_t *ch) +{ + assert(ch && ch->is_initialized); + assert(ch->info && ch->info->scmi_mbx_mem); +} + +#endif /* SCMI_PRIVATE_H */ diff --git a/drivers/arm/css/scmi/scmi_pwr_dmn_proto.c b/drivers/arm/css/scmi/scmi_pwr_dmn_proto.c new file mode 100644 index 0000000..70165de --- /dev/null +++ b/drivers/arm/css/scmi/scmi_pwr_dmn_proto.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +#include "scmi_private.h" + +/* + * API to set the SCMI power domain power state. + */ +int scmi_pwr_state_set(void *p, uint32_t domain_id, + uint32_t scmi_pwr_state) +{ + mailbox_mem_t *mbx_mem; + int token = 0, ret; + + /* + * Only asynchronous mode of `set power state` command is allowed on + * application processors. + */ + uint32_t pwr_state_set_msg_flag = SCMI_PWR_STATE_SET_FLAG_ASYNC; + 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_PWR_DMN_PROTO_ID, + SCMI_PWR_STATE_SET_MSG, token); + mbx_mem->len = SCMI_PWR_STATE_SET_MSG_LEN; + mbx_mem->flags = SCMI_FLAG_RESP_POLL; + SCMI_PAYLOAD_ARG3(mbx_mem->payload, pwr_state_set_msg_flag, + domain_id, scmi_pwr_state); + + scmi_send_sync_command(ch); + + /* Get the return values */ + SCMI_PAYLOAD_RET_VAL1(mbx_mem->payload, ret); + assert(mbx_mem->len == SCMI_PWR_STATE_SET_RESP_LEN); + assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header)); + + scmi_put_channel(ch); + + return ret; +} + +/* + * API to get the SCMI power domain power state. + */ +int scmi_pwr_state_get(void *p, uint32_t domain_id, + uint32_t *scmi_pwr_state) +{ + 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_PWR_DMN_PROTO_ID, + SCMI_PWR_STATE_GET_MSG, token); + mbx_mem->len = SCMI_PWR_STATE_GET_MSG_LEN; + mbx_mem->flags = SCMI_FLAG_RESP_POLL; + SCMI_PAYLOAD_ARG1(mbx_mem->payload, domain_id); + + scmi_send_sync_command(ch); + + /* Get the return values */ + SCMI_PAYLOAD_RET_VAL2(mbx_mem->payload, ret, *scmi_pwr_state); + assert(mbx_mem->len == SCMI_PWR_STATE_GET_RESP_LEN); + assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header)); + + scmi_put_channel(ch); + + return ret; +} diff --git a/drivers/arm/css/scmi/scmi_sys_pwr_proto.c b/drivers/arm/css/scmi/scmi_sys_pwr_proto.c new file mode 100644 index 0000000..a27c4a5 --- /dev/null +++ b/drivers/arm/css/scmi/scmi_sys_pwr_proto.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +#include "scmi_private.h" + +/* + * API to set the SCMI system power state + */ +int scmi_sys_pwr_state_set(void *p, uint32_t flags, uint32_t system_state) +{ + 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_SYS_PWR_PROTO_ID, + SCMI_SYS_PWR_STATE_SET_MSG, token); + mbx_mem->len = SCMI_SYS_PWR_STATE_SET_MSG_LEN; + mbx_mem->flags = SCMI_FLAG_RESP_POLL; + SCMI_PAYLOAD_ARG2(mbx_mem->payload, flags, system_state); + + scmi_send_sync_command(ch); + + /* Get the return values */ + SCMI_PAYLOAD_RET_VAL1(mbx_mem->payload, ret); + assert(mbx_mem->len == SCMI_SYS_PWR_STATE_SET_RESP_LEN); + assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header)); + + scmi_put_channel(ch); + + return ret; +} + +/* + * API to get the SCMI system power state + */ +int scmi_sys_pwr_state_get(void *p, uint32_t *system_state) +{ + 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_SYS_PWR_PROTO_ID, + SCMI_SYS_PWR_STATE_GET_MSG, token); + mbx_mem->len = SCMI_SYS_PWR_STATE_GET_MSG_LEN; + mbx_mem->flags = SCMI_FLAG_RESP_POLL; + + scmi_send_sync_command(ch); + + /* Get the return values */ + SCMI_PAYLOAD_RET_VAL2(mbx_mem->payload, ret, *system_state); + assert(mbx_mem->len == SCMI_SYS_PWR_STATE_GET_RESP_LEN); + assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header)); + + scmi_put_channel(ch); + + return ret; +} diff --git a/drivers/arm/css/scp/css_bom_bootloader.c b/drivers/arm/css/scp/css_bom_bootloader.c new file mode 100644 index 0000000..1fc1270 --- /dev/null +++ b/drivers/arm/css/scp/css_bom_bootloader.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* ID of the MHU slot used for the BOM protocol */ +#define BOM_MHU_SLOT_ID 0 + +/* Boot commands sent from AP -> SCP */ +#define BOOT_CMD_INFO 0x00 +#define BOOT_CMD_DATA 0x01 + +/* BOM command header */ +typedef struct { + uint32_t id : 8; + uint32_t reserved : 24; +} bom_cmd_t; + +typedef struct { + uint32_t image_size; + uint32_t checksum; +} cmd_info_payload_t; + +/* + * Unlike the SCPI protocol, the boot protocol uses the same memory region + * for both AP -> SCP and SCP -> AP transfers; define the address of this... + */ +#define BOM_SHARED_MEM PLAT_CSS_SCP_COM_SHARED_MEM_BASE +#define BOM_CMD_HEADER ((bom_cmd_t *) BOM_SHARED_MEM) +#define BOM_CMD_PAYLOAD ((void *) (BOM_SHARED_MEM + sizeof(bom_cmd_t))) + +typedef struct { + /* Offset from the base address of the Trusted RAM */ + uint32_t offset; + uint32_t block_size; +} cmd_data_payload_t; + +/* + * All CSS platforms load SCP_BL2/SCP_BL2U just below BL2 (this is where BL31 + * usually resides except when ARM_BL31_IN_DRAM is + * set). Ensure that SCP_BL2/SCP_BL2U do not overflow into shared RAM and + * the tb_fw_config. + */ +CASSERT(SCP_BL2_LIMIT <= BL2_BASE, assert_scp_bl2_overwrite_bl2); +CASSERT(SCP_BL2U_LIMIT <= BL2_BASE, assert_scp_bl2u_overwrite_bl2); + +CASSERT(SCP_BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2_overflow); +CASSERT(SCP_BL2U_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2u_overflow); + +static void scp_boot_message_start(void) +{ + mhu_secure_message_start(BOM_MHU_SLOT_ID); +} + +static void scp_boot_message_send(size_t payload_size) +{ + /* Ensure that any write to the BOM payload area is seen by SCP before + * we write to the MHU register. If these 2 writes were reordered by + * the CPU then SCP would read stale payload data */ + dmbst(); + + /* Send command to SCP */ + mhu_secure_message_send(BOM_MHU_SLOT_ID); +} + +static uint32_t scp_boot_message_wait(size_t size) +{ + uint32_t mhu_status; + + mhu_status = mhu_secure_message_wait(); + + /* Expect an SCP Boot Protocol message, reject any other protocol */ + if (mhu_status != (1 << BOM_MHU_SLOT_ID)) { + ERROR("MHU: Unexpected protocol (MHU status: 0x%x)\n", + mhu_status); + panic(); + } + + /* Ensure that any read to the BOM payload area is done after reading + * the MHU register. If these 2 reads were reordered then the CPU would + * read invalid payload data */ + dmbld(); + + return *(uint32_t *) BOM_SHARED_MEM; +} + +static void scp_boot_message_end(void) +{ + mhu_secure_message_end(BOM_MHU_SLOT_ID); +} + +int css_scp_boot_image_xfer(void *image, unsigned int image_size) +{ + uint32_t response; + uint32_t checksum; + cmd_info_payload_t *cmd_info_payload; + cmd_data_payload_t *cmd_data_payload; + + assert((uintptr_t) image == SCP_BL2_BASE); + + if ((image_size == 0) || (image_size % 4 != 0)) { + ERROR("Invalid size for the SCP_BL2 image. Must be a multiple of " + "4 bytes and not zero (current size = 0x%x)\n", + image_size); + return -1; + } + + /* Extract the checksum from the image */ + checksum = *(uint32_t *) image; + image = (char *) image + sizeof(checksum); + image_size -= sizeof(checksum); + + mhu_secure_init(); + + VERBOSE("Send info about the SCP_BL2 image to be transferred to SCP\n"); + + /* + * Send information about the SCP firmware image about to be transferred + * to SCP + */ + scp_boot_message_start(); + + BOM_CMD_HEADER->id = BOOT_CMD_INFO; + cmd_info_payload = BOM_CMD_PAYLOAD; + cmd_info_payload->image_size = image_size; + cmd_info_payload->checksum = checksum; + + scp_boot_message_send(sizeof(*cmd_info_payload)); +#if CSS_DETECT_PRE_1_7_0_SCP + { + const uint32_t deprecated_scp_nack_cmd = 0x404; + uint32_t mhu_status; + + VERBOSE("Detecting SCP version incompatibility\n"); + + mhu_status = mhu_secure_message_wait(); + if (mhu_status == deprecated_scp_nack_cmd) { + ERROR("Detected an incompatible version of the SCP firmware.\n"); + ERROR("Only versions from v1.7.0 onwards are supported.\n"); + ERROR("Please update the SCP firmware.\n"); + return -1; + } + + VERBOSE("SCP version looks OK\n"); + } +#endif /* CSS_DETECT_PRE_1_7_0_SCP */ + response = scp_boot_message_wait(sizeof(response)); + scp_boot_message_end(); + + if (response != 0) { + ERROR("SCP BOOT_CMD_INFO returned error %u\n", response); + return -1; + } + + VERBOSE("Transferring SCP_BL2 image to SCP\n"); + + /* Transfer SCP_BL2 image to SCP */ + scp_boot_message_start(); + + BOM_CMD_HEADER->id = BOOT_CMD_DATA; + cmd_data_payload = BOM_CMD_PAYLOAD; + cmd_data_payload->offset = (uintptr_t) image - ARM_TRUSTED_SRAM_BASE; + cmd_data_payload->block_size = image_size; + + scp_boot_message_send(sizeof(*cmd_data_payload)); + response = scp_boot_message_wait(sizeof(response)); + scp_boot_message_end(); + + if (response != 0) { + ERROR("SCP BOOT_CMD_DATA returned error %u\n", response); + return -1; + } + + return 0; +} + +int css_scp_boot_ready(void) +{ + VERBOSE("Waiting for SCP to signal it is ready to go on\n"); + + /* Wait for SCP to signal it's ready */ + return scpi_wait_ready(); +} diff --git a/drivers/arm/css/scp/css_pm_scmi.c b/drivers/arm/css/scp/css_pm_scmi.c new file mode 100644 index 0000000..1966c44 --- /dev/null +++ b/drivers/arm/css/scp/css_pm_scmi.c @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * This file implements the SCP helper functions using SCMI protocol. + */ + +/* + * SCMI power state parameter bit field encoding for ARM CSS platforms. + * + * 31 20 19 16 15 12 11 8 7 4 3 0 + * +-------------------------------------------------------------+ + * | SBZ | Max level | Level 3 | Level 2 | Level 1 | Level 0 | + * | | | state | state | state | state | + * +-------------------------------------------------------------+ + * + * `Max level` encodes the highest level that has a valid power state + * encoded in the power state. + */ +#define SCMI_PWR_STATE_MAX_PWR_LVL_SHIFT 16 +#define SCMI_PWR_STATE_MAX_PWR_LVL_WIDTH 4 +#define SCMI_PWR_STATE_MAX_PWR_LVL_MASK \ + ((1 << SCMI_PWR_STATE_MAX_PWR_LVL_WIDTH) - 1) +#define SCMI_SET_PWR_STATE_MAX_PWR_LVL(_power_state, _max_level) \ + (_power_state) |= ((_max_level) & SCMI_PWR_STATE_MAX_PWR_LVL_MASK)\ + << SCMI_PWR_STATE_MAX_PWR_LVL_SHIFT +#define SCMI_GET_PWR_STATE_MAX_PWR_LVL(_power_state) \ + (((_power_state) >> SCMI_PWR_STATE_MAX_PWR_LVL_SHIFT) \ + & SCMI_PWR_STATE_MAX_PWR_LVL_MASK) + +#define SCMI_PWR_STATE_LVL_WIDTH 4 +#define SCMI_PWR_STATE_LVL_MASK \ + ((1 << SCMI_PWR_STATE_LVL_WIDTH) - 1) +#define SCMI_SET_PWR_STATE_LVL(_power_state, _level, _level_state) \ + (_power_state) |= ((_level_state) & SCMI_PWR_STATE_LVL_MASK) \ + << (SCMI_PWR_STATE_LVL_WIDTH * (_level)) +#define SCMI_GET_PWR_STATE_LVL(_power_state, _level) \ + (((_power_state) >> (SCMI_PWR_STATE_LVL_WIDTH * (_level))) & \ + SCMI_PWR_STATE_LVL_MASK) + +/* + * The SCMI power state enumeration for a power domain level + */ +typedef enum { + scmi_power_state_off = 0, + scmi_power_state_on = 1, + scmi_power_state_sleep = 2, +} scmi_power_state_t; + +/* + * The global handle for invoking the SCMI driver APIs after the driver + * has been initialized. + */ +static void *scmi_handle; + +/* The SCMI channel global object */ +static scmi_channel_t channel; + +ARM_SCMI_INSTANTIATE_LOCK; + +/* + * Helper function to suspend a CPU power domain and its parent power domains + * if applicable. + */ +void css_scp_suspend(const struct psci_power_state *target_state) +{ + int ret; + + /* At least power domain level 0 should be specified to be suspended */ + assert(target_state->pwr_domain_state[ARM_PWR_LVL0] == + ARM_LOCAL_STATE_OFF); + + /* Check if power down at system power domain level is requested */ + if (css_system_pwr_state(target_state) == ARM_LOCAL_STATE_OFF) { + /* Issue SCMI command for SYSTEM_SUSPEND */ + ret = scmi_sys_pwr_state_set(scmi_handle, + SCMI_SYS_PWR_FORCEFUL_REQ, + SCMI_SYS_PWR_SUSPEND); + if (ret != SCMI_E_SUCCESS) { + ERROR("SCMI system power domain suspend return 0x%x unexpected\n", + ret); + panic(); + } + return; + } +#if !HW_ASSISTED_COHERENCY + int lvl; + uint32_t scmi_pwr_state = 0; + /* + * If we reach here, then assert that power down at system power domain + * level is running. + */ + assert(css_system_pwr_state(target_state) == ARM_LOCAL_STATE_RUN); + + /* For level 0, specify `scmi_power_state_sleep` as the power state */ + SCMI_SET_PWR_STATE_LVL(scmi_pwr_state, ARM_PWR_LVL0, + scmi_power_state_sleep); + + for (lvl = ARM_PWR_LVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) { + if (target_state->pwr_domain_state[lvl] == ARM_LOCAL_STATE_RUN) + break; + + assert(target_state->pwr_domain_state[lvl] == + ARM_LOCAL_STATE_OFF); + /* + * Specify `scmi_power_state_off` as power state for higher + * levels. + */ + SCMI_SET_PWR_STATE_LVL(scmi_pwr_state, lvl, + scmi_power_state_off); + } + + SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1); + + ret = scmi_pwr_state_set(scmi_handle, + plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()], + scmi_pwr_state); + + if (ret != SCMI_E_SUCCESS) { + ERROR("SCMI set power state command return 0x%x unexpected\n", + ret); + panic(); + } +#endif +} + +/* + * Helper function to turn off a CPU power domain and its parent power domains + * if applicable. + */ +void css_scp_off(const struct psci_power_state *target_state) +{ + int lvl = 0, ret; + uint32_t scmi_pwr_state = 0; + + /* At-least the CPU level should be specified to be OFF */ + assert(target_state->pwr_domain_state[ARM_PWR_LVL0] == + ARM_LOCAL_STATE_OFF); + + /* PSCI CPU OFF cannot be used to turn OFF system power domain */ + assert(css_system_pwr_state(target_state) == ARM_LOCAL_STATE_RUN); + + for (; lvl <= PLAT_MAX_PWR_LVL; lvl++) { + if (target_state->pwr_domain_state[lvl] == ARM_LOCAL_STATE_RUN) + break; + + assert(target_state->pwr_domain_state[lvl] == + ARM_LOCAL_STATE_OFF); + SCMI_SET_PWR_STATE_LVL(scmi_pwr_state, lvl, + scmi_power_state_off); + } + + SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1); + + ret = scmi_pwr_state_set(scmi_handle, + plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()], + scmi_pwr_state); + + if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) { + ERROR("SCMI set power state command return 0x%x unexpected\n", + ret); + panic(); + } +} + +/* + * Helper function to turn ON a CPU power domain and its parent power domains + * if applicable. + */ +void css_scp_on(u_register_t mpidr) +{ + int lvl = 0, ret, core_pos; + uint32_t scmi_pwr_state = 0; + + for (; lvl <= PLAT_MAX_PWR_LVL; lvl++) + SCMI_SET_PWR_STATE_LVL(scmi_pwr_state, lvl, + scmi_power_state_on); + + SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1); + + core_pos = plat_core_pos_by_mpidr(mpidr); + assert(core_pos >= 0 && core_pos < PLATFORM_CORE_COUNT); + + ret = scmi_pwr_state_set(scmi_handle, + plat_css_core_pos_to_scmi_dmn_id_map[core_pos], + scmi_pwr_state); + + if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) { + ERROR("SCMI set power state command return 0x%x unexpected\n", + ret); + panic(); + } +} + +/* + * Helper function to get the power state of a power domain node as reported + * by the SCP. + */ +int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level) +{ + int ret, cpu_idx; + uint32_t scmi_pwr_state = 0, lvl_state; + + /* We don't support get power state at the system power domain level */ + if ((power_level > PLAT_MAX_PWR_LVL) || + (power_level == CSS_SYSTEM_PWR_DMN_LVL)) { + WARN("Invalid power level %u specified for SCMI get power state\n", + power_level); + return PSCI_E_INVALID_PARAMS; + } + + cpu_idx = plat_core_pos_by_mpidr(mpidr); + assert(cpu_idx > -1); + + ret = scmi_pwr_state_get(scmi_handle, + plat_css_core_pos_to_scmi_dmn_id_map[cpu_idx], + &scmi_pwr_state); + + if (ret != SCMI_E_SUCCESS) { + WARN("SCMI get power state command return 0x%x unexpected\n", + ret); + return PSCI_E_INVALID_PARAMS; + } + + /* + * Find the maximum power level described in the get power state + * command. If it is less than the requested power level, then assume + * the requested power level is ON. + */ + if (SCMI_GET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state) < power_level) + return HW_ON; + + lvl_state = SCMI_GET_PWR_STATE_LVL(scmi_pwr_state, power_level); + if (lvl_state == scmi_power_state_on) + return HW_ON; + + assert((lvl_state == scmi_power_state_off) || + (lvl_state == scmi_power_state_sleep)); + return HW_OFF; +} + +void __dead2 css_scp_system_off(int state) +{ + int ret; + + /* + * Disable GIC CPU interface to prevent pending interrupt from waking + * up the AP from WFI. + */ + plat_arm_gic_cpuif_disable(); + + /* + * Issue SCMI command. First issue a graceful + * request and if that fails force the request. + */ + ret = scmi_sys_pwr_state_set(scmi_handle, + SCMI_SYS_PWR_FORCEFUL_REQ, + state); + + if (ret != SCMI_E_SUCCESS) { + ERROR("SCMI system power state set 0x%x returns unexpected 0x%x\n", + state, ret); + panic(); + } + wfi(); + ERROR("CSS set power state: operation not handled.\n"); + panic(); +} + +/* + * Helper function to shutdown the system via SCMI. + */ +void __dead2 css_scp_sys_shutdown(void) +{ + css_scp_system_off(SCMI_SYS_PWR_SHUTDOWN); +} + +/* + * Helper function to reset the system via SCMI. + */ +void __dead2 css_scp_sys_reboot(void) +{ + css_scp_system_off(SCMI_SYS_PWR_COLD_RESET); +} + +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 __init plat_arm_pwrc_setup(void) +{ + channel.info = plat_css_get_scmi_info(); + channel.lock = ARM_SCMI_LOCK_GET_INSTANCE; + scmi_handle = scmi_init(&channel); + if (scmi_handle == NULL) { + ERROR("SCMI Initialization failed\n"); + panic(); + } + if (scmi_ap_core_init(&channel) < 0) { + ERROR("SCMI AP core protocol initialization failed\n"); + panic(); + } +} + +/****************************************************************************** + * This function overrides the default definition for ARM platforms. Initialize + * the SCMI driver, query capability via SCMI and modify the PSCI capability + * based on that. + *****************************************************************************/ +const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops) +{ + uint32_t msg_attr; + int ret; + + assert(scmi_handle); + + /* Check that power domain POWER_STATE_SET message is supported */ + ret = scmi_proto_msg_attr(scmi_handle, SCMI_PWR_DMN_PROTO_ID, + SCMI_PWR_STATE_SET_MSG, &msg_attr); + if (ret != SCMI_E_SUCCESS) { + ERROR("Set power state command is not supported by SCMI\n"); + panic(); + } + + /* + * Don't support PSCI NODE_HW_STATE call if SCMI doesn't support + * POWER_STATE_GET message. + */ + ret = scmi_proto_msg_attr(scmi_handle, SCMI_PWR_DMN_PROTO_ID, + SCMI_PWR_STATE_GET_MSG, &msg_attr); + if (ret != SCMI_E_SUCCESS) + ops->get_node_hw_state = NULL; + + /* Check if the SCMI SYSTEM_POWER_STATE_SET message is supported */ + ret = scmi_proto_msg_attr(scmi_handle, SCMI_SYS_PWR_PROTO_ID, + SCMI_SYS_PWR_STATE_SET_MSG, &msg_attr); + if (ret != SCMI_E_SUCCESS) { + /* System power management operations are not supported */ + ops->system_off = NULL; + ops->system_reset = NULL; + ops->get_sys_suspend_power_state = NULL; + } else { + if (!(msg_attr & SCMI_SYS_PWR_SUSPEND_SUPPORTED)) { + /* + * System power management protocol is available, but + * it does not support SYSTEM SUSPEND. + */ + ops->get_sys_suspend_power_state = NULL; + } + if (!(msg_attr & SCMI_SYS_PWR_WARM_RESET_SUPPORTED)) { + /* + * WARM reset is not available. + */ + ops->system_reset2 = NULL; + } + } + + return ops; +} + +int css_system_reset2(int is_vendor, int reset_type, u_register_t cookie) +{ + if (is_vendor || (reset_type != PSCI_RESET2_SYSTEM_WARM_RESET)) + return PSCI_E_INVALID_PARAMS; + + css_scp_system_off(SCMI_SYS_PWR_WARM_RESET); + /* + * css_scp_system_off cannot return (it is a __dead function), + * but css_system_reset2 has to return some value, even in + * this case. + */ + 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 diff --git a/drivers/arm/css/scp/css_pm_scpi.c b/drivers/arm/css/scp/css_pm_scpi.c new file mode 100644 index 0000000..b4019ce --- /dev/null +++ b/drivers/arm/css/scp/css_pm_scpi.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include + +/* + * This file implements the SCP power management functions using SCPI protocol. + */ + +/* + * Helper function to inform power down state to SCP. + */ +void css_scp_suspend(const struct psci_power_state *target_state) +{ + uint32_t cluster_state = scpi_power_on; + uint32_t system_state = scpi_power_on; + + /* Check if power down at system power domain level is requested */ + if (css_system_pwr_state(target_state) == ARM_LOCAL_STATE_OFF) + system_state = scpi_power_retention; + + /* Cluster is to be turned off, so disable coherency */ + if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) + cluster_state = scpi_power_off; + + /* + * Ask the SCP to power down the appropriate components depending upon + * their state. + */ + scpi_set_css_power_state(read_mpidr_el1(), + scpi_power_off, + cluster_state, + system_state); +} + +/* + * Helper function to turn off a CPU power domain and its parent power domains + * if applicable. Since SCPI doesn't differentiate between OFF and suspend, we + * call the suspend helper here. + */ +void css_scp_off(const struct psci_power_state *target_state) +{ + css_scp_suspend(target_state); +} + +/* + * Helper function to turn ON a CPU power domain and its parent power domains + * if applicable. + */ +void css_scp_on(u_register_t mpidr) +{ + /* + * SCP takes care of powering up parent power domains so we + * only need to care about level 0 + */ + scpi_set_css_power_state(mpidr, scpi_power_on, scpi_power_on, + scpi_power_on); +} + +/* + * Helper function to get the power state of a power domain node as reported + * by the SCP. + */ +int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level) +{ + int rc, element; + unsigned int cpu_state, cluster_state; + + /* + * The format of 'power_level' is implementation-defined, but 0 must + * mean a CPU. We also allow 1 to denote the cluster + */ + if (power_level != ARM_PWR_LVL0 && power_level != ARM_PWR_LVL1) + return PSCI_E_INVALID_PARAMS; + + /* Query SCP */ + rc = scpi_get_css_power_state(mpidr, &cpu_state, &cluster_state); + if (rc != 0) + return PSCI_E_INVALID_PARAMS; + + /* Map power states of CPU and cluster to expected PSCI return codes */ + if (power_level == ARM_PWR_LVL0) { + /* + * The CPU state returned by SCP is an 8-bit bit mask + * corresponding to each CPU in the cluster + */ +#if ARM_PLAT_MT + /* + * The current SCPI driver only caters for single-threaded + * platforms. Hence we ignore the thread ID (which is always 0) + * for such platforms. + */ + element = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; +#else + element = mpidr & MPIDR_AFFLVL_MASK; +#endif /* ARM_PLAT_MT */ + return CSS_CPU_PWR_STATE(cpu_state, element) == + CSS_CPU_PWR_STATE_ON ? HW_ON : HW_OFF; + } else { + assert(cluster_state == CSS_CLUSTER_PWR_STATE_ON || + cluster_state == CSS_CLUSTER_PWR_STATE_OFF); + return cluster_state == CSS_CLUSTER_PWR_STATE_ON ? HW_ON : + HW_OFF; + } +} + +/* + * Helper function to shutdown the system via SCPI. + */ +void __dead2 css_scp_sys_shutdown(void) +{ + uint32_t response; + + /* + * Disable GIC CPU interface to prevent pending interrupt + * from waking up the AP from WFI. + */ + plat_arm_gic_cpuif_disable(); + + /* Send the power down request to the SCP */ + response = scpi_sys_power_state(scpi_system_shutdown); + + if (response != SCP_OK) { + ERROR("CSS System Off: SCP error %u.\n", response); + panic(); + } + wfi(); + ERROR("CSS System Off: operation not handled.\n"); + panic(); +} + +/* + * Helper function to reset the system via SCPI. + */ +void __dead2 css_scp_sys_reboot(void) +{ + uint32_t response; + + /* + * Disable GIC CPU interface to prevent pending interrupt + * from waking up the AP from WFI. + */ + plat_arm_gic_cpuif_disable(); + + /* Send the system reset request to the SCP */ + response = scpi_sys_power_state(scpi_system_reboot); + + if (response != SCP_OK) { + ERROR("CSS System Reset: SCP error %u.\n", response); + panic(); + } + wfi(); + ERROR("CSS System Reset: operation not handled.\n"); + panic(); +} diff --git a/drivers/arm/css/scp/css_sds.c b/drivers/arm/css/scp/css_sds.c new file mode 100644 index 0000000..e42ee10 --- /dev/null +++ b/drivers/arm/css/scp/css_sds.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +int css_scp_boot_image_xfer(void *image, unsigned int image_size) +{ + int ret; + unsigned int image_offset, image_flags; + + ret = sds_init(); + if (ret != SDS_OK) { + ERROR("SCP SDS initialization failed\n"); + panic(); + } + + VERBOSE("Writing SCP image metadata\n"); + image_offset = (uintptr_t) image - ARM_TRUSTED_SRAM_BASE; + ret = sds_struct_write(SDS_SCP_IMG_STRUCT_ID, SDS_SCP_IMG_ADDR_OFFSET, + &image_offset, SDS_SCP_IMG_ADDR_SIZE, + SDS_ACCESS_MODE_NON_CACHED); + if (ret != SDS_OK) + goto sds_fail; + + ret = sds_struct_write(SDS_SCP_IMG_STRUCT_ID, SDS_SCP_IMG_SIZE_OFFSET, + &image_size, SDS_SCP_IMG_SIZE_SIZE, + SDS_ACCESS_MODE_NON_CACHED); + if (ret != SDS_OK) + goto sds_fail; + + VERBOSE("Marking SCP image metadata as valid\n"); + image_flags = SDS_SCP_IMG_VALID_FLAG_BIT; + ret = sds_struct_write(SDS_SCP_IMG_STRUCT_ID, SDS_SCP_IMG_FLAG_OFFSET, + &image_flags, SDS_SCP_IMG_FLAG_SIZE, + SDS_ACCESS_MODE_NON_CACHED); + if (ret != SDS_OK) + goto sds_fail; + + return 0; +sds_fail: + ERROR("SCP SDS write to SCP IMG struct failed\n"); + panic(); +} + +/* + * API to wait for SCP to signal till it's ready after booting the transferred + * image. + */ +int css_scp_boot_ready(void) +{ + uint32_t scp_feature_availability_flags; + int ret, retry = CSS_SCP_READY_10US_RETRIES; + + + VERBOSE("Waiting for SCP RAM to complete its initialization process\n"); + + /* Wait for the SCP RAM Firmware to complete its initialization process */ + while (retry > 0) { + ret = sds_struct_read(SDS_FEATURE_AVAIL_STRUCT_ID, 0, + &scp_feature_availability_flags, + SDS_FEATURE_AVAIL_SIZE, + SDS_ACCESS_MODE_NON_CACHED); + if (ret == SDS_ERR_STRUCT_NOT_FINALIZED) + continue; + + if (ret != SDS_OK) { + ERROR(" sds_struct_read failed\n"); + panic(); + } + + if (scp_feature_availability_flags & + SDS_FEATURE_AVAIL_SCP_RAM_READY_BIT) + return 0; + + udelay(10); + retry--; + } + + ERROR("Timeout of %d ms expired waiting for SCP RAM Ready flag\n", + CSS_SCP_READY_10US_RETRIES/100); + + plat_panic_handler(); +} diff --git a/drivers/arm/css/scpi/css_scpi.c b/drivers/arm/css/scpi/css_scpi.c new file mode 100644 index 0000000..4b73265 --- /dev/null +++ b/drivers/arm/css/scpi/css_scpi.c @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define SCPI_SHARED_MEM_SCP_TO_AP PLAT_CSS_SCP_COM_SHARED_MEM_BASE +#define SCPI_SHARED_MEM_AP_TO_SCP (PLAT_CSS_SCP_COM_SHARED_MEM_BASE \ + + 0x100) + +/* Header and payload addresses for commands from AP to SCP */ +#define SCPI_CMD_HEADER_AP_TO_SCP \ + ((scpi_cmd_t *) SCPI_SHARED_MEM_AP_TO_SCP) +#define SCPI_CMD_PAYLOAD_AP_TO_SCP \ + ((void *) (SCPI_SHARED_MEM_AP_TO_SCP + sizeof(scpi_cmd_t))) + +/* Header and payload addresses for responses from SCP to AP */ +#define SCPI_RES_HEADER_SCP_TO_AP \ + ((scpi_cmd_t *) SCPI_SHARED_MEM_SCP_TO_AP) +#define SCPI_RES_PAYLOAD_SCP_TO_AP \ + ((void *) (SCPI_SHARED_MEM_SCP_TO_AP + sizeof(scpi_cmd_t))) + +/* ID of the MHU slot used for the SCPI protocol */ +#define SCPI_MHU_SLOT_ID 0 + +static void scpi_secure_message_start(void) +{ + mhu_secure_message_start(SCPI_MHU_SLOT_ID); +} + +static void scpi_secure_message_send(size_t payload_size) +{ + /* + * Ensure that any write to the SCPI payload area is seen by SCP before + * we write to the MHU register. If these 2 writes were reordered by + * the CPU then SCP would read stale payload data + */ + dmbst(); + + mhu_secure_message_send(SCPI_MHU_SLOT_ID); +} + +static void scpi_secure_message_receive(scpi_cmd_t *cmd) +{ + uint32_t mhu_status; + + assert(cmd != NULL); + + mhu_status = mhu_secure_message_wait(); + + /* Expect an SCPI message, reject any other protocol */ + if (mhu_status != (1 << SCPI_MHU_SLOT_ID)) { + ERROR("MHU: Unexpected protocol (MHU status: 0x%x)\n", + mhu_status); + panic(); + } + + /* + * Ensure that any read to the SCPI payload area is done after reading + * the MHU register. If these 2 reads were reordered then the CPU would + * read invalid payload data + */ + dmbld(); + + memcpy(cmd, (void *) SCPI_SHARED_MEM_SCP_TO_AP, sizeof(*cmd)); +} + +static void scpi_secure_message_end(void) +{ + mhu_secure_message_end(SCPI_MHU_SLOT_ID); +} + +int scpi_wait_ready(void) +{ + scpi_cmd_t scpi_cmd; + + VERBOSE("Waiting for SCP_READY command...\n"); + + /* Get a message from the SCP */ + scpi_secure_message_start(); + scpi_secure_message_receive(&scpi_cmd); + scpi_secure_message_end(); + + /* We are expecting 'SCP Ready', produce correct error if it's not */ + scpi_status_t status = SCP_OK; + if (scpi_cmd.id != SCPI_CMD_SCP_READY) { + ERROR("Unexpected SCP command: expected command #%u, got command #%u\n", + SCPI_CMD_SCP_READY, scpi_cmd.id); + status = SCP_E_SUPPORT; + } else if (scpi_cmd.size != 0) { + ERROR("SCP_READY command has incorrect size: expected 0, got %u\n", + scpi_cmd.size); + status = SCP_E_SIZE; + } + + VERBOSE("Sending response for SCP_READY command\n"); + + /* + * Send our response back to SCP. + * We are using the same SCPI header, just update the status field. + */ + scpi_cmd.status = status; + scpi_secure_message_start(); + memcpy((void *) SCPI_SHARED_MEM_AP_TO_SCP, &scpi_cmd, sizeof(scpi_cmd)); + scpi_secure_message_send(0); + scpi_secure_message_end(); + + return status == SCP_OK ? 0 : -1; +} + +void scpi_set_css_power_state(unsigned int mpidr, + scpi_power_state_t cpu_state, scpi_power_state_t cluster_state, + scpi_power_state_t css_state) +{ + scpi_cmd_t *cmd; + uint32_t state = 0; + uint32_t *payload_addr; + +#if ARM_PLAT_MT + /* + * The current SCPI driver only caters for single-threaded platforms. + * Hence we ignore the thread ID (which is always 0) for such platforms. + */ + state |= (mpidr >> MPIDR_AFF1_SHIFT) & 0x0f; /* CPU ID */ + state |= ((mpidr >> MPIDR_AFF2_SHIFT) & 0x0f) << 4; /* Cluster ID */ +#else + state |= mpidr & 0x0f; /* CPU ID */ + state |= (mpidr & 0xf00) >> 4; /* Cluster ID */ +#endif /* ARM_PLAT_MT */ + + state |= cpu_state << 8; + state |= cluster_state << 12; + state |= css_state << 16; + + scpi_secure_message_start(); + + /* Populate the command header */ + cmd = SCPI_CMD_HEADER_AP_TO_SCP; + cmd->id = SCPI_CMD_SET_CSS_POWER_STATE; + cmd->set = SCPI_SET_NORMAL; + cmd->sender = 0; + cmd->size = sizeof(state); + /* Populate the command payload */ + payload_addr = SCPI_CMD_PAYLOAD_AP_TO_SCP; + *payload_addr = state; + scpi_secure_message_send(sizeof(state)); + /* + * SCP does not reply to this command in order to avoid MHU interrupts + * from the sender, which could interfere with its power state request. + */ + + scpi_secure_message_end(); +} + +/* + * Query and obtain CSS power state from SCP. + * + * In response to the query, SCP returns power states of all CPUs in all + * clusters of the system. The returned response is then filtered based on the + * supplied MPIDR. Power states of requested cluster and CPUs within are updated + * via. supplied non-NULL pointer arguments. + * + * Returns 0 on success, or -1 on errors. + */ +int scpi_get_css_power_state(unsigned int mpidr, unsigned int *cpu_state_p, + unsigned int *cluster_state_p) +{ + scpi_cmd_t *cmd; + scpi_cmd_t response; + int power_state, cpu, cluster, rc = -1; + + /* + * Extract CPU and cluster membership of the given MPIDR. SCPI caters + * for only up to 0xf clusters, and 8 CPUs per cluster + */ +#if ARM_PLAT_MT + /* + * The current SCPI driver only caters for single-threaded platforms. + * Hence we ignore the thread ID (which is always 0) for such platforms. + */ + cpu = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; + cluster = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK; +#else + cpu = mpidr & MPIDR_AFFLVL_MASK; + cluster = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; +#endif /* ARM_PLAT_MT */ + if (cpu >= 8 || cluster >= 0xf) + return -1; + + scpi_secure_message_start(); + + /* Populate request headers */ + zeromem(SCPI_CMD_HEADER_AP_TO_SCP, sizeof(*cmd)); + cmd = SCPI_CMD_HEADER_AP_TO_SCP; + cmd->id = SCPI_CMD_GET_CSS_POWER_STATE; + + /* + * Send message and wait for SCP's response + */ + scpi_secure_message_send(0); + scpi_secure_message_receive(&response); + + if (response.status != SCP_OK) + goto exit; + + /* Validate SCP response */ + if (!CHECK_RESPONSE(response, cluster)) + goto exit; + + /* Extract power states for required cluster */ + power_state = *(((uint16_t *) SCPI_RES_PAYLOAD_SCP_TO_AP) + cluster); + if (CLUSTER_ID(power_state) != cluster) + goto exit; + + /* Update power state via. pointers */ + if (cluster_state_p) + *cluster_state_p = CLUSTER_POWER_STATE(power_state); + if (cpu_state_p) + *cpu_state_p = CPU_POWER_STATE(power_state); + rc = 0; + +exit: + scpi_secure_message_end(); + return rc; +} + +uint32_t scpi_sys_power_state(scpi_system_state_t system_state) +{ + scpi_cmd_t *cmd; + uint8_t *payload_addr; + scpi_cmd_t response; + + scpi_secure_message_start(); + + /* Populate the command header */ + cmd = SCPI_CMD_HEADER_AP_TO_SCP; + cmd->id = SCPI_CMD_SYS_POWER_STATE; + cmd->set = 0; + cmd->sender = 0; + cmd->size = sizeof(*payload_addr); + /* Populate the command payload */ + payload_addr = SCPI_CMD_PAYLOAD_AP_TO_SCP; + *payload_addr = system_state & 0xff; + scpi_secure_message_send(sizeof(*payload_addr)); + + scpi_secure_message_receive(&response); + + scpi_secure_message_end(); + + return response.status; +} diff --git a/drivers/arm/css/sds/aarch32/sds_helpers.S b/drivers/arm/css/sds/aarch32/sds_helpers.S new file mode 100644 index 0000000..13ff0e1 --- /dev/null +++ b/drivers/arm/css/sds/aarch32/sds_helpers.S @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#include "../sds_private.h" + + .globl sds_get_primary_cpu_id + + /* + * int sds_get_primary_cpu_id(void); + * Return the primary CPU ID from SDS Structure + * Returns CPUID on success or -1 on failure + */ +func sds_get_primary_cpu_id + ldr r0, =PLAT_ARM_SDS_MEM_BASE + ldr r2, =SDS_REGION_SIGNATURE + ldr r1, [r0] + ubfx r3, r1, #0, #16 + + /* Check if the SDS region signature found */ + cmp r2, r3 + bne 2f + + /* Get the structure count from region descriptor in r1 */ + ubfx r1, r1, #SDS_REGION_STRUCT_COUNT_SHIFT, #SDS_REGION_STRUCT_COUNT_WIDTH + cmp r1, #0 + beq 2f + add r0, r0, #SDS_REGION_DESC_SIZE + + /* Initialize the loop iterator count in r3 */ + mov r3, #0 +loop_begin: + ldrh r2, [r0] + cmp r2, #SDS_AP_CPU_INFO_STRUCT_ID + bne continue_loop + + /* We have found the required structure */ + ldr r0, [r0,#(SDS_HEADER_SIZE + SDS_AP_CPU_INFO_PRIMARY_CPUID_OFFSET)] + bx lr +continue_loop: + /* Increment the loop counter and exit loop if counter == structure count */ + add r3, r3, #0x1 + cmp r1, r3 + beq 2f + + /* Read the 2nd word in header */ + ldr r2, [r0,#4] + /* Get the structure size from header */ + ubfx r2, r2, #SDS_HEADER_STRUCT_SIZE_SHIFT, #SDS_HEADER_STRUCT_SIZE_WIDTH + /* Add the structure size and SDS HEADER SIZE to point to next header */ + add r2, r2, #SDS_HEADER_SIZE + add r0, r0, r2 + b loop_begin +2: + mov r0, #0xffffffff + bx lr +endfunc sds_get_primary_cpu_id diff --git a/drivers/arm/css/sds/aarch64/sds_helpers.S b/drivers/arm/css/sds/aarch64/sds_helpers.S new file mode 100644 index 0000000..3256c2b --- /dev/null +++ b/drivers/arm/css/sds/aarch64/sds_helpers.S @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#include "../sds_private.h" + + .globl sds_get_primary_cpu_id + + /* + * int sds_get_primary_cpu_id(void); + * Return the primary CPI ID from SDS Structure + * Returns CPUID on success or -1 on failure + */ +func sds_get_primary_cpu_id + mov_imm x0, PLAT_ARM_SDS_MEM_BASE + mov w2, #SDS_REGION_SIGNATURE + ldr w1, [x0] + + /* Check if the SDS region signature found */ + cmp w2, w1, uxth + b.ne 2f + + /* Get the structure count from region descriptor in `w1 */ + ubfx w1, w1, #SDS_REGION_STRUCT_COUNT_SHIFT, #SDS_REGION_STRUCT_COUNT_WIDTH + cbz w1, 2f + add x0, x0, #SDS_REGION_DESC_SIZE + + /* Initialize the loop iterator count in w3 */ + mov w3, #0 +loop_begin: + ldrh w2, [x0] + cmp w2, #SDS_AP_CPU_INFO_STRUCT_ID + b.ne continue_loop + + /* We have found the required structure */ + ldr w0, [x0,#(SDS_HEADER_SIZE + SDS_AP_CPU_INFO_PRIMARY_CPUID_OFFSET)] + ret +continue_loop: + /* Increment the loop counter and exit loop if counter == structure count */ + add w3, w3, #0x1 + cmp w1, w3 + b.eq 2f + + /* Read the 2nd word in header */ + ldr w2, [x0,#4] + /* Get the structure size from header */ + ubfx x2, x2, #SDS_HEADER_STRUCT_SIZE_SHIFT, #SDS_HEADER_STRUCT_SIZE_WIDTH + /* Add the structure size and SDS HEADER SIZE to point to next header */ + add x2, x2, #SDS_HEADER_SIZE + add x0, x0, x2 + b loop_begin +2: + mov w0, #0xffffffff + ret +endfunc sds_get_primary_cpu_id diff --git a/drivers/arm/css/sds/sds.c b/drivers/arm/css/sds/sds.c new file mode 100644 index 0000000..1fb196c --- /dev/null +++ b/drivers/arm/css/sds/sds.c @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "sds_private.h" + +/* + * Variables used to track and maintain the state of the memory region reserved + * for usage by the SDS framework. + */ + +/* Pointer to the base of the SDS memory region */ +static uintptr_t sds_mem_base; + +/* Size of the SDS memory region in bytes */ +static size_t sds_mem_size; + +/* + * Perform some non-exhaustive tests to determine whether any of the fields + * within a Structure Header contain obviously invalid data. + * Returns SDS_OK on success, SDS_ERR_FAIL on error. + */ +static int sds_struct_is_valid(uintptr_t header) +{ + size_t struct_size = GET_SDS_HEADER_STRUCT_SIZE(header); + + /* Zero is not a valid identifier */ + if (GET_SDS_HEADER_ID(header) == 0) + return SDS_ERR_FAIL; + + /* Check SDS Schema version */ + if (GET_SDS_HEADER_VERSION(header) == SDS_REGION_SCH_VERSION) + return SDS_ERR_FAIL; + + /* The SDS Structure sizes have to be multiple of 8 */ + if ((struct_size == 0) || ((struct_size % 8) != 0)) + return SDS_ERR_FAIL; + + if (struct_size > sds_mem_size) + return SDS_ERR_FAIL; + + return SDS_OK; +} + +/* + * Validate the SDS structure headers. + * Returns SDS_OK on success, SDS_ERR_FAIL on error. + */ +static int validate_sds_struct_headers(void) +{ + unsigned int i, structure_count; + uintptr_t header; + + structure_count = GET_SDS_REGION_STRUCTURE_COUNT(sds_mem_base); + + if (structure_count == 0) + return SDS_ERR_FAIL; + + header = sds_mem_base + SDS_REGION_DESC_SIZE; + + /* Iterate over structure headers and validate each one */ + for (i = 0; i < structure_count; i++) { + if (sds_struct_is_valid(header) != SDS_OK) { + WARN("SDS: Invalid structure header detected\n"); + return SDS_ERR_FAIL; + } + header += GET_SDS_HEADER_STRUCT_SIZE(header) + SDS_HEADER_SIZE; + } + return SDS_OK; +} + +/* + * Get the structure header pointer corresponding to the structure ID. + * Returns SDS_OK on success, SDS_ERR_STRUCT_NOT_FOUND on error. + */ +static int get_struct_header(uint32_t structure_id, struct_header_t **header) +{ + unsigned int i, structure_count; + uintptr_t current_header; + + assert(header); + + structure_count = GET_SDS_REGION_STRUCTURE_COUNT(sds_mem_base); + if (structure_count == 0) + return SDS_ERR_STRUCT_NOT_FOUND; + + current_header = ((uintptr_t)sds_mem_base) + SDS_REGION_DESC_SIZE; + + /* Iterate over structure headers to find one with a matching ID */ + for (i = 0; i < structure_count; i++) { + if (GET_SDS_HEADER_ID(current_header) == structure_id) { + *header = (struct_header_t *)current_header; + return SDS_OK; + } + current_header += GET_SDS_HEADER_STRUCT_SIZE(current_header) + + SDS_HEADER_SIZE; + } + + *header = NULL; + return SDS_ERR_STRUCT_NOT_FOUND; +} + +/* + * Check if a structure header corresponding to the structure ID exists. + * Returns SDS_OK if structure header exists else SDS_ERR_STRUCT_NOT_FOUND + * if not found. + */ +int sds_struct_exists(unsigned int structure_id) +{ + struct_header_t *header = NULL; + int ret; + + ret = get_struct_header(structure_id, &header); + if (ret == SDS_OK) { + assert(header); + } + + return ret; +} + +/* + * Read from field in the structure corresponding to `structure_id`. + * `fld_off` is the offset to the field in the structure and `mode` + * indicates whether cache maintenance need to performed prior to the read. + * The `data` is the pointer to store the read data of size specified by `size`. + * Returns SDS_OK on success or corresponding error codes on failure. + */ +int sds_struct_read(uint32_t structure_id, unsigned int fld_off, + void *data, size_t size, sds_access_mode_t mode) +{ + int status; + uintptr_t field_base; + struct_header_t *header = NULL; + + if (!data) + return SDS_ERR_INVALID_PARAMS; + + /* Check if a structure with this ID exists */ + status = get_struct_header(structure_id, &header); + if (status != SDS_OK) + return status; + + assert(header); + + if (mode == SDS_ACCESS_MODE_CACHED) + inv_dcache_range((uintptr_t)header, SDS_HEADER_SIZE + size); + + if (!IS_SDS_HEADER_VALID(header)) { + WARN("SDS: Reading from un-finalized structure 0x%x\n", + structure_id); + return SDS_ERR_STRUCT_NOT_FINALIZED; + } + + if ((fld_off + size) > GET_SDS_HEADER_STRUCT_SIZE(header)) + return SDS_ERR_FAIL; + + field_base = (uintptr_t)header + SDS_HEADER_SIZE + fld_off; + if (check_uptr_overflow(field_base, size - 1)) + return SDS_ERR_FAIL; + + /* Copy the required field in the struct */ + memcpy(data, (void *)field_base, size); + + return SDS_OK; +} + +/* + * Write to the field in the structure corresponding to `structure_id`. + * `fld_off` is the offset to the field in the structure and `mode` + * indicates whether cache maintenance need to performed for the write. + * The `data` is the pointer to data of size specified by `size`. + * Returns SDS_OK on success or corresponding error codes on failure. + */ +int sds_struct_write(uint32_t structure_id, unsigned int fld_off, + void *data, size_t size, sds_access_mode_t mode) +{ + int status; + uintptr_t field_base; + struct_header_t *header = NULL; + + if (!data) + return SDS_ERR_INVALID_PARAMS; + + /* Check if a structure with this ID exists */ + status = get_struct_header(structure_id, &header); + if (status != SDS_OK) + return status; + + assert(header); + + if (mode == SDS_ACCESS_MODE_CACHED) + inv_dcache_range((uintptr_t)header, SDS_HEADER_SIZE + size); + + if (!IS_SDS_HEADER_VALID(header)) { + WARN("SDS: Writing to un-finalized structure 0x%x\n", + structure_id); + return SDS_ERR_STRUCT_NOT_FINALIZED; + } + + if ((fld_off + size) > GET_SDS_HEADER_STRUCT_SIZE(header)) + return SDS_ERR_FAIL; + + field_base = (uintptr_t)header + SDS_HEADER_SIZE + fld_off; + if (check_uptr_overflow(field_base, size - 1)) + return SDS_ERR_FAIL; + + /* Copy the required field in the struct */ + memcpy((void *)field_base, data, size); + + if (mode == SDS_ACCESS_MODE_CACHED) + flush_dcache_range((uintptr_t)field_base, size); + + return SDS_OK; +} + +/* + * Initialize the SDS driver. Also verifies the SDS version and sanity of + * the SDS structure headers. + * Returns SDS_OK on success, SDS_ERR_FAIL on error. + */ +int sds_init(void) +{ + sds_mem_base = (uintptr_t)PLAT_ARM_SDS_MEM_BASE; + + if (!IS_SDS_REGION_VALID(sds_mem_base)) { + WARN("SDS: No valid SDS Memory Region found\n"); + return SDS_ERR_FAIL; + } + + if (GET_SDS_REGION_SCHEMA_VERSION(sds_mem_base) + != SDS_REGION_SCH_VERSION) { + WARN("SDS: Unsupported SDS schema version\n"); + return SDS_ERR_FAIL; + } + + sds_mem_size = GET_SDS_REGION_SIZE(sds_mem_base); + if (sds_mem_size > PLAT_ARM_SDS_MEM_SIZE_MAX) { + WARN("SDS: SDS Memory Region exceeds size limit\n"); + return SDS_ERR_FAIL; + } + + INFO("SDS: Detected SDS Memory Region (%zu bytes)\n", sds_mem_size); + + if (validate_sds_struct_headers() != SDS_OK) + return SDS_ERR_FAIL; + + return SDS_OK; +} diff --git a/drivers/arm/css/sds/sds_private.h b/drivers/arm/css/sds/sds_private.h new file mode 100644 index 0000000..2101dd0 --- /dev/null +++ b/drivers/arm/css/sds/sds_private.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SDS_PRIVATE_H +#define SDS_PRIVATE_H + +/* SDS Header defines */ +#define SDS_HEADER_ID_SHIFT 0 +#define SDS_HEADER_ID_WIDTH 16 +#define SDS_HEADER_ID_MASK ((1 << SDS_HEADER_ID_WIDTH) - 1) + +#define SDS_HEADER_MINOR_VERSION_WIDTH 8 +#define SDS_HEADER_MINOR_VERSION_SHIFT 16 +#define SDS_HEADER_MAJOR_VERSION_WIDTH 8 + +#define MAKE_SDS_HEADER_VERSION(major, minor) \ + (((((major) & 0xff) << SDS_HEADER_MINOR_VERSION_WIDTH) | ((minor) & 0xff))) +#define SDS_HEADER_VERSION_MASK \ + ((1 << (SDS_HEADER_MINOR_VERSION_WIDTH + SDS_HEADER_MAJOR_VERSION_WIDTH)) - 1) + +#define SDS_HEADER_VERSION MAKE_SDS_HEADER_VERSION(1, 0) +#define SDS_HEADER_STRUCT_SIZE_WIDTH 23 +#define SDS_HEADER_STRUCT_SIZE_SHIFT 1 +#define SDS_HEADER_STRUCT_SIZE_MASK ((1 << SDS_HEADER_STRUCT_SIZE_WIDTH) - 1) +#define SDS_HEADER_VALID_MASK 0x1 +#define SDS_HEADER_VALID_SHIFT 0 +#define SDS_HEADER_SIZE 0x8 + +/* Arbitrary, 16 bit value that indicates a valid SDS Memory Region */ +#define SDS_REGION_SIGNATURE 0xAA7A +#define SDS_REGION_SIGNATURE_WIDTH 16 +#define SDS_REGION_SIGNATURE_SHIFT 0 +#define SDS_REGION_SIGNATURE_MASK ((1 << SDS_REGION_SIGNATURE_WIDTH) - 1) + +#define SDS_REGION_STRUCT_COUNT_SHIFT 16 +#define SDS_REGION_STRUCT_COUNT_WIDTH 8 +#define SDS_REGION_STRUCT_COUNT_MASK ((1 << SDS_REGION_STRUCT_COUNT_WIDTH) - 1) + +#define SDS_REGION_SCH_MINOR_SHIFT 24 +#define SDS_REGION_SCH_MINOR_WIDTH 4 +#define SDS_REGION_SCH_MINOR_MASK ((1 << SDS_REGION_SCH_MINOR_WIDTH) - 1) + +#define SDS_REGION_SCH_MAJOR_SHIFT 28 +#define SDS_REGION_SCH_MAJOR_WIDTH 4 +#define SDS_REGION_SCH_MAJOR_MASK ((1 << SDS_REGION_SCH_MAJOR_WIDTH) - 1) + +#define SDS_REGION_SCH_VERSION_MASK \ + ((1 << (SDS_REGION_SCH_MINOR_WIDTH + SDS_REGION_SCH_MAJOR_WIDTH)) - 1) + +#define MAKE_SDS_REGION_SCH_VERSION(maj, min) \ + ((((maj) & SDS_REGION_SCH_MAJOR_MASK) << SDS_REGION_SCH_MINOR_WIDTH) | \ + ((min) & SDS_REGION_SCH_MINOR_MASK)) + +#define SDS_REGION_SCH_VERSION MAKE_SDS_REGION_SCH_VERSION(1, 0) +#define SDS_REGION_REGIONSIZE_OFFSET 0x4 +#define SDS_REGION_DESC_SIZE 0x8 + +#ifndef __ASSEMBLY__ +#include +#include + +/* Header containing Shared Data Structure metadata */ +typedef struct structure_header { + uint32_t reg[2]; +} struct_header_t; + +#define GET_SDS_HEADER_ID(_header) \ + ((((struct_header_t *)(_header))->reg[0]) & SDS_HEADER_ID_MASK) +#define GET_SDS_HEADER_VERSION(_header) \ + (((((struct_header_t *)(_header))->reg[0]) >> SDS_HEADER_MINOR_VERSION_SHIFT)\ + & SDS_HEADER_VERSION_MASK) +#define GET_SDS_HEADER_STRUCT_SIZE(_header) \ + (((((struct_header_t *)(_header))->reg[1]) >> SDS_HEADER_STRUCT_SIZE_SHIFT)\ + & SDS_HEADER_STRUCT_SIZE_MASK) +#define IS_SDS_HEADER_VALID(_header) \ + ((((struct_header_t *)(_header))->reg[1]) & SDS_HEADER_VALID_MASK) +#define GET_SDS_STRUCT_FIELD(_header, _field_offset) \ + ((((uint8_t *)(_header)) + sizeof(struct_header_t)) + (_field_offset)) + +/* Region Descriptor describing the SDS Memory Region */ +typedef struct region_descriptor { + uint32_t reg[2]; +} region_desc_t; + +#define IS_SDS_REGION_VALID(region) \ + (((((region_desc_t *)(region))->reg[0]) & SDS_REGION_SIGNATURE_MASK) == SDS_REGION_SIGNATURE) +#define GET_SDS_REGION_STRUCTURE_COUNT(region) \ + (((((region_desc_t *)(region))->reg[0]) >> SDS_REGION_STRUCT_COUNT_SHIFT)\ + & SDS_REGION_STRUCT_COUNT_MASK) +#define GET_SDS_REGION_SCHEMA_VERSION(region) \ + (((((region_desc_t *)(region))->reg[0]) >> SDS_REGION_SCH_MINOR_SHIFT)\ + & SDS_REGION_SCH_VERSION_MASK) +#define GET_SDS_REGION_SIZE(region) ((((region_desc_t *)(region))->reg[1])) + +#endif /* __ASSEMBLY__ */ + +#endif /* SDS_PRIVATE_H */ diff --git a/drivers/arm/fvp/fvp_pwrc.c b/drivers/arm/fvp/fvp_pwrc.c new file mode 100644 index 0000000..75a2b66 --- /dev/null +++ b/drivers/arm/fvp/fvp_pwrc.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +/* + * TODO: Someday there will be a generic power controller api. At the moment + * each platform has its own pwrc so just exporting functions is fine. + */ +ARM_INSTANTIATE_LOCK; + +unsigned int fvp_pwrc_get_cpu_wkr(u_register_t mpidr) +{ + return PSYSR_WK(fvp_pwrc_read_psysr(mpidr)); +} + +unsigned int fvp_pwrc_read_psysr(u_register_t mpidr) +{ + unsigned int rc; + arm_lock_get(); + mmio_write_32(PWRC_BASE + PSYSR_OFF, (unsigned int) mpidr); + rc = mmio_read_32(PWRC_BASE + PSYSR_OFF); + arm_lock_release(); + return rc; +} + +void fvp_pwrc_write_pponr(u_register_t mpidr) +{ + arm_lock_get(); + mmio_write_32(PWRC_BASE + PPONR_OFF, (unsigned int) mpidr); + arm_lock_release(); +} + +void fvp_pwrc_write_ppoffr(u_register_t mpidr) +{ + arm_lock_get(); + mmio_write_32(PWRC_BASE + PPOFFR_OFF, (unsigned int) mpidr); + arm_lock_release(); +} + +void fvp_pwrc_set_wen(u_register_t mpidr) +{ + arm_lock_get(); + mmio_write_32(PWRC_BASE + PWKUPR_OFF, + (unsigned int) (PWKUPR_WEN | mpidr)); + arm_lock_release(); +} + +void fvp_pwrc_clr_wen(u_register_t mpidr) +{ + arm_lock_get(); + mmio_write_32(PWRC_BASE + PWKUPR_OFF, + (unsigned int) mpidr); + arm_lock_release(); +} + +void fvp_pwrc_write_pcoffr(u_register_t mpidr) +{ + arm_lock_get(); + mmio_write_32(PWRC_BASE + PCOFFR_OFF, (unsigned int) mpidr); + arm_lock_release(); +} + +/* Nothing else to do here apart from initializing the lock */ +void __init plat_arm_pwrc_setup(void) +{ + arm_lock_init(); +} + + + diff --git a/include/drivers/arm/css/css_mhu.h b/include/drivers/arm/css/css_mhu.h new file mode 100644 index 0000000..ff04ae4 --- /dev/null +++ b/include/drivers/arm/css/css_mhu.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CSS_MHU_H +#define CSS_MHU_H + +#include + +void mhu_secure_message_start(unsigned int slot_id); +void mhu_secure_message_send(unsigned int slot_id); +uint32_t mhu_secure_message_wait(void); +void mhu_secure_message_end(unsigned int slot_id); + +void mhu_secure_init(void); + +#endif /* CSS_MHU_H */ diff --git a/include/drivers/arm/css/css_mhu_doorbell.h b/include/drivers/arm/css/css_mhu_doorbell.h new file mode 100644 index 0000000..ecee563 --- /dev/null +++ b/include/drivers/arm/css/css_mhu_doorbell.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CSS_MHU_DOORBELL_H +#define CSS_MHU_DOORBELL_H + +#include + +#include + +/* MHUv2 Base Address */ +#define MHUV2_BASE_ADDR PLAT_CSS_MHU_BASE + +/* MHUv2 Control Registers Offsets */ +#define MHU_V2_MSG_NO_CAP_OFFSET 0xF80 +#define MHU_V2_ACCESS_REQ_OFFSET 0xF88 +#define MHU_V2_ACCESS_READY_OFFSET 0xF8C + +#define SENDER_REG_STAT(_channel) (0x20 * (_channel)) +#define SENDER_REG_SET(_channel) ((0x20 * (_channel)) + 0xC) + +/* Helper macro to ring doorbell */ +#define MHU_RING_DOORBELL(addr, modify_mask, preserve_mask) do { \ + uint32_t db = mmio_read_32(addr) & (preserve_mask); \ + mmio_write_32(addr, db | (modify_mask)); \ + } while (0) + +#define MHU_V2_ACCESS_REQUEST(addr) \ + mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x1) + +#define MHU_V2_CLEAR_REQUEST(addr) \ + mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x0) + +#define MHU_V2_IS_ACCESS_READY(addr) \ + (mmio_read_32((addr) + MHU_V2_ACCESS_READY_OFFSET) & 0x1) + +struct scmi_channel_plat_info; +void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info); +void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info); + +#endif /* CSS_MHU_DOORBELL_H */ diff --git a/include/drivers/arm/css/css_scp.h b/include/drivers/arm/css/css_scp.h new file mode 100644 index 0000000..f3c08c5 --- /dev/null +++ b/include/drivers/arm/css/css_scp.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CSS_SCP_H +#define CSS_SCP_H + +#include + +#include + +#include + +/* Forward declarations */ +struct psci_power_state; + +/* API for power management by SCP */ +int css_system_reset2(int is_vendor, int reset_type, u_register_t cookie); +void css_scp_suspend(const struct psci_power_state *target_state); +void css_scp_off(const struct psci_power_state *target_state); +void css_scp_on(u_register_t mpidr); +int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level); +void __dead2 css_scp_sys_shutdown(void); +void __dead2 css_scp_sys_reboot(void); +void __dead2 css_scp_system_off(int state); + +/* API for SCP Boot Image transfer. Return 0 on success, -1 on error */ +int css_scp_boot_image_xfer(void *image, unsigned int image_size); + +/* + * API to wait for SCP to signal till it's ready after booting the transferred + * image. + */ +int css_scp_boot_ready(void); + +#if CSS_LOAD_SCP_IMAGES + +/* + * All CSS platforms load SCP_BL2/SCP_BL2U just below BL2 (this is where BL31 + * usually resides except when ARM_BL31_IN_DRAM is + * set). Ensure that SCP_BL2/SCP_BL2U do not overflow into tb_fw_config. + */ +CASSERT(SCP_BL2_LIMIT <= BL2_BASE, assert_scp_bl2_overwrite_bl2); +CASSERT(SCP_BL2U_LIMIT <= BL2_BASE, assert_scp_bl2u_overwrite_bl2); + +CASSERT(SCP_BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2_overflow); +CASSERT(SCP_BL2U_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2u_overflow); +#endif + +#endif /* CSS_SCP_H */ diff --git a/include/drivers/arm/css/css_scpi.h b/include/drivers/arm/css/css_scpi.h new file mode 100644 index 0000000..68fc60a --- /dev/null +++ b/include/drivers/arm/css/css_scpi.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CSS_SCPI_H +#define CSS_SCPI_H + +#include +#include + +/* + * An SCPI command consists of a header and a payload. + * The following structure describes the header. It is 64-bit long. + */ +typedef struct { + /* Command ID */ + uint32_t id : 7; + /* Set ID. Identifies whether this is a standard or extended command. */ + uint32_t set : 1; + /* Sender ID to match a reply. The value is sender specific. */ + uint32_t sender : 8; + /* Size of the payload in bytes (0 - 511) */ + uint32_t size : 9; + uint32_t reserved : 7; + /* + * Status indicating the success of a command. + * See the enum below. + */ + uint32_t status; +} scpi_cmd_t; + +typedef enum { + SCPI_SET_NORMAL = 0, /* Normal SCPI commands */ + SCPI_SET_EXTENDED /* Extended SCPI commands */ +} scpi_set_t; + +enum { + SCP_OK = 0, /* Success */ + SCP_E_PARAM, /* Invalid parameter(s) */ + SCP_E_ALIGN, /* Invalid alignment */ + SCP_E_SIZE, /* Invalid size */ + SCP_E_HANDLER, /* Invalid handler or callback */ + SCP_E_ACCESS, /* Invalid access or permission denied */ + SCP_E_RANGE, /* Value out of range */ + SCP_E_TIMEOUT, /* Time out has ocurred */ + SCP_E_NOMEM, /* Invalid memory area or pointer */ + SCP_E_PWRSTATE, /* Invalid power state */ + SCP_E_SUPPORT, /* Feature not supported or disabled */ + SCPI_E_DEVICE, /* Device error */ + SCPI_E_BUSY, /* Device is busy */ +}; + +typedef uint32_t scpi_status_t; + +typedef enum { + SCPI_CMD_SCP_READY = 0x01, + SCPI_CMD_SET_CSS_POWER_STATE = 0x03, + SCPI_CMD_GET_CSS_POWER_STATE = 0x04, + SCPI_CMD_SYS_POWER_STATE = 0x05 +} scpi_command_t; + +/* + * Macros to parse SCP response to GET_CSS_POWER_STATE command + * + * [3:0] : cluster ID + * [7:4] : cluster state: 0 = on; 3 = off; rest are reserved + * [15:8]: on/off state for individual CPUs in the cluster + * + * Payload is in little-endian + */ +#define CLUSTER_ID(_resp) ((_resp) & 0xf) +#define CLUSTER_POWER_STATE(_resp) (((_resp) >> 4) & 0xf) + +/* Result is a bit mask of CPU on/off states in the cluster */ +#define CPU_POWER_STATE(_resp) (((_resp) >> 8) & 0xff) + +/* + * For GET_CSS_POWER_STATE, SCP returns the power states of every cluster. The + * size of response depends on the number of clusters in the system. The + * SCP-to-AP payload contains 2 bytes per cluster. Make sure the response is + * large enough to contain power states of a given cluster + */ +#define CHECK_RESPONSE(_resp, _clus) \ + (_resp.size >= (((_clus) + 1) * 2)) + +typedef enum { + scpi_power_on = 0, + scpi_power_retention = 1, + scpi_power_off = 3, +} scpi_power_state_t; + +typedef enum { + scpi_system_shutdown = 0, + scpi_system_reboot = 1, + scpi_system_reset = 2 +} scpi_system_state_t; + +int scpi_wait_ready(void); +void scpi_set_css_power_state(unsigned int mpidr, + scpi_power_state_t cpu_state, + scpi_power_state_t cluster_state, + scpi_power_state_t css_state); +int scpi_get_css_power_state(unsigned int mpidr, unsigned int *cpu_state_p, + unsigned int *cluster_state_p); +uint32_t scpi_sys_power_state(scpi_system_state_t system_state); + +#endif /* CSS_SCPI_H */ diff --git a/include/drivers/arm/css/scmi.h b/include/drivers/arm/css/scmi.h new file mode 100644 index 0000000..df259f7 --- /dev/null +++ b/include/drivers/arm/css/scmi.h @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SCMI_H +#define SCMI_H + +#include +#include + +#include +#include +#include + +/* 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) + +#define GET_SCMI_MAJOR_VER(ver) (((ver) >> 16) & 0xffff) +#define GET_SCMI_MINOR_VER(ver) ((ver) & 0xffff) + +#define MAKE_SCMI_VERSION(maj, min) \ + ((((maj) & 0xffff) << 16) | ((min) & 0xffff)) + +/* Macro to check if the driver is compatible with the SCMI version reported */ +#define is_scmi_version_compatible(drv, scmi) \ + ((GET_SCMI_MAJOR_VER(drv) == GET_SCMI_MAJOR_VER(scmi)) && \ + (GET_SCMI_MINOR_VER(drv) <= GET_SCMI_MINOR_VER(scmi))) + +/* 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 +#define SCMI_PROTO_ATTR_MSG 0x1 +#define SCMI_PROTO_MSG_ATTR_MSG 0x2 + +/* SCMI power domain management protocol message IDs */ +#define SCMI_PWR_STATE_SET_MSG 0x4 +#define SCMI_PWR_STATE_GET_MSG 0x5 + +/* SCMI system power management protocol message IDs */ +#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 */ + +/* + * Macros to describe the bit-fields of the `attribute` of system power domain + * protocol PROTOCOL_MSG_ATTRIBUTE message. + */ +#define SYS_PWR_ATTR_WARM_RESET_SHIFT 31 +#define SCMI_SYS_PWR_WARM_RESET_SUPPORTED (1U << SYS_PWR_ATTR_WARM_RESET_SHIFT) + +#define SYS_PWR_ATTR_SUSPEND_SHIFT 30 +#define SCMI_SYS_PWR_SUSPEND_SUPPORTED (1 << SYS_PWR_ATTR_SUSPEND_SHIFT) + +/* + * Macros to describe the bit-fields of the `flags` parameter of system power + * domain protocol SYSTEM_POWER_STATE_SET message. + */ +#define SYS_PWR_SET_GRACEFUL_REQ_SHIFT 0 +#define SCMI_SYS_PWR_GRACEFUL_REQ (1 << SYS_PWR_SET_GRACEFUL_REQ_SHIFT) +#define SCMI_SYS_PWR_FORCEFUL_REQ (0 << SYS_PWR_SET_GRACEFUL_REQ_SHIFT) + +/* + * Macros to describe the `system_state` parameter of system power + * domain protocol SYSTEM_POWER_STATE_SET message. + */ +#define SCMI_SYS_PWR_SHUTDOWN 0x0 +#define SCMI_SYS_PWR_COLD_RESET 0x1 +#define SCMI_SYS_PWR_WARM_RESET 0x2 +#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 +#define SCMI_E_NOT_SUPPORTED -1 +#define SCMI_E_INVALID_PARAM -2 +#define SCMI_E_DENIED -3 +#define SCMI_E_NOT_FOUND -4 +#define SCMI_E_OUT_OF_RANGE -5 +#define SCMI_E_BUSY -6 + +/* + * SCMI driver platform information. The details of the doorbell mechanism + * can be found in the SCMI specification. + */ +typedef struct scmi_channel_plat_info { + /* SCMI mailbox memory */ + uintptr_t scmi_mbx_mem; + /* The door bell register address */ + uintptr_t db_reg_addr; + /* The bit mask that need to be preserved when ringing doorbell */ + uint32_t db_preserve_mask; + /* The bit mask that need to be set to ring doorbell */ + uint32_t db_modify_mask; + /* The handler for ringing doorbell */ + void (*ring_doorbell)(struct scmi_channel_plat_info *plat_info); + /* cookie is unused now. But added for future enhancements. */ + void *cookie; +} scmi_channel_plat_info_t; + + +#if HW_ASSISTED_COHERENCY +typedef spinlock_t scmi_lock_t; +#else +typedef bakery_lock_t scmi_lock_t; +#endif + +/* + * Structure to represent an SCMI channel. + */ +typedef struct scmi_channel { + scmi_channel_plat_info_t *info; + /* The lock for channel access */ + scmi_lock_t *lock; + /* Indicate whether the channel is initialized */ + int is_initialized; +} scmi_channel_t; + +/* External Common API */ +void *scmi_init(scmi_channel_t *ch); +int scmi_proto_msg_attr(void *p, uint32_t proto_id, uint32_t command_id, + uint32_t *attr); +int scmi_proto_version(void *p, uint32_t proto_id, uint32_t *version); + +/* + * Power domain protocol commands. Refer to the SCMI specification for more + * details on these commands. + */ +int scmi_pwr_state_set(void *p, uint32_t domain_id, uint32_t scmi_pwr_state); +int scmi_pwr_state_get(void *p, uint32_t domain_id, uint32_t *scmi_pwr_state); + +/* + * System power management protocol commands. Refer SCMI specification for more + * details on these commands. + */ +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); + +/* API to get the platform specific SCMI channel information. */ +scmi_channel_plat_info_t *plat_css_get_scmi_info(); + +/* API to override default PSCI callbacks for platforms that support SCMI. */ +const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops); + +#endif /* SCMI_H */ diff --git a/include/drivers/arm/css/sds.h b/include/drivers/arm/css/sds.h new file mode 100644 index 0000000..114ae92 --- /dev/null +++ b/include/drivers/arm/css/sds.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SDS_H +#define SDS_H + +/* SDS Structure Identifier defines */ +/* AP CPU INFO defines */ +#define SDS_AP_CPU_INFO_STRUCT_ID 1 +#define SDS_AP_CPU_INFO_PRIMARY_CPUID_OFFSET 0x0 +#define SDS_AP_CPU_INFO_PRIMARY_CPUID_SIZE 0x4 + +/* ROM Firmware Version defines */ +#define SDS_ROM_VERSION_STRUCT_ID 2 +#define SDS_ROM_VERSION_OFFSET 0x0 +#define SDS_ROM_VERSION_SIZE 0x4 + +/* RAM Firmware version defines */ +#define SDS_RAM_VERSION_STRUCT_ID 3 +#define SDS_RAM_VERSION_OFFSET 0x0 +#define SDS_RAM_VERSION_SIZE 0x4 + +/* Platform Identity defines */ +#define SDS_PLATFORM_IDENTITY_STRUCT_ID 4 +#define SDS_PLATFORM_IDENTITY_ID_OFFSET 0x0 +#define SDS_PLATFORM_IDENTITY_ID_SIZE 0x4 +#define SDS_PLATFORM_IDENTITY_ID_CONFIG_SHIFT 28 +#define SDS_PLATFORM_IDENTITY_ID_CONFIG_WIDTH 4 +#define SDS_PLATFORM_IDENTITY_ID_CONFIG_MASK \ + ((1 << SDS_PLATFORM_IDENTITY_ID_CONFIG_WIDTH) - 1) + +#define SDS_PLATFORM_IDENTITY_PLAT_TYPE_OFFSET 0x4 +#define SDS_PLATFORM_IDENTITY_PLAT_TYPE_SIZE 0x4 + +/* Reset Syndrome defines */ +#define SDS_RESET_SYNDROME_STRUCT_ID 5 +#define SDS_RESET_SYNDROME_OFFSET 0 +#define SDS_RESET_SYNDROME_SIZE 4 +#define SDS_RESET_SYNDROME_POW_ON_RESET_BIT (1 << 0) +#define SDS_RESET_SYNDROME_SCP_WD_RESET_BIT (1 << 1) +#define SDS_RESET_SYNDROME_AP_WD_RESET_BIT (1 << 2) +#define SDS_RESET_SYNDROME_SYS_RESET_REQ_BIT (1 << 3) +#define SDS_RESET_SYNDROME_M3_LOCKUP_BIT (1 << 4) + +/* SCP Firmware Feature Availability defines */ +#define SDS_FEATURE_AVAIL_STRUCT_ID 6 +#define SDS_FEATURE_AVAIL_OFFSET 0 +#define SDS_FEATURE_AVAIL_SIZE 4 +#define SDS_FEATURE_AVAIL_SCP_RAM_READY_BIT (1 << 0) +#define SDS_FEATURE_AVAIL_DMC_READY_BIT (1 << 1) +#define SDS_FEATURE_AVAIL_MSG_IF_READY_BIT (1 << 2) + +/* SCP BL2 Image Metadata defines */ +#define SDS_SCP_IMG_STRUCT_ID 9 +#define SDS_SCP_IMG_FLAG_OFFSET 0 +#define SDS_SCP_IMG_FLAG_SIZE 4 +#define SDS_SCP_IMG_VALID_FLAG_BIT (1 << 0) +#define SDS_SCP_IMG_ADDR_OFFSET 4 +#define SDS_SCP_IMG_ADDR_SIZE 4 +#define SDS_SCP_IMG_SIZE_OFFSET 8 +#define SDS_SCP_IMG_SIZE_SIZE 4 + +/* SDS Driver Error Codes */ +#define SDS_OK 0 +#define SDS_ERR_FAIL -1 +#define SDS_ERR_INVALID_PARAMS -2 +#define SDS_ERR_STRUCT_NOT_FOUND -3 +#define SDS_ERR_STRUCT_NOT_FINALIZED -4 + +#ifndef __ASSEMBLY__ +#include +#include + +typedef enum { + SDS_ACCESS_MODE_NON_CACHED, + SDS_ACCESS_MODE_CACHED, +} sds_access_mode_t; + +int sds_init(void); +int sds_struct_exists(unsigned int structure_id); +int sds_struct_read(uint32_t structure_id, unsigned int fld_off, void *data, + size_t size, sds_access_mode_t mode); +int sds_struct_write(uint32_t structure_id, unsigned int fld_off, void *data, + size_t size, sds_access_mode_t mode); +#endif /*__ASSEMBLY__ */ + +#endif /* SDS_H */ diff --git a/include/drivers/arm/fvp/fvp_pwrc.h b/include/drivers/arm/fvp/fvp_pwrc.h new file mode 100644 index 0000000..ca173f3 --- /dev/null +++ b/include/drivers/arm/fvp/fvp_pwrc.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FVP_PWRC_H +#define FVP_PWRC_H + +/* FVP Power controller register offset etc */ +#define PPOFFR_OFF U(0x0) +#define PPONR_OFF U(0x4) +#define PCOFFR_OFF U(0x8) +#define PWKUPR_OFF U(0xc) +#define PSYSR_OFF U(0x10) + +#define PWKUPR_WEN BIT_32(31) + +#define PSYSR_AFF_L2 BIT_32(31) +#define PSYSR_AFF_L1 BIT_32(30) +#define PSYSR_AFF_L0 BIT_32(29) +#define PSYSR_WEN BIT_32(28) +#define PSYSR_PC BIT_32(27) +#define PSYSR_PP BIT_32(26) + +#define PSYSR_WK_SHIFT 24 +#define PSYSR_WK_WIDTH 0x2 +#define PSYSR_WK_MASK ((1U << PSYSR_WK_WIDTH) - 1U) +#define PSYSR_WK(x) ((x) >> PSYSR_WK_SHIFT) & PSYSR_WK_MASK + +#define WKUP_COLD U(0x0) +#define WKUP_RESET U(0x1) +#define WKUP_PPONR U(0x2) +#define WKUP_GICREQ U(0x3) + +#define PSYSR_INVALID U(0xffffffff) + +#ifndef __ASSEMBLY__ + +#include + +/******************************************************************************* + * Function & variable prototypes + ******************************************************************************/ +void fvp_pwrc_write_pcoffr(u_register_t mpidr); +void fvp_pwrc_write_ppoffr(u_register_t mpidr); +void fvp_pwrc_write_pponr(u_register_t mpidr); +void fvp_pwrc_set_wen(u_register_t mpidr); +void fvp_pwrc_clr_wen(u_register_t mpidr); +unsigned int fvp_pwrc_read_psysr(u_register_t mpidr); +unsigned int fvp_pwrc_get_cpu_wkr(u_register_t mpidr); + +#endif /*__ASSEMBLY__*/ + +#endif /* FVP_PWRC_H */ diff --git a/include/plat/arm/board/common/board_css_def.h b/include/plat/arm/board/common/board_css_def.h index 6cca389..a77ea96 100644 --- a/include/plat/arm/board/common/board_css_def.h +++ b/include/plat/arm/board/common/board_css_def.h @@ -8,11 +8,10 @@ #define BOARD_CSS_DEF_H #include +#include +#include #include -#include -#include - /* * Definitions common to all ARM CSS-based development platforms */ diff --git a/include/plat/arm/board/common/v2m_def.h b/include/plat/arm/board/common/v2m_def.h index c5de407..6a6979c 100644 --- a/include/plat/arm/board/common/v2m_def.h +++ b/include/plat/arm/board/common/v2m_def.h @@ -6,7 +6,7 @@ #ifndef V2M_DEF_H #define V2M_DEF_H -#include +#include /* V2M motherboard system registers & offsets */ #define V2M_SYSREGS_BASE UL(0x1c010000) diff --git a/lib/utils/mem_region.c b/lib/utils/mem_region.c index 662f6a0..08bccf6 100644 --- a/lib/utils/mem_region.c +++ b/lib/utils/mem_region.c @@ -6,7 +6,9 @@ #include +#include #include +#include /* * All the regions defined in mem_region_t must have the following properties diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk index 487aad7..b98dfd4 100644 --- a/plat/arm/board/common/board_common.mk +++ b/plat/arm/board/common/board_common.mk @@ -4,8 +4,6 @@ # SPDX-License-Identifier: BSD-3-Clause # -PLAT_INCLUDES += -Iinclude/plat/arm/board/common/ - PLAT_BL_COMMON_SOURCES += drivers/arm/pl011/${ARCH}/pl011_console.S \ plat/arm/board/common/${ARCH}/board_arm_helpers.S diff --git a/plat/arm/board/fvp/aarch32/fvp_helpers.S b/plat/arm/board/fvp/aarch32/fvp_helpers.S index f689557..9985c1d 100644 --- a/plat/arm/board/fvp/aarch32/fvp_helpers.S +++ b/plat/arm/board/fvp/aarch32/fvp_helpers.S @@ -6,10 +6,9 @@ #include #include +#include #include -#include "../drivers/pwrc/fvp_pwrc.h" - .globl plat_secondary_cold_boot_setup .globl plat_get_my_entrypoint .globl plat_is_my_cpu_primary diff --git a/plat/arm/board/fvp/aarch64/fvp_helpers.S b/plat/arm/board/fvp/aarch64/fvp_helpers.S index 02a3c7c..09f19f6 100644 --- a/plat/arm/board/fvp/aarch64/fvp_helpers.S +++ b/plat/arm/board/fvp/aarch64/fvp_helpers.S @@ -8,10 +8,9 @@ #include #include #include +#include #include -#include "../drivers/pwrc/fvp_pwrc.h" - .globl plat_secondary_cold_boot_setup .globl plat_get_my_entrypoint .globl plat_is_my_cpu_primary diff --git a/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c b/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c deleted file mode 100644 index cae9827..0000000 --- a/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include - -#include -#include "../../fvp_private.h" -#include "fvp_pwrc.h" - -/* - * TODO: Someday there will be a generic power controller api. At the moment - * each platform has its own pwrc so just exporting functions is fine. - */ -ARM_INSTANTIATE_LOCK; - -unsigned int fvp_pwrc_get_cpu_wkr(u_register_t mpidr) -{ - return PSYSR_WK(fvp_pwrc_read_psysr(mpidr)); -} - -unsigned int fvp_pwrc_read_psysr(u_register_t mpidr) -{ - unsigned int rc; - arm_lock_get(); - mmio_write_32(PWRC_BASE + PSYSR_OFF, (unsigned int) mpidr); - rc = mmio_read_32(PWRC_BASE + PSYSR_OFF); - arm_lock_release(); - return rc; -} - -void fvp_pwrc_write_pponr(u_register_t mpidr) -{ - arm_lock_get(); - mmio_write_32(PWRC_BASE + PPONR_OFF, (unsigned int) mpidr); - arm_lock_release(); -} - -void fvp_pwrc_write_ppoffr(u_register_t mpidr) -{ - arm_lock_get(); - mmio_write_32(PWRC_BASE + PPOFFR_OFF, (unsigned int) mpidr); - arm_lock_release(); -} - -void fvp_pwrc_set_wen(u_register_t mpidr) -{ - arm_lock_get(); - mmio_write_32(PWRC_BASE + PWKUPR_OFF, - (unsigned int) (PWKUPR_WEN | mpidr)); - arm_lock_release(); -} - -void fvp_pwrc_clr_wen(u_register_t mpidr) -{ - arm_lock_get(); - mmio_write_32(PWRC_BASE + PWKUPR_OFF, - (unsigned int) mpidr); - arm_lock_release(); -} - -void fvp_pwrc_write_pcoffr(u_register_t mpidr) -{ - arm_lock_get(); - mmio_write_32(PWRC_BASE + PCOFFR_OFF, (unsigned int) mpidr); - arm_lock_release(); -} - -/* Nothing else to do here apart from initializing the lock */ -void __init plat_arm_pwrc_setup(void) -{ - arm_lock_init(); -} - - - diff --git a/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.h b/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.h deleted file mode 100644 index 324f3e2..0000000 --- a/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef FVP_PWRC_H -#define FVP_PWRC_H - -/* FVP Power controller register offset etc */ -#define PPOFFR_OFF U(0x0) -#define PPONR_OFF U(0x4) -#define PCOFFR_OFF U(0x8) -#define PWKUPR_OFF U(0xc) -#define PSYSR_OFF U(0x10) - -#define PWKUPR_WEN BIT_32(31) - -#define PSYSR_AFF_L2 BIT_32(31) -#define PSYSR_AFF_L1 BIT_32(30) -#define PSYSR_AFF_L0 BIT_32(29) -#define PSYSR_WEN BIT_32(28) -#define PSYSR_PC BIT_32(27) -#define PSYSR_PP BIT_32(26) - -#define PSYSR_WK_SHIFT 24 -#define PSYSR_WK_WIDTH 0x2 -#define PSYSR_WK_MASK ((1U << PSYSR_WK_WIDTH) - 1U) -#define PSYSR_WK(x) ((x) >> PSYSR_WK_SHIFT) & PSYSR_WK_MASK - -#define WKUP_COLD U(0x0) -#define WKUP_RESET U(0x1) -#define WKUP_PPONR U(0x2) -#define WKUP_GICREQ U(0x3) - -#define PSYSR_INVALID U(0xffffffff) - -#ifndef __ASSEMBLY__ - -/******************************************************************************* - * Function & variable prototypes - ******************************************************************************/ -void fvp_pwrc_write_pcoffr(u_register_t mpidr); -void fvp_pwrc_write_ppoffr(u_register_t mpidr); -void fvp_pwrc_write_pponr(u_register_t mpidr); -void fvp_pwrc_set_wen(u_register_t mpidr); -void fvp_pwrc_clr_wen(u_register_t mpidr); -unsigned int fvp_pwrc_read_psysr(u_register_t mpidr); -unsigned int fvp_pwrc_get_cpu_wkr(u_register_t mpidr); - -#endif /*__ASSEMBLY__*/ - -#endif /* FVP_PWRC_H */ diff --git a/plat/arm/board/fvp/fvp_bl1_setup.c b/plat/arm/board/fvp/fvp_bl1_setup.c index d6e82f5..75090e8 100644 --- a/plat/arm/board/fvp/fvp_bl1_setup.c +++ b/plat/arm/board/fvp/fvp_bl1_setup.c @@ -5,10 +5,9 @@ */ #include +#include #include -#include - #include "fvp_private.h" /******************************************************************************* diff --git a/plat/arm/board/fvp/fvp_bl2_el3_setup.c b/plat/arm/board/fvp/fvp_bl2_el3_setup.c index 69f2f7a..7def56a 100644 --- a/plat/arm/board/fvp/fvp_bl2_el3_setup.c +++ b/plat/arm/board/fvp/fvp_bl2_el3_setup.c @@ -4,7 +4,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include + #include "fvp_private.h" void bl2_el3_early_platform_setup(u_register_t arg0 __unused, diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c index 7aa620b..d280949 100644 --- a/plat/arm/board/fvp/fvp_bl2_setup.c +++ b/plat/arm/board/fvp/fvp_bl2_setup.c @@ -7,10 +7,10 @@ #include #include #include +#include #include #include -#include #include "fvp_private.h" void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) diff --git a/plat/arm/board/fvp/fvp_bl2u_setup.c b/plat/arm/board/fvp/fvp_bl2u_setup.c index 6367be6..a8db055 100644 --- a/plat/arm/board/fvp/fvp_bl2u_setup.c +++ b/plat/arm/board/fvp/fvp_bl2u_setup.c @@ -4,10 +4,10 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include -#include #include "fvp_private.h" void bl2u_early_platform_setup(struct meminfo *mem_layout, void *plat_info) diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c index 5f2121c..7f28b20 100644 --- a/plat/arm/board/fvp/fvp_bl31_setup.c +++ b/plat/arm/board/fvp/fvp_bl31_setup.c @@ -5,10 +5,10 @@ */ #include +#include +#include #include -#include -#include #include "fvp_private.h" void __init bl31_early_platform_setup2(u_register_t arg0, diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index fdf82f4..b885b47 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -12,13 +12,12 @@ #include #include #include +#include +#include #include #include #include -#include -#include - #include "fvp_private.h" /* Defines for GIC Driver build time selection */ diff --git a/plat/arm/board/fvp/fvp_io_storage.c b/plat/arm/board/fvp/fvp_io_storage.c index e186b30..9c4c1d5 100644 --- a/plat/arm/board/fvp/fvp_io_storage.c +++ b/plat/arm/board/fvp/fvp_io_storage.c @@ -11,10 +11,9 @@ #include #include #include +#include #include -#include - /* Semihosting filenames */ #define BL2_IMAGE_NAME "bl2.bin" #define BL31_IMAGE_NAME "bl31.bin" diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c index 8ba8281..ecf0b01 100644 --- a/plat/arm/board/fvp/fvp_pm.c +++ b/plat/arm/board/fvp/fvp_pm.c @@ -10,17 +10,15 @@ #include #include #include +#include #include #include #include +#include +#include #include #include -#include -#include - -#include "../../../../drivers/arm/gic/v3/gicv3_private.h" -#include "drivers/pwrc/fvp_pwrc.h" #include "fvp_private.h" diff --git a/plat/arm/board/fvp/fvp_private.h b/plat/arm/board/fvp/fvp_private.h index e7dea99..3d96537 100644 --- a/plat/arm/board/fvp/fvp_private.h +++ b/plat/arm/board/fvp/fvp_private.h @@ -7,7 +7,7 @@ #ifndef FVP_PRIVATE_H #define FVP_PRIVATE_H -#include +#include /******************************************************************************* * Function and variable prototypes diff --git a/plat/arm/board/fvp/fvp_security.c b/plat/arm/board/fvp/fvp_security.c index 028522c..80ec217 100644 --- a/plat/arm/board/fvp/fvp_security.c +++ b/plat/arm/board/fvp/fvp_security.c @@ -4,8 +4,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include -#include +#include +#include /* * We assume that all security programming is done by the primary core. diff --git a/plat/arm/board/fvp/fvp_topology.c b/plat/arm/board/fvp/fvp_topology.c index 3384a2f..9823fb3 100644 --- a/plat/arm/board/fvp/fvp_topology.c +++ b/plat/arm/board/fvp/fvp_topology.c @@ -7,13 +7,12 @@ #include #include +#include #include +#include +#include #include -#include -#include -#include "drivers/pwrc/fvp_pwrc.h" - /* The FVP power domain tree descriptor */ static unsigned char fvp_power_domain_tree_desc[FVP_CLUSTER_COUNT + 2]; diff --git a/plat/arm/board/fvp/include/plat.ld.S b/plat/arm/board/fvp/include/plat.ld.S index ad2d46c..f024f55 100644 --- a/plat/arm/board/fvp/include/plat.ld.S +++ b/plat/arm/board/fvp/include/plat.ld.S @@ -6,7 +6,7 @@ #ifndef PLAT_LD_S #define PLAT_LD_S -#include -#include +#include +#include #endif /* PLAT_LD_S */ diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 8c0daf1..fcf363d 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -7,25 +7,13 @@ #ifndef PLATFORM_DEF_H #define PLATFORM_DEF_H -/* Enable the dynamic translation tables library. */ -#ifdef AARCH32 -# if defined(IMAGE_BL32) && RESET_TO_SP_MIN -# define PLAT_XLAT_TABLES_DYNAMIC 1 -# endif -#else -# if defined(IMAGE_BL31) && (RESET_TO_BL31 || (ENABLE_SPM && !SPM_MM)) -# define PLAT_XLAT_TABLES_DYNAMIC 1 -# endif -#endif /* AARCH32 */ - #include #include +#include +#include +#include #include -#include -#include -#include - #include "../fvp_def.h" /* Required platform porting definitions */ diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 3b60daa..f79ac46 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -146,14 +146,14 @@ BL2U_SOURCES += plat/arm/board/fvp/fvp_bl2u_setup.c \ ${FVP_SECURITY_SOURCES} -BL31_SOURCES += drivers/arm/smmu/smmu_v3.c \ +BL31_SOURCES += drivers/arm/fvp/fvp_pwrc.c \ + drivers/arm/smmu/smmu_v3.c \ drivers/cfi/v2m/v2m_flash.c \ lib/utils/mem_region.c \ plat/arm/board/fvp/fvp_bl31_setup.c \ plat/arm/board/fvp/fvp_pm.c \ plat/arm/board/fvp/fvp_topology.c \ plat/arm/board/fvp/aarch64/fvp_helpers.S \ - plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c \ plat/arm/common/arm_nor_psci_mem_protect.c \ ${FVP_CPU_LIBS} \ ${FVP_GIC_SOURCES} \ @@ -231,6 +231,22 @@ NEED_BL32 := yes endif +# Enable the dynamic translation tables library. +ifeq (${ARCH},aarch32) + ifeq (${RESET_TO_SP_MIN},1) + BL32_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + endif +else + ifeq (${RESET_TO_BL31},1) + BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + endif + ifeq (${ENABLE_SPM},1) + ifeq (${SPM_MM},0) + BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + endif + endif +endif + # Add support for platform supplied linker script for BL31 build $(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT)) diff --git a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c index 7c89c27..88c91e6 100644 --- a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c +++ b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c @@ -4,7 +4,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include + #include "../fvp_private.h" void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1, diff --git a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk index 8b17c9b..0250a5f 100644 --- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk +++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk @@ -5,10 +5,10 @@ # # SP_MIN source files specific to FVP platform -BL32_SOURCES += drivers/cfi/v2m/v2m_flash.c \ +BL32_SOURCES += drivers/arm/fvp/fvp_pwrc.c \ + drivers/cfi/v2m/v2m_flash.c \ lib/utils/mem_region.c \ plat/arm/board/fvp/aarch32/fvp_helpers.S \ - plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c \ plat/arm/board/fvp/fvp_pm.c \ plat/arm/board/fvp/fvp_topology.c \ plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c \ diff --git a/plat/arm/board/fvp/tsp/fvp_tsp_setup.c b/plat/arm/board/fvp/tsp/fvp_tsp_setup.c index 86d265a..3c8a963 100644 --- a/plat/arm/board/fvp/tsp/fvp_tsp_setup.c +++ b/plat/arm/board/fvp/tsp/fvp_tsp_setup.c @@ -4,7 +4,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include + #include "../fvp_private.h" void tsp_early_platform_setup(void) diff --git a/plat/arm/board/fvp/tsp/tsp-fvp.mk b/plat/arm/board/fvp/tsp/tsp-fvp.mk index 861fe72..ab3f225 100644 --- a/plat/arm/board/fvp/tsp/tsp-fvp.mk +++ b/plat/arm/board/fvp/tsp/tsp-fvp.mk @@ -5,8 +5,8 @@ # # TSP source files specific to FVP platform -BL32_SOURCES += plat/arm/board/fvp/aarch64/fvp_helpers.S \ - plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c \ +BL32_SOURCES += drivers/arm/fvp/fvp_pwrc.c \ + plat/arm/board/fvp/aarch64/fvp_helpers.S \ plat/arm/board/fvp/fvp_topology.c \ plat/arm/board/fvp/tsp/fvp_tsp_setup.c \ ${FVP_GIC_SOURCES} diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index b10cfdc..ddbc9b7 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,29 +7,17 @@ #ifndef PLATFORM_DEF_H #define PLATFORM_DEF_H -/* Enable the dynamic translation tables library. */ -#ifdef AARCH32 -# if defined(IMAGE_BL32) && RESET_TO_SP_MIN -# define PLAT_XLAT_TABLES_DYNAMIC 1 -# endif -#else -# if defined(IMAGE_BL31) && RESET_TO_BL31 -# define PLAT_XLAT_TABLES_DYNAMIC 1 -# endif -#endif /* AARCH32 */ - - #include #if TRUSTED_BOARD_BOOT #include #endif +#include +#include +#include +#include +#include #include -#include -#include -#include -#include -#include #include "../juno_def.h" /* Required platform porting definitions */ diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c index 383409d..f72a6ff 100644 --- a/plat/arm/board/juno/juno_bl1_setup.c +++ b/plat/arm/board/juno/juno_bl1_setup.c @@ -9,13 +9,12 @@ #include #include #include +#include #include +#include #include #include -#include -#include - void juno_reset_to_aarch32_state(void); static int is_watchdog_reset(void) diff --git a/plat/arm/board/juno/juno_bl2_setup.c b/plat/arm/board/juno/juno_bl2_setup.c index 56f05eb..95ef77c 100644 --- a/plat/arm/board/juno/juno_bl2_setup.c +++ b/plat/arm/board/juno/juno_bl2_setup.c @@ -8,8 +8,7 @@ #include #include - -#include +#include #if JUNO_AARCH32_EL3_RUNTIME /******************************************************************************* diff --git a/plat/arm/board/juno/juno_common.c b/plat/arm/board/juno/juno_common.c index e134108..118c19a 100644 --- a/plat/arm/board/juno/juno_common.c +++ b/plat/arm/board/juno/juno_common.c @@ -5,7 +5,7 @@ */ #include -#include +#include /* * Table of memory regions for different BL stages to map using the MMU. diff --git a/plat/arm/board/juno/juno_pm.c b/plat/arm/board/juno/juno_pm.c index dbf7b6c..cc80651 100644 --- a/plat/arm/board/juno/juno_pm.c +++ b/plat/arm/board/juno/juno_pm.c @@ -4,8 +4,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include -#include +#include +#include const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) { diff --git a/plat/arm/board/juno/juno_security.c b/plat/arm/board/juno/juno_security.c index 51c8669..9d7f0e4 100644 --- a/plat/arm/board/juno/juno_security.c +++ b/plat/arm/board/juno/juno_security.c @@ -8,9 +8,9 @@ #include #include #include +#include +#include -#include -#include #include "juno_tzmp1_def.h" #ifdef JUNO_TZMP1 diff --git a/plat/arm/board/juno/juno_topology.c b/plat/arm/board/juno/juno_topology.c index e70cbdc..ca5c344 100644 --- a/plat/arm/board/juno/juno_topology.c +++ b/plat/arm/board/juno/juno_topology.c @@ -4,14 +4,13 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include +#include +#include +#include #include #include -#include -#include -#include "../../css/drivers/scmi/scmi.h" -#include "../../css/drivers/mhu/css_mhu_doorbell.h" - #if CSS_USE_SCMI_SDS_DRIVER static scmi_channel_plat_info_t juno_scmi_plat_info = { .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE, diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index aec2b9b..6575811 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -26,9 +26,7 @@ # SCP during power management operations and for SCP RAM Firmware transfer. CSS_USE_SCMI_SDS_DRIVER := 1 -PLAT_INCLUDES := -Iplat/arm/board/juno/include \ - -Iplat/arm/css/drivers/scmi \ - -Iplat/arm/css/drivers/sds +PLAT_INCLUDES := -Iplat/arm/board/juno/include PLAT_BL_COMMON_SOURCES := plat/arm/board/juno/${ARCH}/juno_helpers.S \ plat/arm/board/juno/juno_common.c @@ -88,7 +86,7 @@ ${JUNO_SECURITY_SOURCES} ifeq (${CSS_USE_SCMI_SDS_DRIVER},1) -BL1_SOURCES += plat/arm/css/drivers/sds/sds.c +BL1_SOURCES += drivers/arm/css/sds/sds.c endif endif @@ -134,6 +132,17 @@ # Do not enable SVE ENABLE_SVE_FOR_NS := 0 +# Enable the dynamic translation tables library. +ifeq (${ARCH},aarch32) + ifeq (${RESET_TO_SP_MIN},1) + BL32_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + endif +else + ifeq (${RESET_TO_BL31},1) + BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 + endif +endif + include plat/arm/board/common/board_common.mk include plat/arm/common/arm_common.mk include plat/arm/soc/common/soc_css.mk diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h index 68d0f93..7b8c367 100644 --- a/plat/arm/board/n1sdp/include/platform_def.h +++ b/plat/arm/board/n1sdp/include/platform_def.h @@ -7,9 +7,9 @@ #ifndef PLATFORM_DEF_H #define PLATFORM_DEF_H -#include -#include -#include +#include +#include +#include /* UART related constants */ #define PLAT_ARM_BOOT_UART_BASE 0x2A400000 diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c index d044b7c..18a0dea 100644 --- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c +++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c @@ -6,9 +6,9 @@ #include -#include "../../css/drivers/scmi/scmi.h" -#include "../../css/drivers/mhu/css_mhu_doorbell.h" -#include +#include +#include +#include static scmi_channel_plat_info_t n1sdp_scmi_plat_info = { .scmi_mbx_mem = N1SDP_SCMI_PAYLOAD_BASE, diff --git a/plat/arm/board/n1sdp/n1sdp_plat.c b/plat/arm/board/n1sdp/n1sdp_plat.c index 87e1511..6905896 100644 --- a/plat/arm/board/n1sdp/n1sdp_plat.c +++ b/plat/arm/board/n1sdp/n1sdp_plat.c @@ -8,10 +8,9 @@ #include #include +#include #include -#include - /* * Table of regions to map using the MMU. * Replace or extend the below regions as required diff --git a/plat/arm/board/n1sdp/n1sdp_topology.c b/plat/arm/board/n1sdp/n1sdp_topology.c index c3b4550..edf1170 100644 --- a/plat/arm/board/n1sdp/n1sdp_topology.c +++ b/plat/arm/board/n1sdp/n1sdp_topology.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include /* Topology */ typedef struct n1sdp_topology { diff --git a/plat/arm/common/arm_bl1_fwu.c b/plat/arm/common/arm_bl1_fwu.c index cd92aa8..124c1af 100644 --- a/plat/arm/common/arm_bl1_fwu.c +++ b/plat/arm/common/arm_bl1_fwu.c @@ -13,10 +13,9 @@ #include #include #include +#include #include -#include - /* Struct to keep track of usable memory */ typedef struct bl1_mem_info { uintptr_t mem_base; diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c index 3a8b5c2..fd4809c 100644 --- a/plat/arm/common/arm_bl1_setup.c +++ b/plat/arm/common/arm_bl1_setup.c @@ -14,10 +14,9 @@ #include #include #include +#include #include -#include - /* Weak definitions may be overridden in specific ARM standard platform */ #pragma weak bl1_early_platform_setup #pragma weak bl1_plat_arch_setup diff --git a/plat/arm/common/arm_bl2_el3_setup.c b/plat/arm/common/arm_bl2_el3_setup.c index c38f2ec..0c01c87 100644 --- a/plat/arm/common/arm_bl2_el3_setup.c +++ b/plat/arm/common/arm_bl2_el3_setup.c @@ -7,11 +7,10 @@ #include #include +#include #include #include -#include - #pragma weak bl2_el3_early_platform_setup #pragma weak bl2_el3_plat_arch_setup #pragma weak bl2_el3_plat_prepare_exit diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index b661eb1..32617f6 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -18,10 +18,9 @@ #include #endif #include +#include #include -#include - /* Data structure which holds the extents of the trusted SRAM for BL2 */ static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); diff --git a/plat/arm/common/arm_bl2u_setup.c b/plat/arm/common/arm_bl2u_setup.c index 332ed14..9f44b9e 100644 --- a/plat/arm/common/arm_bl2u_setup.c +++ b/plat/arm/common/arm_bl2u_setup.c @@ -12,10 +12,9 @@ #include #include #include +#include #include -#include - /* Weak definitions may be overridden in specific ARM standard platform */ #pragma weak bl2u_platform_setup #pragma weak bl2u_early_platform_setup diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index dacefc4..8e1a263 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -15,11 +15,10 @@ #include #include #include +#include #include #include -#include - /* * Placeholder variables for copying the arguments that have been passed to * BL31 from BL2. diff --git a/plat/arm/common/arm_cci.c b/plat/arm/common/arm_cci.c index 7ee997e..3795fc5 100644 --- a/plat/arm/common/arm_cci.c +++ b/plat/arm/common/arm_cci.c @@ -9,8 +9,7 @@ #include #include #include - -#include +#include static const int cci_map[] = { PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX, diff --git a/plat/arm/common/arm_ccn.c b/plat/arm/common/arm_ccn.c index 6aa56f2..2e681ca 100644 --- a/plat/arm/common/arm_ccn.c +++ b/plat/arm/common/arm_ccn.c @@ -8,8 +8,7 @@ #include #include - -#include +#include static const unsigned char master_to_rn_id_map[] = { PLAT_ARM_CLUSTER_TO_CCN_ID_MAP diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c index 4cd2ce3..5361d4a 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -14,11 +14,10 @@ #include #include #include +#include #include #include -#include - /* Weak definitions may be overridden in specific ARM standard platform */ #pragma weak plat_get_ns_image_entrypoint #pragma weak plat_arm_get_mmap diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 9ad7bd7..f18a9af 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -141,9 +141,6 @@ endif endif -PLAT_INCLUDES += -Iinclude/common/tbbr \ - -Iinclude/plat/arm/common - ifeq (${ARCH}, aarch64) PLAT_INCLUDES += -Iinclude/plat/arm/common/aarch64 endif @@ -257,8 +254,6 @@ drivers/auth/img_parser_mod.c \ drivers/auth/tbbr/tbbr_cot.c \ - PLAT_INCLUDES += -Iinclude/bl1/tbbr - BL1_SOURCES += ${AUTH_SOURCES} \ bl1/tbbr/tbbr_img_desc.c \ plat/arm/common/arm_bl1_fwu.c \ diff --git a/plat/arm/common/arm_console.c b/plat/arm/common/arm_console.c index 29cb378..0367085 100644 --- a/plat/arm/common/arm_console.c +++ b/plat/arm/common/arm_console.c @@ -11,8 +11,7 @@ #include #include #include - -#include +#include /******************************************************************************* * Functions that set up the console diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index 6c6dc56..1c58649 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -15,11 +15,10 @@ #if TRUSTED_BOARD_BOOT #include #endif +#include +#include #include -#include -#include - /* Variable to store the address to TB_FW_CONFIG passed from BL1 */ static void *tb_fw_cfg_dtb; static size_t tb_fw_cfg_dtb_size; diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c index bf2f156..36d37f8 100644 --- a/plat/arm/common/arm_dyn_cfg_helpers.c +++ b/plat/arm/common/arm_dyn_cfg_helpers.c @@ -10,9 +10,8 @@ #include #include - -#include -#include +#include +#include #define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr" #define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size" diff --git a/plat/arm/common/arm_err.c b/plat/arm/common/arm_err.c index 8650d48..e77f5dc 100644 --- a/plat/arm/common/arm_err.c +++ b/plat/arm/common/arm_err.c @@ -13,10 +13,9 @@ #include #include #include +#include #include -#include - #pragma weak plat_arm_error_handler /* diff --git a/plat/arm/common/arm_gicv2.c b/plat/arm/common/arm_gicv2.c index fc848c1..80a845f 100644 --- a/plat/arm/common/arm_gicv2.c +++ b/plat/arm/common/arm_gicv2.c @@ -7,10 +7,9 @@ #include #include +#include #include -#include - /****************************************************************************** * The following functions are defined as weak to allow a platform to override * the way the GICv2 driver is initialised and used. diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c index e16e13d..93bebf3 100644 --- a/plat/arm/common/arm_gicv3.c +++ b/plat/arm/common/arm_gicv3.c @@ -9,10 +9,9 @@ #include #include #include +#include #include -#include - /****************************************************************************** * The following functions are defined as weak to allow a platform to override * the way the GICv3 driver is initialised and used. diff --git a/plat/arm/common/arm_image_load.c b/plat/arm/common/arm_image_load.c index 74018d2..2faaa76 100644 --- a/plat/arm/common/arm_image_load.c +++ b/plat/arm/common/arm_image_load.c @@ -7,10 +7,9 @@ #include #include #include +#include #include -#include - #pragma weak plat_flush_next_bl_params #pragma weak plat_get_bl_image_load_info #pragma weak plat_get_next_bl_params diff --git a/plat/arm/common/arm_io_storage.c b/plat/arm/common/arm_io_storage.c index d7c5cac..fc1eb49 100644 --- a/plat/arm/common/arm_io_storage.c +++ b/plat/arm/common/arm_io_storage.c @@ -15,11 +15,10 @@ #include #include #include +#include #include #include -#include - /* IO devices */ static const io_dev_connector_t *fip_dev_con; static uintptr_t fip_dev_handle; diff --git a/plat/arm/common/arm_nor_psci_mem_protect.c b/plat/arm/common/arm_nor_psci_mem_protect.c index 4ae57e5..dfbd129 100644 --- a/plat/arm/common/arm_nor_psci_mem_protect.c +++ b/plat/arm/common/arm_nor_psci_mem_protect.c @@ -11,8 +11,7 @@ #include #include #include - -#include +#include /* * DRAM1 is used also to load the NS boot loader. For this reason we diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c index 4ce13aa..cb87baf 100644 --- a/plat/arm/common/arm_pm.c +++ b/plat/arm/common/arm_pm.c @@ -11,10 +11,9 @@ #include #include +#include #include -#include - /* Allow ARM Standard platforms to override these functions */ #pragma weak plat_arm_program_trusted_mailbox diff --git a/plat/arm/common/arm_sip_svc.c b/plat/arm/common/arm_sip_svc.c index 6b0f7e7..3d308a3 100644 --- a/plat/arm/common/arm_sip_svc.c +++ b/plat/arm/common/arm_sip_svc.c @@ -9,11 +9,10 @@ #include #include #include +#include +#include #include -#include -#include - /* ARM SiP Service UUID */ DEFINE_SVC_UUID2(arm_sip_svc_uid, 0x556d75e2, 0x6033, 0xb54b, 0xb5, 0x75, diff --git a/plat/arm/common/arm_topology.c b/plat/arm/common/arm_topology.c index 6986e52..37047bc 100644 --- a/plat/arm/common/arm_topology.c +++ b/plat/arm/common/arm_topology.c @@ -7,8 +7,7 @@ #include #include - -#include +#include /******************************************************************************* * This function validates an MPIDR by checking whether it falls within the diff --git a/plat/arm/common/arm_tzc400.c b/plat/arm/common/arm_tzc400.c index 322713b..34e650f 100644 --- a/plat/arm/common/arm_tzc400.c +++ b/plat/arm/common/arm_tzc400.c @@ -8,8 +8,7 @@ #include #include - -#include +#include /* Weak definitions may be overridden in specific ARM standard platform */ #pragma weak plat_arm_security_setup diff --git a/plat/arm/common/arm_tzc_dmc500.c b/plat/arm/common/arm_tzc_dmc500.c index 07260a7..e9f897f 100644 --- a/plat/arm/common/arm_tzc_dmc500.c +++ b/plat/arm/common/arm_tzc_dmc500.c @@ -10,8 +10,7 @@ #include #include - -#include +#include /******************************************************************************* * Initialize the DMC500-TrustZone Controller for ARM standard platforms. diff --git a/plat/arm/common/execution_state_switch.c b/plat/arm/common/execution_state_switch.c index e313410..d471130 100644 --- a/plat/arm/common/execution_state_switch.c +++ b/plat/arm/common/execution_state_switch.c @@ -12,11 +12,10 @@ #include #include #include +#include +#include #include -#include -#include - /* * Handle SMC from a lower exception level to switch its execution state * (either from AArch64 to AArch32, or vice versa). diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c index 967b551..c0ea027 100644 --- a/plat/arm/common/sp_min/arm_sp_min_setup.c +++ b/plat/arm/common/sp_min/arm_sp_min_setup.c @@ -14,10 +14,9 @@ #include #include #include +#include #include -#include - static entry_point_info_t bl33_image_ep_info; /* Weak definitions may be overridden in specific ARM standard platform */ diff --git a/plat/arm/common/tsp/arm_tsp_setup.c b/plat/arm/common/tsp/arm_tsp_setup.c index 2937697..2965ccd 100644 --- a/plat/arm/common/tsp/arm_tsp_setup.c +++ b/plat/arm/common/tsp/arm_tsp_setup.c @@ -13,8 +13,7 @@ #include #include #include - -#include +#include #define BL32_END (unsigned long)(&__BL32_END__) diff --git a/plat/arm/css/common/css_bl1_setup.c b/plat/arm/css/common/css_bl1_setup.c index ae0f011..596cc3d 100644 --- a/plat/arm/css/common/css_bl1_setup.c +++ b/plat/arm/css/common/css_bl1_setup.c @@ -6,11 +6,10 @@ #include #include +#include +#include #include -#include -#include - void bl1_platform_setup(void) { arm_bl1_platform_setup(); diff --git a/plat/arm/css/common/css_bl2_setup.c b/plat/arm/css/common/css_bl2_setup.c index 6aefe03..002c6eb 100644 --- a/plat/arm/css/common/css_bl2_setup.c +++ b/plat/arm/css/common/css_bl2_setup.c @@ -8,14 +8,12 @@ #include #include +#include #include #include +#include #include -#include - -#include "../drivers/scp/css_scp.h" - /* Weak definition may be overridden in specific CSS based platform */ #pragma weak plat_arm_bl2_handle_scp_bl2 diff --git a/plat/arm/css/common/css_bl2u_setup.c b/plat/arm/css/common/css_bl2u_setup.c index 564e98f..15cf4f6 100644 --- a/plat/arm/css/common/css_bl2u_setup.c +++ b/plat/arm/css/common/css_bl2u_setup.c @@ -6,12 +6,10 @@ #include #include +#include +#include #include -#include - -#include "../drivers/scp/css_scp.h" - /* Weak definition may be overridden in specific CSS based platform */ #pragma weak bl2u_plat_handle_scp_bl2u diff --git a/plat/arm/css/common/css_common.mk b/plat/arm/css/common/css_common.mk index ca1edab..2fbbe45 100644 --- a/plat/arm/css/common/css_common.mk +++ b/plat/arm/css/common/css_common.mk @@ -11,8 +11,7 @@ # By default, SCMI driver is disabled for CSS platforms CSS_USE_SCMI_SDS_DRIVER ?= 0 -PLAT_INCLUDES += -Iinclude/plat/arm/css/common \ - -Iinclude/plat/arm/css/common/aarch64 +PLAT_INCLUDES += -Iinclude/plat/arm/css/common/aarch64 PLAT_BL_COMMON_SOURCES += plat/arm/css/common/${ARCH}/css_helpers.S @@ -27,16 +26,16 @@ plat/arm/css/common/css_topology.c ifeq (${CSS_USE_SCMI_SDS_DRIVER},0) -BL31_SOURCES += plat/arm/css/drivers/scp/css_pm_scpi.c \ - plat/arm/css/drivers/mhu/css_mhu.c \ - plat/arm/css/drivers/scpi/css_scpi.c +BL31_SOURCES += drivers/arm/css/mhu/css_mhu.c \ + drivers/arm/css/scp/css_pm_scpi.c \ + drivers/arm/css/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 \ - plat/arm/css/drivers/mhu/css_mhu_doorbell.c +BL31_SOURCES += drivers/arm/css/mhu/css_mhu_doorbell.c \ + drivers/arm/css/scmi/scmi_ap_core_proto.c \ + drivers/arm/css/scmi/scmi_common.c \ + drivers/arm/css/scmi/scmi_pwr_dmn_proto.c \ + drivers/arm/css/scmi/scmi_sys_pwr_proto.c \ + drivers/arm/css/scp/css_pm_scmi.c endif # Process CSS_LOAD_SCP_IMAGES flag @@ -50,19 +49,19 @@ endif ifeq (${CSS_USE_SCMI_SDS_DRIVER},1) - BL2U_SOURCES += plat/arm/css/drivers/scp/css_sds.c \ - plat/arm/css/drivers/sds/sds.c + BL2U_SOURCES += drivers/arm/css/scp/css_sds.c \ + drivers/arm/css/sds/sds.c - BL2_SOURCES += plat/arm/css/drivers/scp/css_sds.c \ - plat/arm/css/drivers/sds/sds.c + BL2_SOURCES += drivers/arm/css/scp/css_sds.c \ + drivers/arm/css/sds/sds.c else - BL2U_SOURCES += plat/arm/css/drivers/scp/css_bom_bootloader.c \ - plat/arm/css/drivers/mhu/css_mhu.c \ - plat/arm/css/drivers/scpi/css_scpi.c + BL2U_SOURCES += drivers/arm/css/mhu/css_mhu.c \ + drivers/arm/css/scp/css_bom_bootloader.c \ + drivers/arm/css/scpi/css_scpi.c - BL2_SOURCES += plat/arm/css/drivers/scp/css_bom_bootloader.c \ - plat/arm/css/drivers/mhu/css_mhu.c \ - plat/arm/css/drivers/scpi/css_scpi.c + BL2_SOURCES += drivers/arm/css/mhu/css_mhu.c \ + drivers/arm/css/scp/css_bom_bootloader.c \ + drivers/arm/css/scpi/css_scpi.c # Enable option to detect whether the SCP ROM firmware in use predates version # 1.7.0 and therefore, is incompatible. CSS_DETECT_PRE_1_7_0_SCP := 1 @@ -74,7 +73,7 @@ endif ifeq (${CSS_USE_SCMI_SDS_DRIVER},1) - PLAT_BL_COMMON_SOURCES += plat/arm/css/drivers/sds/${ARCH}/sds_helpers.S + PLAT_BL_COMMON_SOURCES += drivers/arm/css/sds/${ARCH}/sds_helpers.S endif # Process CSS_USE_SCMI_SDS_DRIVER flag diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c index 8a156e6..f6fc6aa 100644 --- a/plat/arm/css/common/css_pm.c +++ b/plat/arm/css/common/css_pm.c @@ -11,14 +11,12 @@ #include #include +#include #include +#include +#include #include -#include -#include - -#include "../drivers/scp/css_scp.h" - /* Allow CSS platforms to override `plat_arm_psci_pm_ops` */ #pragma weak plat_arm_psci_pm_ops diff --git a/plat/arm/css/common/css_topology.c b/plat/arm/css/common/css_topology.c index 8ac2232..8aca744 100644 --- a/plat/arm/css/common/css_topology.c +++ b/plat/arm/css/common/css_topology.c @@ -6,10 +6,9 @@ #include +#include #include -#include - #if ARM_PLAT_MT #pragma weak plat_arm_get_cpu_pe_count #endif diff --git a/plat/arm/css/common/sp_min/css_sp_min.mk b/plat/arm/css/common/sp_min/css_sp_min.mk index 9fb280c..6523a16 100644 --- a/plat/arm/css/common/sp_min/css_sp_min.mk +++ b/plat/arm/css/common/sp_min/css_sp_min.mk @@ -9,13 +9,13 @@ plat/arm/css/common/css_topology.c ifeq (${CSS_USE_SCMI_SDS_DRIVER},0) -BL32_SOURCES += plat/arm/css/drivers/scp/css_pm_scpi.c \ - plat/arm/css/drivers/mhu/css_mhu.c \ - plat/arm/css/drivers/scpi/css_scpi.c +BL32_SOURCES += drivers/arm/css/mhu/css_mhu.c \ + drivers/arm/css/scp/css_pm_scpi.c \ + drivers/arm/css/scpi/css_scpi.c else -BL32_SOURCES += plat/arm/css/drivers/scp/css_pm_scmi.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 \ - plat/arm/css/drivers/mhu/css_mhu_doorbell.c +BL32_SOURCES += drivers/arm/css/mhu/css_mhu_doorbell.c \ + drivers/arm/css/scp/css_pm_scmi.c \ + drivers/arm/css/scmi/scmi_common.c \ + drivers/arm/css/scmi/scmi_pwr_dmn_proto.c \ + drivers/arm/css/scmi/scmi_sys_pwr_proto.c endif diff --git a/plat/arm/css/drivers/mhu/css_mhu.c b/plat/arm/css/drivers/mhu/css_mhu.c deleted file mode 100644 index 981df9c..0000000 --- a/plat/arm/css/drivers/mhu/css_mhu.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include - -#include -#include -#include - -#include - -#include "css_mhu.h" - -/* SCP MHU secure channel registers */ -#define SCP_INTR_S_STAT 0x200 -#define SCP_INTR_S_SET 0x208 -#define SCP_INTR_S_CLEAR 0x210 - -/* CPU MHU secure channel registers */ -#define CPU_INTR_S_STAT 0x300 -#define CPU_INTR_S_SET 0x308 -#define CPU_INTR_S_CLEAR 0x310 - -ARM_INSTANTIATE_LOCK; - -/* Weak definition may be overridden in specific CSS based platform */ -#pragma weak plat_arm_pwrc_setup - - -/* - * Slot 31 is reserved because the MHU hardware uses this register bit to - * indicate a non-secure access attempt. The total number of available slots is - * therefore 31 [30:0]. - */ -#define MHU_MAX_SLOT_ID 30 - -void mhu_secure_message_start(unsigned int slot_id) -{ - assert(slot_id <= MHU_MAX_SLOT_ID); - - arm_lock_get(); - - /* Make sure any previous command has finished */ - while (mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) & - (1 << slot_id)) - ; -} - -void mhu_secure_message_send(unsigned int slot_id) -{ - assert(slot_id <= MHU_MAX_SLOT_ID); - assert(!(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) & - (1 << slot_id))); - - /* Send command to SCP */ - mmio_write_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_SET, 1 << slot_id); -} - -uint32_t mhu_secure_message_wait(void) -{ - /* Wait for response from SCP */ - uint32_t response; - while (!(response = mmio_read_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_STAT))) - ; - - return response; -} - -void mhu_secure_message_end(unsigned int slot_id) -{ - assert(slot_id <= MHU_MAX_SLOT_ID); - - /* - * Clear any response we got by writing one in the relevant slot bit to - * the CLEAR register - */ - mmio_write_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_CLEAR, 1 << slot_id); - - arm_lock_release(); -} - -void __init mhu_secure_init(void) -{ - arm_lock_init(); - - /* - * The STAT register resets to zero. Ensure it is in the expected state, - * as a stale or garbage value would make us think it's a message we've - * already sent. - */ - assert(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) == 0); -} - -void __init plat_arm_pwrc_setup(void) -{ - mhu_secure_init(); -} diff --git a/plat/arm/css/drivers/mhu/css_mhu.h b/plat/arm/css/drivers/mhu/css_mhu.h deleted file mode 100644 index ff04ae4..0000000 --- a/plat/arm/css/drivers/mhu/css_mhu.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef CSS_MHU_H -#define CSS_MHU_H - -#include - -void mhu_secure_message_start(unsigned int slot_id); -void mhu_secure_message_send(unsigned int slot_id); -uint32_t mhu_secure_message_wait(void); -void mhu_secure_message_end(unsigned int slot_id); - -void mhu_secure_init(void); - -#endif /* CSS_MHU_H */ diff --git a/plat/arm/css/drivers/mhu/css_mhu_doorbell.c b/plat/arm/css/drivers/mhu/css_mhu_doorbell.c deleted file mode 100644 index 964428b..0000000 --- a/plat/arm/css/drivers/mhu/css_mhu_doorbell.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include - -#include "css_mhu_doorbell.h" -#include "../scmi/scmi.h" - -void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info) -{ - MHU_RING_DOORBELL(plat_info->db_reg_addr, - plat_info->db_modify_mask, - plat_info->db_preserve_mask); - return; -} - -void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info) -{ - /* wake receiver */ - MHU_V2_ACCESS_REQUEST(MHUV2_BASE_ADDR); - - /* wait for receiver to acknowledge its ready */ - while (MHU_V2_IS_ACCESS_READY(MHUV2_BASE_ADDR) == 0) - ; - - MHU_RING_DOORBELL(plat_info->db_reg_addr, - plat_info->db_modify_mask, - plat_info->db_preserve_mask); - - /* clear the access request for the receiver */ - MHU_V2_CLEAR_REQUEST(MHUV2_BASE_ADDR); - - return; -} diff --git a/plat/arm/css/drivers/mhu/css_mhu_doorbell.h b/plat/arm/css/drivers/mhu/css_mhu_doorbell.h deleted file mode 100644 index ecee563..0000000 --- a/plat/arm/css/drivers/mhu/css_mhu_doorbell.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef CSS_MHU_DOORBELL_H -#define CSS_MHU_DOORBELL_H - -#include - -#include - -/* MHUv2 Base Address */ -#define MHUV2_BASE_ADDR PLAT_CSS_MHU_BASE - -/* MHUv2 Control Registers Offsets */ -#define MHU_V2_MSG_NO_CAP_OFFSET 0xF80 -#define MHU_V2_ACCESS_REQ_OFFSET 0xF88 -#define MHU_V2_ACCESS_READY_OFFSET 0xF8C - -#define SENDER_REG_STAT(_channel) (0x20 * (_channel)) -#define SENDER_REG_SET(_channel) ((0x20 * (_channel)) + 0xC) - -/* Helper macro to ring doorbell */ -#define MHU_RING_DOORBELL(addr, modify_mask, preserve_mask) do { \ - uint32_t db = mmio_read_32(addr) & (preserve_mask); \ - mmio_write_32(addr, db | (modify_mask)); \ - } while (0) - -#define MHU_V2_ACCESS_REQUEST(addr) \ - mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x1) - -#define MHU_V2_CLEAR_REQUEST(addr) \ - mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x0) - -#define MHU_V2_IS_ACCESS_READY(addr) \ - (mmio_read_32((addr) + MHU_V2_ACCESS_READY_OFFSET) & 0x1) - -struct scmi_channel_plat_info; -void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info); -void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info); - -#endif /* CSS_MHU_DOORBELL_H */ diff --git a/plat/arm/css/drivers/scmi/scmi.h b/plat/arm/css/drivers/scmi/scmi.h deleted file mode 100644 index df259f7..0000000 --- a/plat/arm/css/drivers/scmi/scmi.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef SCMI_H -#define SCMI_H - -#include -#include - -#include -#include -#include - -/* 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) - -#define GET_SCMI_MAJOR_VER(ver) (((ver) >> 16) & 0xffff) -#define GET_SCMI_MINOR_VER(ver) ((ver) & 0xffff) - -#define MAKE_SCMI_VERSION(maj, min) \ - ((((maj) & 0xffff) << 16) | ((min) & 0xffff)) - -/* Macro to check if the driver is compatible with the SCMI version reported */ -#define is_scmi_version_compatible(drv, scmi) \ - ((GET_SCMI_MAJOR_VER(drv) == GET_SCMI_MAJOR_VER(scmi)) && \ - (GET_SCMI_MINOR_VER(drv) <= GET_SCMI_MINOR_VER(scmi))) - -/* 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 -#define SCMI_PROTO_ATTR_MSG 0x1 -#define SCMI_PROTO_MSG_ATTR_MSG 0x2 - -/* SCMI power domain management protocol message IDs */ -#define SCMI_PWR_STATE_SET_MSG 0x4 -#define SCMI_PWR_STATE_GET_MSG 0x5 - -/* SCMI system power management protocol message IDs */ -#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 */ - -/* - * Macros to describe the bit-fields of the `attribute` of system power domain - * protocol PROTOCOL_MSG_ATTRIBUTE message. - */ -#define SYS_PWR_ATTR_WARM_RESET_SHIFT 31 -#define SCMI_SYS_PWR_WARM_RESET_SUPPORTED (1U << SYS_PWR_ATTR_WARM_RESET_SHIFT) - -#define SYS_PWR_ATTR_SUSPEND_SHIFT 30 -#define SCMI_SYS_PWR_SUSPEND_SUPPORTED (1 << SYS_PWR_ATTR_SUSPEND_SHIFT) - -/* - * Macros to describe the bit-fields of the `flags` parameter of system power - * domain protocol SYSTEM_POWER_STATE_SET message. - */ -#define SYS_PWR_SET_GRACEFUL_REQ_SHIFT 0 -#define SCMI_SYS_PWR_GRACEFUL_REQ (1 << SYS_PWR_SET_GRACEFUL_REQ_SHIFT) -#define SCMI_SYS_PWR_FORCEFUL_REQ (0 << SYS_PWR_SET_GRACEFUL_REQ_SHIFT) - -/* - * Macros to describe the `system_state` parameter of system power - * domain protocol SYSTEM_POWER_STATE_SET message. - */ -#define SCMI_SYS_PWR_SHUTDOWN 0x0 -#define SCMI_SYS_PWR_COLD_RESET 0x1 -#define SCMI_SYS_PWR_WARM_RESET 0x2 -#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 -#define SCMI_E_NOT_SUPPORTED -1 -#define SCMI_E_INVALID_PARAM -2 -#define SCMI_E_DENIED -3 -#define SCMI_E_NOT_FOUND -4 -#define SCMI_E_OUT_OF_RANGE -5 -#define SCMI_E_BUSY -6 - -/* - * SCMI driver platform information. The details of the doorbell mechanism - * can be found in the SCMI specification. - */ -typedef struct scmi_channel_plat_info { - /* SCMI mailbox memory */ - uintptr_t scmi_mbx_mem; - /* The door bell register address */ - uintptr_t db_reg_addr; - /* The bit mask that need to be preserved when ringing doorbell */ - uint32_t db_preserve_mask; - /* The bit mask that need to be set to ring doorbell */ - uint32_t db_modify_mask; - /* The handler for ringing doorbell */ - void (*ring_doorbell)(struct scmi_channel_plat_info *plat_info); - /* cookie is unused now. But added for future enhancements. */ - void *cookie; -} scmi_channel_plat_info_t; - - -#if HW_ASSISTED_COHERENCY -typedef spinlock_t scmi_lock_t; -#else -typedef bakery_lock_t scmi_lock_t; -#endif - -/* - * Structure to represent an SCMI channel. - */ -typedef struct scmi_channel { - scmi_channel_plat_info_t *info; - /* The lock for channel access */ - scmi_lock_t *lock; - /* Indicate whether the channel is initialized */ - int is_initialized; -} scmi_channel_t; - -/* External Common API */ -void *scmi_init(scmi_channel_t *ch); -int scmi_proto_msg_attr(void *p, uint32_t proto_id, uint32_t command_id, - uint32_t *attr); -int scmi_proto_version(void *p, uint32_t proto_id, uint32_t *version); - -/* - * Power domain protocol commands. Refer to the SCMI specification for more - * details on these commands. - */ -int scmi_pwr_state_set(void *p, uint32_t domain_id, uint32_t scmi_pwr_state); -int scmi_pwr_state_get(void *p, uint32_t domain_id, uint32_t *scmi_pwr_state); - -/* - * System power management protocol commands. Refer SCMI specification for more - * details on these commands. - */ -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); - -/* API to get the platform specific SCMI channel information. */ -scmi_channel_plat_info_t *plat_css_get_scmi_info(); - -/* API to override default PSCI callbacks for platforms that support SCMI. */ -const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops); - -#endif /* SCMI_H */ diff --git a/plat/arm/css/drivers/scmi/scmi_ap_core_proto.c b/plat/arm/css/drivers/scmi/scmi_ap_core_proto.c deleted file mode 100644 index e495dcc..0000000 --- a/plat/arm/css/drivers/scmi/scmi_ap_core_proto.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include - -#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; -} diff --git a/plat/arm/css/drivers/scmi/scmi_common.c b/plat/arm/css/drivers/scmi/scmi_common.c deleted file mode 100644 index 1b4ecb2..0000000 --- a/plat/arm/css/drivers/scmi/scmi_common.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include - -#include "scmi.h" -#include "scmi_private.h" - -#if HW_ASSISTED_COHERENCY -#define scmi_lock_init(lock) -#define scmi_lock_get(lock) spin_lock(lock) -#define scmi_lock_release(lock) spin_unlock(lock) -#else -#define scmi_lock_init(lock) bakery_lock_init(lock) -#define scmi_lock_get(lock) bakery_lock_get(lock) -#define scmi_lock_release(lock) bakery_lock_release(lock) -#endif - - -/* - * Private helper function to get exclusive access to SCMI channel. - */ -void scmi_get_channel(scmi_channel_t *ch) -{ - assert(ch->lock); - scmi_lock_get(ch->lock); - - /* Make sure any previous command has finished */ - assert(SCMI_IS_CHANNEL_FREE( - ((mailbox_mem_t *)(ch->info->scmi_mbx_mem))->status)); -} - -/* - * Private helper function to transfer ownership of channel from AP to SCP. - */ -void scmi_send_sync_command(scmi_channel_t *ch) -{ - mailbox_mem_t *mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem); - - SCMI_MARK_CHANNEL_BUSY(mbx_mem->status); - - /* - * Ensure that any write to the SCMI payload area is seen by SCP before - * we write to the doorbell register. If these 2 writes were reordered - * by the CPU then SCP would read stale payload data - */ - dmbst(); - - ch->info->ring_doorbell(ch->info); - /* - * Ensure that the write to the doorbell register is ordered prior to - * checking whether the channel is free. - */ - dmbsy(); - - /* Wait for channel to be free */ - while (!SCMI_IS_CHANNEL_FREE(mbx_mem->status)) - ; - - /* - * Ensure that any read to the SCMI payload area is done after reading - * mailbox status. If these 2 reads were reordered then the CPU would - * read invalid payload data - */ - dmbld(); -} - -/* - * Private helper function to release exclusive access to SCMI channel. - */ -void scmi_put_channel(scmi_channel_t *ch) -{ - /* Make sure any previous command has finished */ - assert(SCMI_IS_CHANNEL_FREE( - ((mailbox_mem_t *)(ch->info->scmi_mbx_mem))->status)); - - assert(ch->lock); - scmi_lock_release(ch->lock); -} - -/* - * API to query the SCMI protocol version. - */ -int scmi_proto_version(void *p, uint32_t proto_id, uint32_t *version) -{ - 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(proto_id, SCMI_PROTO_VERSION_MSG, - token); - mbx_mem->len = SCMI_PROTO_VERSION_MSG_LEN; - mbx_mem->flags = SCMI_FLAG_RESP_POLL; - - scmi_send_sync_command(ch); - - /* Get the return values */ - SCMI_PAYLOAD_RET_VAL2(mbx_mem->payload, ret, *version); - assert(mbx_mem->len == SCMI_PROTO_VERSION_RESP_LEN); - assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header)); - - scmi_put_channel(ch); - - return ret; -} - -/* - * API to query the protocol message attributes for a SCMI protocol. - */ -int scmi_proto_msg_attr(void *p, uint32_t proto_id, - uint32_t command_id, 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(proto_id, - SCMI_PROTO_MSG_ATTR_MSG, token); - mbx_mem->len = SCMI_PROTO_MSG_ATTR_MSG_LEN; - mbx_mem->flags = SCMI_FLAG_RESP_POLL; - SCMI_PAYLOAD_ARG1(mbx_mem->payload, command_id); - - scmi_send_sync_command(ch); - - /* Get the return values */ - SCMI_PAYLOAD_RET_VAL2(mbx_mem->payload, ret, *attr); - assert(mbx_mem->len == SCMI_PROTO_MSG_ATTR_RESP_LEN); - assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header)); - - scmi_put_channel(ch); - - return ret; -} - -/* - * SCMI Driver initialization API. Returns initialized channel on success - * or NULL on error. The return type is an opaque void pointer. - */ -void *scmi_init(scmi_channel_t *ch) -{ - uint32_t version; - int ret; - - assert(ch && ch->info); - assert(ch->info->db_reg_addr); - assert(ch->info->db_modify_mask); - assert(ch->info->db_preserve_mask); - assert(ch->info->ring_doorbell != NULL); - - assert(ch->lock); - - scmi_lock_init(ch->lock); - - ch->is_initialized = 1; - - ret = scmi_proto_version(ch, SCMI_PWR_DMN_PROTO_ID, &version); - if (ret != SCMI_E_SUCCESS) { - WARN("SCMI power domain protocol version message failed"); - goto error; - } - - if (!is_scmi_version_compatible(SCMI_PWR_DMN_PROTO_VER, version)) { - WARN("SCMI power domain protocol version 0x%x incompatible with driver version 0x%x", - version, SCMI_PWR_DMN_PROTO_VER); - goto error; - } - - VERBOSE("SCMI power domain protocol version 0x%x detected\n", version); - - ret = scmi_proto_version(ch, SCMI_SYS_PWR_PROTO_ID, &version); - if ((ret != SCMI_E_SUCCESS)) { - WARN("SCMI system power protocol version message failed"); - goto error; - } - - if (!is_scmi_version_compatible(SCMI_SYS_PWR_PROTO_VER, version)) { - WARN("SCMI system power management protocol version 0x%x incompatible with driver version 0x%x", - version, SCMI_SYS_PWR_PROTO_VER); - goto error; - } - - VERBOSE("SCMI system power management protocol version 0x%x detected\n", - version); - - INFO("SCMI driver initialized\n"); - - return (void *)ch; - -error: - ch->is_initialized = 0; - return NULL; -} diff --git a/plat/arm/css/drivers/scmi/scmi_private.h b/plat/arm/css/drivers/scmi/scmi_private.h deleted file mode 100644 index 6530573..0000000 --- a/plat/arm/css/drivers/scmi/scmi_private.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef SCMI_PRIVATE_H -#define SCMI_PRIVATE_H - -#include - -/* - * SCMI power domain management protocol message and response lengths. It is - * calculated as sum of length in bytes of the message header (4) and payload - * area (the number of bytes of parameters or return values in the payload). - */ -#define SCMI_PROTO_VERSION_MSG_LEN 4 -#define SCMI_PROTO_VERSION_RESP_LEN 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 - -#define SCMI_PWR_STATE_GET_MSG_LEN 8 -#define SCMI_PWR_STATE_GET_RESP_LEN 12 - -#define SCMI_SYS_PWR_STATE_SET_MSG_LEN 12 -#define SCMI_SYS_PWR_STATE_SET_RESP_LEN 8 - -#define SCMI_SYS_PWR_STATE_GET_MSG_LEN 4 -#define SCMI_SYS_PWR_STATE_GET_RESP_LEN 12 - -/* SCMI message header format bit field */ -#define SCMI_MSG_ID_SHIFT 0 -#define SCMI_MSG_ID_WIDTH 8 -#define SCMI_MSG_ID_MASK ((1 << SCMI_MSG_ID_WIDTH) - 1) - -#define SCMI_MSG_TYPE_SHIFT 8 -#define SCMI_MSG_TYPE_WIDTH 2 -#define SCMI_MSG_TYPE_MASK ((1 << SCMI_MSG_TYPE_WIDTH) - 1) - -#define SCMI_MSG_PROTO_ID_SHIFT 10 -#define SCMI_MSG_PROTO_ID_WIDTH 8 -#define SCMI_MSG_PROTO_ID_MASK ((1 << SCMI_MSG_PROTO_ID_WIDTH) - 1) - -#define SCMI_MSG_TOKEN_SHIFT 18 -#define SCMI_MSG_TOKEN_WIDTH 10 -#define SCMI_MSG_TOKEN_MASK ((1 << SCMI_MSG_TOKEN_WIDTH) - 1) - - -/* SCMI mailbox flags */ -#define SCMI_FLAG_RESP_POLL 0 -#define SCMI_FLAG_RESP_INT 1 - -/* SCMI power domain protocol `POWER_STATE_SET` message flags */ -#define SCMI_PWR_STATE_SET_FLAG_SYNC 0 -#define SCMI_PWR_STATE_SET_FLAG_ASYNC 1 - -/* - * Helper macro to create an SCMI message header given protocol, message id - * and token. - */ -#define SCMI_MSG_CREATE(_protocol, _msg_id, _token) \ - ((((_protocol) & SCMI_MSG_PROTO_ID_MASK) << SCMI_MSG_PROTO_ID_SHIFT) | \ - (((_msg_id) & SCMI_MSG_ID_MASK) << SCMI_MSG_ID_SHIFT) | \ - (((_token) & SCMI_MSG_TOKEN_MASK) << SCMI_MSG_TOKEN_SHIFT)) - -/* Helper macro to get the token from a SCMI message header */ -#define SCMI_MSG_GET_TOKEN(_msg) \ - (((_msg) >> SCMI_MSG_TOKEN_SHIFT) & SCMI_MSG_TOKEN_MASK) - -/* SCMI Channel Status bit fields */ -#define SCMI_CH_STATUS_RES0_MASK 0xFFFFFFFE -#define SCMI_CH_STATUS_FREE_SHIFT 0 -#define SCMI_CH_STATUS_FREE_WIDTH 1 -#define SCMI_CH_STATUS_FREE_MASK ((1 << SCMI_CH_STATUS_FREE_WIDTH) - 1) - -/* Helper macros to check and write the channel status */ -#define SCMI_IS_CHANNEL_FREE(status) \ - (!!(((status) >> SCMI_CH_STATUS_FREE_SHIFT) & SCMI_CH_STATUS_FREE_MASK)) - -#define SCMI_MARK_CHANNEL_BUSY(status) do { \ - assert(SCMI_IS_CHANNEL_FREE(status)); \ - (status) &= ~(SCMI_CH_STATUS_FREE_MASK << \ - SCMI_CH_STATUS_FREE_SHIFT); \ - } while (0) - -/* Helper macros to copy arguments to the mailbox payload */ -#define SCMI_PAYLOAD_ARG1(payld_arr, arg1) \ - mmio_write_32((uintptr_t)&payld_arr[0], arg1) - -#define SCMI_PAYLOAD_ARG2(payld_arr, arg1, arg2) do { \ - SCMI_PAYLOAD_ARG1(payld_arr, arg1); \ - mmio_write_32((uintptr_t)&payld_arr[1], arg2); \ - } while (0) - -#define SCMI_PAYLOAD_ARG3(payld_arr, arg1, arg2, arg3) do { \ - SCMI_PAYLOAD_ARG2(payld_arr, arg1, arg2); \ - mmio_write_32((uintptr_t)&payld_arr[2], arg3); \ - } while (0) - -/* Helper macros to read return values from the mailbox payload */ -#define SCMI_PAYLOAD_RET_VAL1(payld_arr, val1) \ - (val1) = mmio_read_32((uintptr_t)&payld_arr[0]) - -#define SCMI_PAYLOAD_RET_VAL2(payld_arr, val1, val2) do { \ - SCMI_PAYLOAD_RET_VAL1(payld_arr, val1); \ - (val2) = mmio_read_32((uintptr_t)&payld_arr[1]); \ - } while (0) - -#define SCMI_PAYLOAD_RET_VAL3(payld_arr, val1, val2, val3) do { \ - SCMI_PAYLOAD_RET_VAL2(payld_arr, val1, val2); \ - (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. - */ -typedef struct mailbox_mem { - uint32_t res_a; /* Reserved */ - volatile uint32_t status; - uint64_t res_b; /* Reserved */ - uint32_t flags; - volatile uint32_t len; - uint32_t msg_header; - uint32_t payload[]; -} mailbox_mem_t; - - -/* Private APIs for use within SCMI driver */ -void scmi_get_channel(scmi_channel_t *ch); -void scmi_send_sync_command(scmi_channel_t *ch); -void scmi_put_channel(scmi_channel_t *ch); - -static inline void validate_scmi_channel(scmi_channel_t *ch) -{ - assert(ch && ch->is_initialized); - assert(ch->info && ch->info->scmi_mbx_mem); -} - -#endif /* SCMI_PRIVATE_H */ diff --git a/plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c b/plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c deleted file mode 100644 index f315621..0000000 --- a/plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include - -#include "scmi.h" -#include "scmi_private.h" - -/* - * API to set the SCMI power domain power state. - */ -int scmi_pwr_state_set(void *p, uint32_t domain_id, - uint32_t scmi_pwr_state) -{ - mailbox_mem_t *mbx_mem; - int token = 0, ret; - - /* - * Only asynchronous mode of `set power state` command is allowed on - * application processors. - */ - uint32_t pwr_state_set_msg_flag = SCMI_PWR_STATE_SET_FLAG_ASYNC; - 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_PWR_DMN_PROTO_ID, - SCMI_PWR_STATE_SET_MSG, token); - mbx_mem->len = SCMI_PWR_STATE_SET_MSG_LEN; - mbx_mem->flags = SCMI_FLAG_RESP_POLL; - SCMI_PAYLOAD_ARG3(mbx_mem->payload, pwr_state_set_msg_flag, - domain_id, scmi_pwr_state); - - scmi_send_sync_command(ch); - - /* Get the return values */ - SCMI_PAYLOAD_RET_VAL1(mbx_mem->payload, ret); - assert(mbx_mem->len == SCMI_PWR_STATE_SET_RESP_LEN); - assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header)); - - scmi_put_channel(ch); - - return ret; -} - -/* - * API to get the SCMI power domain power state. - */ -int scmi_pwr_state_get(void *p, uint32_t domain_id, - uint32_t *scmi_pwr_state) -{ - 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_PWR_DMN_PROTO_ID, - SCMI_PWR_STATE_GET_MSG, token); - mbx_mem->len = SCMI_PWR_STATE_GET_MSG_LEN; - mbx_mem->flags = SCMI_FLAG_RESP_POLL; - SCMI_PAYLOAD_ARG1(mbx_mem->payload, domain_id); - - scmi_send_sync_command(ch); - - /* Get the return values */ - SCMI_PAYLOAD_RET_VAL2(mbx_mem->payload, ret, *scmi_pwr_state); - assert(mbx_mem->len == SCMI_PWR_STATE_GET_RESP_LEN); - assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header)); - - scmi_put_channel(ch); - - return ret; -} diff --git a/plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c b/plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c deleted file mode 100644 index 03c3c06..0000000 --- a/plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include - -#include "scmi.h" -#include "scmi_private.h" - -/* - * API to set the SCMI system power state - */ -int scmi_sys_pwr_state_set(void *p, uint32_t flags, uint32_t system_state) -{ - 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_SYS_PWR_PROTO_ID, - SCMI_SYS_PWR_STATE_SET_MSG, token); - mbx_mem->len = SCMI_SYS_PWR_STATE_SET_MSG_LEN; - mbx_mem->flags = SCMI_FLAG_RESP_POLL; - SCMI_PAYLOAD_ARG2(mbx_mem->payload, flags, system_state); - - scmi_send_sync_command(ch); - - /* Get the return values */ - SCMI_PAYLOAD_RET_VAL1(mbx_mem->payload, ret); - assert(mbx_mem->len == SCMI_SYS_PWR_STATE_SET_RESP_LEN); - assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header)); - - scmi_put_channel(ch); - - return ret; -} - -/* - * API to get the SCMI system power state - */ -int scmi_sys_pwr_state_get(void *p, uint32_t *system_state) -{ - 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_SYS_PWR_PROTO_ID, - SCMI_SYS_PWR_STATE_GET_MSG, token); - mbx_mem->len = SCMI_SYS_PWR_STATE_GET_MSG_LEN; - mbx_mem->flags = SCMI_FLAG_RESP_POLL; - - scmi_send_sync_command(ch); - - /* Get the return values */ - SCMI_PAYLOAD_RET_VAL2(mbx_mem->payload, ret, *system_state); - assert(mbx_mem->len == SCMI_SYS_PWR_STATE_GET_RESP_LEN); - assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header)); - - scmi_put_channel(ch); - - return ret; -} diff --git a/plat/arm/css/drivers/scp/css_bom_bootloader.c b/plat/arm/css/drivers/scp/css_bom_bootloader.c deleted file mode 100644 index ca40c30..0000000 --- a/plat/arm/css/drivers/scp/css_bom_bootloader.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include -#include -#include -#include - -#include "../mhu/css_mhu.h" -#include "../scpi/css_scpi.h" -#include "css_scp.h" - -/* ID of the MHU slot used for the BOM protocol */ -#define BOM_MHU_SLOT_ID 0 - -/* Boot commands sent from AP -> SCP */ -#define BOOT_CMD_INFO 0x00 -#define BOOT_CMD_DATA 0x01 - -/* BOM command header */ -typedef struct { - uint32_t id : 8; - uint32_t reserved : 24; -} bom_cmd_t; - -typedef struct { - uint32_t image_size; - uint32_t checksum; -} cmd_info_payload_t; - -/* - * Unlike the SCPI protocol, the boot protocol uses the same memory region - * for both AP -> SCP and SCP -> AP transfers; define the address of this... - */ -#define BOM_SHARED_MEM PLAT_CSS_SCP_COM_SHARED_MEM_BASE -#define BOM_CMD_HEADER ((bom_cmd_t *) BOM_SHARED_MEM) -#define BOM_CMD_PAYLOAD ((void *) (BOM_SHARED_MEM + sizeof(bom_cmd_t))) - -typedef struct { - /* Offset from the base address of the Trusted RAM */ - uint32_t offset; - uint32_t block_size; -} cmd_data_payload_t; - -/* - * All CSS platforms load SCP_BL2/SCP_BL2U just below BL2 (this is where BL31 - * usually resides except when ARM_BL31_IN_DRAM is - * set). Ensure that SCP_BL2/SCP_BL2U do not overflow into shared RAM and - * the tb_fw_config. - */ -CASSERT(SCP_BL2_LIMIT <= BL2_BASE, assert_scp_bl2_overwrite_bl2); -CASSERT(SCP_BL2U_LIMIT <= BL2_BASE, assert_scp_bl2u_overwrite_bl2); - -CASSERT(SCP_BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2_overflow); -CASSERT(SCP_BL2U_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2u_overflow); - -static void scp_boot_message_start(void) -{ - mhu_secure_message_start(BOM_MHU_SLOT_ID); -} - -static void scp_boot_message_send(size_t payload_size) -{ - /* Ensure that any write to the BOM payload area is seen by SCP before - * we write to the MHU register. If these 2 writes were reordered by - * the CPU then SCP would read stale payload data */ - dmbst(); - - /* Send command to SCP */ - mhu_secure_message_send(BOM_MHU_SLOT_ID); -} - -static uint32_t scp_boot_message_wait(size_t size) -{ - uint32_t mhu_status; - - mhu_status = mhu_secure_message_wait(); - - /* Expect an SCP Boot Protocol message, reject any other protocol */ - if (mhu_status != (1 << BOM_MHU_SLOT_ID)) { - ERROR("MHU: Unexpected protocol (MHU status: 0x%x)\n", - mhu_status); - panic(); - } - - /* Ensure that any read to the BOM payload area is done after reading - * the MHU register. If these 2 reads were reordered then the CPU would - * read invalid payload data */ - dmbld(); - - return *(uint32_t *) BOM_SHARED_MEM; -} - -static void scp_boot_message_end(void) -{ - mhu_secure_message_end(BOM_MHU_SLOT_ID); -} - -int css_scp_boot_image_xfer(void *image, unsigned int image_size) -{ - uint32_t response; - uint32_t checksum; - cmd_info_payload_t *cmd_info_payload; - cmd_data_payload_t *cmd_data_payload; - - assert((uintptr_t) image == SCP_BL2_BASE); - - if ((image_size == 0) || (image_size % 4 != 0)) { - ERROR("Invalid size for the SCP_BL2 image. Must be a multiple of " - "4 bytes and not zero (current size = 0x%x)\n", - image_size); - return -1; - } - - /* Extract the checksum from the image */ - checksum = *(uint32_t *) image; - image = (char *) image + sizeof(checksum); - image_size -= sizeof(checksum); - - mhu_secure_init(); - - VERBOSE("Send info about the SCP_BL2 image to be transferred to SCP\n"); - - /* - * Send information about the SCP firmware image about to be transferred - * to SCP - */ - scp_boot_message_start(); - - BOM_CMD_HEADER->id = BOOT_CMD_INFO; - cmd_info_payload = BOM_CMD_PAYLOAD; - cmd_info_payload->image_size = image_size; - cmd_info_payload->checksum = checksum; - - scp_boot_message_send(sizeof(*cmd_info_payload)); -#if CSS_DETECT_PRE_1_7_0_SCP - { - const uint32_t deprecated_scp_nack_cmd = 0x404; - uint32_t mhu_status; - - VERBOSE("Detecting SCP version incompatibility\n"); - - mhu_status = mhu_secure_message_wait(); - if (mhu_status == deprecated_scp_nack_cmd) { - ERROR("Detected an incompatible version of the SCP firmware.\n"); - ERROR("Only versions from v1.7.0 onwards are supported.\n"); - ERROR("Please update the SCP firmware.\n"); - return -1; - } - - VERBOSE("SCP version looks OK\n"); - } -#endif /* CSS_DETECT_PRE_1_7_0_SCP */ - response = scp_boot_message_wait(sizeof(response)); - scp_boot_message_end(); - - if (response != 0) { - ERROR("SCP BOOT_CMD_INFO returned error %u\n", response); - return -1; - } - - VERBOSE("Transferring SCP_BL2 image to SCP\n"); - - /* Transfer SCP_BL2 image to SCP */ - scp_boot_message_start(); - - BOM_CMD_HEADER->id = BOOT_CMD_DATA; - cmd_data_payload = BOM_CMD_PAYLOAD; - cmd_data_payload->offset = (uintptr_t) image - ARM_TRUSTED_SRAM_BASE; - cmd_data_payload->block_size = image_size; - - scp_boot_message_send(sizeof(*cmd_data_payload)); - response = scp_boot_message_wait(sizeof(response)); - scp_boot_message_end(); - - if (response != 0) { - ERROR("SCP BOOT_CMD_DATA returned error %u\n", response); - return -1; - } - - return 0; -} - -int css_scp_boot_ready(void) -{ - VERBOSE("Waiting for SCP to signal it is ready to go on\n"); - - /* Wait for SCP to signal it's ready */ - return scpi_wait_ready(); -} diff --git a/plat/arm/css/drivers/scp/css_pm_scmi.c b/plat/arm/css/drivers/scp/css_pm_scmi.c deleted file mode 100644 index fa4dd8a..0000000 --- a/plat/arm/css/drivers/scp/css_pm_scmi.c +++ /dev/null @@ -1,423 +0,0 @@ -/* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include "../scmi/scmi.h" -#include "css_scp.h" - -/* - * This file implements the SCP helper functions using SCMI protocol. - */ - -/* - * SCMI power state parameter bit field encoding for ARM CSS platforms. - * - * 31 20 19 16 15 12 11 8 7 4 3 0 - * +-------------------------------------------------------------+ - * | SBZ | Max level | Level 3 | Level 2 | Level 1 | Level 0 | - * | | | state | state | state | state | - * +-------------------------------------------------------------+ - * - * `Max level` encodes the highest level that has a valid power state - * encoded in the power state. - */ -#define SCMI_PWR_STATE_MAX_PWR_LVL_SHIFT 16 -#define SCMI_PWR_STATE_MAX_PWR_LVL_WIDTH 4 -#define SCMI_PWR_STATE_MAX_PWR_LVL_MASK \ - ((1 << SCMI_PWR_STATE_MAX_PWR_LVL_WIDTH) - 1) -#define SCMI_SET_PWR_STATE_MAX_PWR_LVL(_power_state, _max_level) \ - (_power_state) |= ((_max_level) & SCMI_PWR_STATE_MAX_PWR_LVL_MASK)\ - << SCMI_PWR_STATE_MAX_PWR_LVL_SHIFT -#define SCMI_GET_PWR_STATE_MAX_PWR_LVL(_power_state) \ - (((_power_state) >> SCMI_PWR_STATE_MAX_PWR_LVL_SHIFT) \ - & SCMI_PWR_STATE_MAX_PWR_LVL_MASK) - -#define SCMI_PWR_STATE_LVL_WIDTH 4 -#define SCMI_PWR_STATE_LVL_MASK \ - ((1 << SCMI_PWR_STATE_LVL_WIDTH) - 1) -#define SCMI_SET_PWR_STATE_LVL(_power_state, _level, _level_state) \ - (_power_state) |= ((_level_state) & SCMI_PWR_STATE_LVL_MASK) \ - << (SCMI_PWR_STATE_LVL_WIDTH * (_level)) -#define SCMI_GET_PWR_STATE_LVL(_power_state, _level) \ - (((_power_state) >> (SCMI_PWR_STATE_LVL_WIDTH * (_level))) & \ - SCMI_PWR_STATE_LVL_MASK) - -/* - * The SCMI power state enumeration for a power domain level - */ -typedef enum { - scmi_power_state_off = 0, - scmi_power_state_on = 1, - scmi_power_state_sleep = 2, -} scmi_power_state_t; - -/* - * The global handle for invoking the SCMI driver APIs after the driver - * has been initialized. - */ -static void *scmi_handle; - -/* The SCMI channel global object */ -static scmi_channel_t channel; - -ARM_SCMI_INSTANTIATE_LOCK; - -/* - * Helper function to suspend a CPU power domain and its parent power domains - * if applicable. - */ -void css_scp_suspend(const struct psci_power_state *target_state) -{ - int ret; - - /* At least power domain level 0 should be specified to be suspended */ - assert(target_state->pwr_domain_state[ARM_PWR_LVL0] == - ARM_LOCAL_STATE_OFF); - - /* Check if power down at system power domain level is requested */ - if (css_system_pwr_state(target_state) == ARM_LOCAL_STATE_OFF) { - /* Issue SCMI command for SYSTEM_SUSPEND */ - ret = scmi_sys_pwr_state_set(scmi_handle, - SCMI_SYS_PWR_FORCEFUL_REQ, - SCMI_SYS_PWR_SUSPEND); - if (ret != SCMI_E_SUCCESS) { - ERROR("SCMI system power domain suspend return 0x%x unexpected\n", - ret); - panic(); - } - return; - } -#if !HW_ASSISTED_COHERENCY - int lvl; - uint32_t scmi_pwr_state = 0; - /* - * If we reach here, then assert that power down at system power domain - * level is running. - */ - assert(css_system_pwr_state(target_state) == ARM_LOCAL_STATE_RUN); - - /* For level 0, specify `scmi_power_state_sleep` as the power state */ - SCMI_SET_PWR_STATE_LVL(scmi_pwr_state, ARM_PWR_LVL0, - scmi_power_state_sleep); - - for (lvl = ARM_PWR_LVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) { - if (target_state->pwr_domain_state[lvl] == ARM_LOCAL_STATE_RUN) - break; - - assert(target_state->pwr_domain_state[lvl] == - ARM_LOCAL_STATE_OFF); - /* - * Specify `scmi_power_state_off` as power state for higher - * levels. - */ - SCMI_SET_PWR_STATE_LVL(scmi_pwr_state, lvl, - scmi_power_state_off); - } - - SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1); - - ret = scmi_pwr_state_set(scmi_handle, - plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()], - scmi_pwr_state); - - if (ret != SCMI_E_SUCCESS) { - ERROR("SCMI set power state command return 0x%x unexpected\n", - ret); - panic(); - } -#endif -} - -/* - * Helper function to turn off a CPU power domain and its parent power domains - * if applicable. - */ -void css_scp_off(const struct psci_power_state *target_state) -{ - int lvl = 0, ret; - uint32_t scmi_pwr_state = 0; - - /* At-least the CPU level should be specified to be OFF */ - assert(target_state->pwr_domain_state[ARM_PWR_LVL0] == - ARM_LOCAL_STATE_OFF); - - /* PSCI CPU OFF cannot be used to turn OFF system power domain */ - assert(css_system_pwr_state(target_state) == ARM_LOCAL_STATE_RUN); - - for (; lvl <= PLAT_MAX_PWR_LVL; lvl++) { - if (target_state->pwr_domain_state[lvl] == ARM_LOCAL_STATE_RUN) - break; - - assert(target_state->pwr_domain_state[lvl] == - ARM_LOCAL_STATE_OFF); - SCMI_SET_PWR_STATE_LVL(scmi_pwr_state, lvl, - scmi_power_state_off); - } - - SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1); - - ret = scmi_pwr_state_set(scmi_handle, - plat_css_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()], - scmi_pwr_state); - - if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) { - ERROR("SCMI set power state command return 0x%x unexpected\n", - ret); - panic(); - } -} - -/* - * Helper function to turn ON a CPU power domain and its parent power domains - * if applicable. - */ -void css_scp_on(u_register_t mpidr) -{ - int lvl = 0, ret, core_pos; - uint32_t scmi_pwr_state = 0; - - for (; lvl <= PLAT_MAX_PWR_LVL; lvl++) - SCMI_SET_PWR_STATE_LVL(scmi_pwr_state, lvl, - scmi_power_state_on); - - SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1); - - core_pos = plat_core_pos_by_mpidr(mpidr); - assert(core_pos >= 0 && core_pos < PLATFORM_CORE_COUNT); - - ret = scmi_pwr_state_set(scmi_handle, - plat_css_core_pos_to_scmi_dmn_id_map[core_pos], - scmi_pwr_state); - - if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) { - ERROR("SCMI set power state command return 0x%x unexpected\n", - ret); - panic(); - } -} - -/* - * Helper function to get the power state of a power domain node as reported - * by the SCP. - */ -int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level) -{ - int ret, cpu_idx; - uint32_t scmi_pwr_state = 0, lvl_state; - - /* We don't support get power state at the system power domain level */ - if ((power_level > PLAT_MAX_PWR_LVL) || - (power_level == CSS_SYSTEM_PWR_DMN_LVL)) { - WARN("Invalid power level %u specified for SCMI get power state\n", - power_level); - return PSCI_E_INVALID_PARAMS; - } - - cpu_idx = plat_core_pos_by_mpidr(mpidr); - assert(cpu_idx > -1); - - ret = scmi_pwr_state_get(scmi_handle, - plat_css_core_pos_to_scmi_dmn_id_map[cpu_idx], - &scmi_pwr_state); - - if (ret != SCMI_E_SUCCESS) { - WARN("SCMI get power state command return 0x%x unexpected\n", - ret); - return PSCI_E_INVALID_PARAMS; - } - - /* - * Find the maximum power level described in the get power state - * command. If it is less than the requested power level, then assume - * the requested power level is ON. - */ - if (SCMI_GET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state) < power_level) - return HW_ON; - - lvl_state = SCMI_GET_PWR_STATE_LVL(scmi_pwr_state, power_level); - if (lvl_state == scmi_power_state_on) - return HW_ON; - - assert((lvl_state == scmi_power_state_off) || - (lvl_state == scmi_power_state_sleep)); - return HW_OFF; -} - -void __dead2 css_scp_system_off(int state) -{ - int ret; - - /* - * Disable GIC CPU interface to prevent pending interrupt from waking - * up the AP from WFI. - */ - plat_arm_gic_cpuif_disable(); - - /* - * Issue SCMI command. First issue a graceful - * request and if that fails force the request. - */ - ret = scmi_sys_pwr_state_set(scmi_handle, - SCMI_SYS_PWR_FORCEFUL_REQ, - state); - - if (ret != SCMI_E_SUCCESS) { - ERROR("SCMI system power state set 0x%x returns unexpected 0x%x\n", - state, ret); - panic(); - } - wfi(); - ERROR("CSS set power state: operation not handled.\n"); - panic(); -} - -/* - * Helper function to shutdown the system via SCMI. - */ -void __dead2 css_scp_sys_shutdown(void) -{ - css_scp_system_off(SCMI_SYS_PWR_SHUTDOWN); -} - -/* - * Helper function to reset the system via SCMI. - */ -void __dead2 css_scp_sys_reboot(void) -{ - css_scp_system_off(SCMI_SYS_PWR_COLD_RESET); -} - -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 __init plat_arm_pwrc_setup(void) -{ - channel.info = plat_css_get_scmi_info(); - channel.lock = ARM_SCMI_LOCK_GET_INSTANCE; - scmi_handle = scmi_init(&channel); - if (scmi_handle == NULL) { - ERROR("SCMI Initialization failed\n"); - panic(); - } - if (scmi_ap_core_init(&channel) < 0) { - ERROR("SCMI AP core protocol initialization failed\n"); - panic(); - } -} - -/****************************************************************************** - * This function overrides the default definition for ARM platforms. Initialize - * the SCMI driver, query capability via SCMI and modify the PSCI capability - * based on that. - *****************************************************************************/ -const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops) -{ - uint32_t msg_attr; - int ret; - - assert(scmi_handle); - - /* Check that power domain POWER_STATE_SET message is supported */ - ret = scmi_proto_msg_attr(scmi_handle, SCMI_PWR_DMN_PROTO_ID, - SCMI_PWR_STATE_SET_MSG, &msg_attr); - if (ret != SCMI_E_SUCCESS) { - ERROR("Set power state command is not supported by SCMI\n"); - panic(); - } - - /* - * Don't support PSCI NODE_HW_STATE call if SCMI doesn't support - * POWER_STATE_GET message. - */ - ret = scmi_proto_msg_attr(scmi_handle, SCMI_PWR_DMN_PROTO_ID, - SCMI_PWR_STATE_GET_MSG, &msg_attr); - if (ret != SCMI_E_SUCCESS) - ops->get_node_hw_state = NULL; - - /* Check if the SCMI SYSTEM_POWER_STATE_SET message is supported */ - ret = scmi_proto_msg_attr(scmi_handle, SCMI_SYS_PWR_PROTO_ID, - SCMI_SYS_PWR_STATE_SET_MSG, &msg_attr); - if (ret != SCMI_E_SUCCESS) { - /* System power management operations are not supported */ - ops->system_off = NULL; - ops->system_reset = NULL; - ops->get_sys_suspend_power_state = NULL; - } else { - if (!(msg_attr & SCMI_SYS_PWR_SUSPEND_SUPPORTED)) { - /* - * System power management protocol is available, but - * it does not support SYSTEM SUSPEND. - */ - ops->get_sys_suspend_power_state = NULL; - } - if (!(msg_attr & SCMI_SYS_PWR_WARM_RESET_SUPPORTED)) { - /* - * WARM reset is not available. - */ - ops->system_reset2 = NULL; - } - } - - return ops; -} - -int css_system_reset2(int is_vendor, int reset_type, u_register_t cookie) -{ - if (is_vendor || (reset_type != PSCI_RESET2_SYSTEM_WARM_RESET)) - return PSCI_E_INVALID_PARAMS; - - css_scp_system_off(SCMI_SYS_PWR_WARM_RESET); - /* - * css_scp_system_off cannot return (it is a __dead function), - * but css_system_reset2 has to return some value, even in - * this case. - */ - 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 diff --git a/plat/arm/css/drivers/scp/css_pm_scpi.c b/plat/arm/css/drivers/scp/css_pm_scpi.c deleted file mode 100644 index f53ac30..0000000 --- a/plat/arm/css/drivers/scp/css_pm_scpi.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include - -#include -#include - -#include "../scpi/css_scpi.h" -#include "css_scp.h" - -/* - * This file implements the SCP power management functions using SCPI protocol. - */ - -/* - * Helper function to inform power down state to SCP. - */ -void css_scp_suspend(const struct psci_power_state *target_state) -{ - uint32_t cluster_state = scpi_power_on; - uint32_t system_state = scpi_power_on; - - /* Check if power down at system power domain level is requested */ - if (css_system_pwr_state(target_state) == ARM_LOCAL_STATE_OFF) - system_state = scpi_power_retention; - - /* Cluster is to be turned off, so disable coherency */ - if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) - cluster_state = scpi_power_off; - - /* - * Ask the SCP to power down the appropriate components depending upon - * their state. - */ - scpi_set_css_power_state(read_mpidr_el1(), - scpi_power_off, - cluster_state, - system_state); -} - -/* - * Helper function to turn off a CPU power domain and its parent power domains - * if applicable. Since SCPI doesn't differentiate between OFF and suspend, we - * call the suspend helper here. - */ -void css_scp_off(const struct psci_power_state *target_state) -{ - css_scp_suspend(target_state); -} - -/* - * Helper function to turn ON a CPU power domain and its parent power domains - * if applicable. - */ -void css_scp_on(u_register_t mpidr) -{ - /* - * SCP takes care of powering up parent power domains so we - * only need to care about level 0 - */ - scpi_set_css_power_state(mpidr, scpi_power_on, scpi_power_on, - scpi_power_on); -} - -/* - * Helper function to get the power state of a power domain node as reported - * by the SCP. - */ -int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level) -{ - int rc, element; - unsigned int cpu_state, cluster_state; - - /* - * The format of 'power_level' is implementation-defined, but 0 must - * mean a CPU. We also allow 1 to denote the cluster - */ - if (power_level != ARM_PWR_LVL0 && power_level != ARM_PWR_LVL1) - return PSCI_E_INVALID_PARAMS; - - /* Query SCP */ - rc = scpi_get_css_power_state(mpidr, &cpu_state, &cluster_state); - if (rc != 0) - return PSCI_E_INVALID_PARAMS; - - /* Map power states of CPU and cluster to expected PSCI return codes */ - if (power_level == ARM_PWR_LVL0) { - /* - * The CPU state returned by SCP is an 8-bit bit mask - * corresponding to each CPU in the cluster - */ -#if ARM_PLAT_MT - /* - * The current SCPI driver only caters for single-threaded - * platforms. Hence we ignore the thread ID (which is always 0) - * for such platforms. - */ - element = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; -#else - element = mpidr & MPIDR_AFFLVL_MASK; -#endif /* ARM_PLAT_MT */ - return CSS_CPU_PWR_STATE(cpu_state, element) == - CSS_CPU_PWR_STATE_ON ? HW_ON : HW_OFF; - } else { - assert(cluster_state == CSS_CLUSTER_PWR_STATE_ON || - cluster_state == CSS_CLUSTER_PWR_STATE_OFF); - return cluster_state == CSS_CLUSTER_PWR_STATE_ON ? HW_ON : - HW_OFF; - } -} - -/* - * Helper function to shutdown the system via SCPI. - */ -void __dead2 css_scp_sys_shutdown(void) -{ - uint32_t response; - - /* - * Disable GIC CPU interface to prevent pending interrupt - * from waking up the AP from WFI. - */ - plat_arm_gic_cpuif_disable(); - - /* Send the power down request to the SCP */ - response = scpi_sys_power_state(scpi_system_shutdown); - - if (response != SCP_OK) { - ERROR("CSS System Off: SCP error %u.\n", response); - panic(); - } - wfi(); - ERROR("CSS System Off: operation not handled.\n"); - panic(); -} - -/* - * Helper function to reset the system via SCPI. - */ -void __dead2 css_scp_sys_reboot(void) -{ - uint32_t response; - - /* - * Disable GIC CPU interface to prevent pending interrupt - * from waking up the AP from WFI. - */ - plat_arm_gic_cpuif_disable(); - - /* Send the system reset request to the SCP */ - response = scpi_sys_power_state(scpi_system_reboot); - - if (response != SCP_OK) { - ERROR("CSS System Reset: SCP error %u.\n", response); - panic(); - } - wfi(); - ERROR("CSS System Reset: operation not handled.\n"); - panic(); -} diff --git a/plat/arm/css/drivers/scp/css_scp.h b/plat/arm/css/drivers/scp/css_scp.h deleted file mode 100644 index f3c08c5..0000000 --- a/plat/arm/css/drivers/scp/css_scp.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef CSS_SCP_H -#define CSS_SCP_H - -#include - -#include - -#include - -/* Forward declarations */ -struct psci_power_state; - -/* API for power management by SCP */ -int css_system_reset2(int is_vendor, int reset_type, u_register_t cookie); -void css_scp_suspend(const struct psci_power_state *target_state); -void css_scp_off(const struct psci_power_state *target_state); -void css_scp_on(u_register_t mpidr); -int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level); -void __dead2 css_scp_sys_shutdown(void); -void __dead2 css_scp_sys_reboot(void); -void __dead2 css_scp_system_off(int state); - -/* API for SCP Boot Image transfer. Return 0 on success, -1 on error */ -int css_scp_boot_image_xfer(void *image, unsigned int image_size); - -/* - * API to wait for SCP to signal till it's ready after booting the transferred - * image. - */ -int css_scp_boot_ready(void); - -#if CSS_LOAD_SCP_IMAGES - -/* - * All CSS platforms load SCP_BL2/SCP_BL2U just below BL2 (this is where BL31 - * usually resides except when ARM_BL31_IN_DRAM is - * set). Ensure that SCP_BL2/SCP_BL2U do not overflow into tb_fw_config. - */ -CASSERT(SCP_BL2_LIMIT <= BL2_BASE, assert_scp_bl2_overwrite_bl2); -CASSERT(SCP_BL2U_LIMIT <= BL2_BASE, assert_scp_bl2u_overwrite_bl2); - -CASSERT(SCP_BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2_overflow); -CASSERT(SCP_BL2U_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_scp_bl2u_overflow); -#endif - -#endif /* CSS_SCP_H */ diff --git a/plat/arm/css/drivers/scp/css_sds.c b/plat/arm/css/drivers/scp/css_sds.c deleted file mode 100644 index e3f6102..0000000 --- a/plat/arm/css/drivers/scp/css_sds.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include -#include -#include -#include -#include - -#include "css_scp.h" -#include "../sds/sds.h" - -int css_scp_boot_image_xfer(void *image, unsigned int image_size) -{ - int ret; - unsigned int image_offset, image_flags; - - ret = sds_init(); - if (ret != SDS_OK) { - ERROR("SCP SDS initialization failed\n"); - panic(); - } - - VERBOSE("Writing SCP image metadata\n"); - image_offset = (uintptr_t) image - ARM_TRUSTED_SRAM_BASE; - ret = sds_struct_write(SDS_SCP_IMG_STRUCT_ID, SDS_SCP_IMG_ADDR_OFFSET, - &image_offset, SDS_SCP_IMG_ADDR_SIZE, - SDS_ACCESS_MODE_NON_CACHED); - if (ret != SDS_OK) - goto sds_fail; - - ret = sds_struct_write(SDS_SCP_IMG_STRUCT_ID, SDS_SCP_IMG_SIZE_OFFSET, - &image_size, SDS_SCP_IMG_SIZE_SIZE, - SDS_ACCESS_MODE_NON_CACHED); - if (ret != SDS_OK) - goto sds_fail; - - VERBOSE("Marking SCP image metadata as valid\n"); - image_flags = SDS_SCP_IMG_VALID_FLAG_BIT; - ret = sds_struct_write(SDS_SCP_IMG_STRUCT_ID, SDS_SCP_IMG_FLAG_OFFSET, - &image_flags, SDS_SCP_IMG_FLAG_SIZE, - SDS_ACCESS_MODE_NON_CACHED); - if (ret != SDS_OK) - goto sds_fail; - - return 0; -sds_fail: - ERROR("SCP SDS write to SCP IMG struct failed\n"); - panic(); -} - -/* - * API to wait for SCP to signal till it's ready after booting the transferred - * image. - */ -int css_scp_boot_ready(void) -{ - uint32_t scp_feature_availability_flags; - int ret, retry = CSS_SCP_READY_10US_RETRIES; - - - VERBOSE("Waiting for SCP RAM to complete its initialization process\n"); - - /* Wait for the SCP RAM Firmware to complete its initialization process */ - while (retry > 0) { - ret = sds_struct_read(SDS_FEATURE_AVAIL_STRUCT_ID, 0, - &scp_feature_availability_flags, - SDS_FEATURE_AVAIL_SIZE, - SDS_ACCESS_MODE_NON_CACHED); - if (ret == SDS_ERR_STRUCT_NOT_FINALIZED) - continue; - - if (ret != SDS_OK) { - ERROR(" sds_struct_read failed\n"); - panic(); - } - - if (scp_feature_availability_flags & - SDS_FEATURE_AVAIL_SCP_RAM_READY_BIT) - return 0; - - udelay(10); - retry--; - } - - ERROR("Timeout of %d ms expired waiting for SCP RAM Ready flag\n", - CSS_SCP_READY_10US_RETRIES/100); - - plat_panic_handler(); -} diff --git a/plat/arm/css/drivers/scpi/css_scpi.c b/plat/arm/css/drivers/scpi/css_scpi.c deleted file mode 100644 index d64bfa2..0000000 --- a/plat/arm/css/drivers/scpi/css_scpi.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include -#include -#include -#include -#include - -#include "../mhu/css_mhu.h" -#include "css_scpi.h" - -#define SCPI_SHARED_MEM_SCP_TO_AP PLAT_CSS_SCP_COM_SHARED_MEM_BASE -#define SCPI_SHARED_MEM_AP_TO_SCP (PLAT_CSS_SCP_COM_SHARED_MEM_BASE \ - + 0x100) - -/* Header and payload addresses for commands from AP to SCP */ -#define SCPI_CMD_HEADER_AP_TO_SCP \ - ((scpi_cmd_t *) SCPI_SHARED_MEM_AP_TO_SCP) -#define SCPI_CMD_PAYLOAD_AP_TO_SCP \ - ((void *) (SCPI_SHARED_MEM_AP_TO_SCP + sizeof(scpi_cmd_t))) - -/* Header and payload addresses for responses from SCP to AP */ -#define SCPI_RES_HEADER_SCP_TO_AP \ - ((scpi_cmd_t *) SCPI_SHARED_MEM_SCP_TO_AP) -#define SCPI_RES_PAYLOAD_SCP_TO_AP \ - ((void *) (SCPI_SHARED_MEM_SCP_TO_AP + sizeof(scpi_cmd_t))) - -/* ID of the MHU slot used for the SCPI protocol */ -#define SCPI_MHU_SLOT_ID 0 - -static void scpi_secure_message_start(void) -{ - mhu_secure_message_start(SCPI_MHU_SLOT_ID); -} - -static void scpi_secure_message_send(size_t payload_size) -{ - /* - * Ensure that any write to the SCPI payload area is seen by SCP before - * we write to the MHU register. If these 2 writes were reordered by - * the CPU then SCP would read stale payload data - */ - dmbst(); - - mhu_secure_message_send(SCPI_MHU_SLOT_ID); -} - -static void scpi_secure_message_receive(scpi_cmd_t *cmd) -{ - uint32_t mhu_status; - - assert(cmd != NULL); - - mhu_status = mhu_secure_message_wait(); - - /* Expect an SCPI message, reject any other protocol */ - if (mhu_status != (1 << SCPI_MHU_SLOT_ID)) { - ERROR("MHU: Unexpected protocol (MHU status: 0x%x)\n", - mhu_status); - panic(); - } - - /* - * Ensure that any read to the SCPI payload area is done after reading - * the MHU register. If these 2 reads were reordered then the CPU would - * read invalid payload data - */ - dmbld(); - - memcpy(cmd, (void *) SCPI_SHARED_MEM_SCP_TO_AP, sizeof(*cmd)); -} - -static void scpi_secure_message_end(void) -{ - mhu_secure_message_end(SCPI_MHU_SLOT_ID); -} - -int scpi_wait_ready(void) -{ - scpi_cmd_t scpi_cmd; - - VERBOSE("Waiting for SCP_READY command...\n"); - - /* Get a message from the SCP */ - scpi_secure_message_start(); - scpi_secure_message_receive(&scpi_cmd); - scpi_secure_message_end(); - - /* We are expecting 'SCP Ready', produce correct error if it's not */ - scpi_status_t status = SCP_OK; - if (scpi_cmd.id != SCPI_CMD_SCP_READY) { - ERROR("Unexpected SCP command: expected command #%u, got command #%u\n", - SCPI_CMD_SCP_READY, scpi_cmd.id); - status = SCP_E_SUPPORT; - } else if (scpi_cmd.size != 0) { - ERROR("SCP_READY command has incorrect size: expected 0, got %u\n", - scpi_cmd.size); - status = SCP_E_SIZE; - } - - VERBOSE("Sending response for SCP_READY command\n"); - - /* - * Send our response back to SCP. - * We are using the same SCPI header, just update the status field. - */ - scpi_cmd.status = status; - scpi_secure_message_start(); - memcpy((void *) SCPI_SHARED_MEM_AP_TO_SCP, &scpi_cmd, sizeof(scpi_cmd)); - scpi_secure_message_send(0); - scpi_secure_message_end(); - - return status == SCP_OK ? 0 : -1; -} - -void scpi_set_css_power_state(unsigned int mpidr, - scpi_power_state_t cpu_state, scpi_power_state_t cluster_state, - scpi_power_state_t css_state) -{ - scpi_cmd_t *cmd; - uint32_t state = 0; - uint32_t *payload_addr; - -#if ARM_PLAT_MT - /* - * The current SCPI driver only caters for single-threaded platforms. - * Hence we ignore the thread ID (which is always 0) for such platforms. - */ - state |= (mpidr >> MPIDR_AFF1_SHIFT) & 0x0f; /* CPU ID */ - state |= ((mpidr >> MPIDR_AFF2_SHIFT) & 0x0f) << 4; /* Cluster ID */ -#else - state |= mpidr & 0x0f; /* CPU ID */ - state |= (mpidr & 0xf00) >> 4; /* Cluster ID */ -#endif /* ARM_PLAT_MT */ - - state |= cpu_state << 8; - state |= cluster_state << 12; - state |= css_state << 16; - - scpi_secure_message_start(); - - /* Populate the command header */ - cmd = SCPI_CMD_HEADER_AP_TO_SCP; - cmd->id = SCPI_CMD_SET_CSS_POWER_STATE; - cmd->set = SCPI_SET_NORMAL; - cmd->sender = 0; - cmd->size = sizeof(state); - /* Populate the command payload */ - payload_addr = SCPI_CMD_PAYLOAD_AP_TO_SCP; - *payload_addr = state; - scpi_secure_message_send(sizeof(state)); - /* - * SCP does not reply to this command in order to avoid MHU interrupts - * from the sender, which could interfere with its power state request. - */ - - scpi_secure_message_end(); -} - -/* - * Query and obtain CSS power state from SCP. - * - * In response to the query, SCP returns power states of all CPUs in all - * clusters of the system. The returned response is then filtered based on the - * supplied MPIDR. Power states of requested cluster and CPUs within are updated - * via. supplied non-NULL pointer arguments. - * - * Returns 0 on success, or -1 on errors. - */ -int scpi_get_css_power_state(unsigned int mpidr, unsigned int *cpu_state_p, - unsigned int *cluster_state_p) -{ - scpi_cmd_t *cmd; - scpi_cmd_t response; - int power_state, cpu, cluster, rc = -1; - - /* - * Extract CPU and cluster membership of the given MPIDR. SCPI caters - * for only up to 0xf clusters, and 8 CPUs per cluster - */ -#if ARM_PLAT_MT - /* - * The current SCPI driver only caters for single-threaded platforms. - * Hence we ignore the thread ID (which is always 0) for such platforms. - */ - cpu = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; - cluster = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK; -#else - cpu = mpidr & MPIDR_AFFLVL_MASK; - cluster = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; -#endif /* ARM_PLAT_MT */ - if (cpu >= 8 || cluster >= 0xf) - return -1; - - scpi_secure_message_start(); - - /* Populate request headers */ - zeromem(SCPI_CMD_HEADER_AP_TO_SCP, sizeof(*cmd)); - cmd = SCPI_CMD_HEADER_AP_TO_SCP; - cmd->id = SCPI_CMD_GET_CSS_POWER_STATE; - - /* - * Send message and wait for SCP's response - */ - scpi_secure_message_send(0); - scpi_secure_message_receive(&response); - - if (response.status != SCP_OK) - goto exit; - - /* Validate SCP response */ - if (!CHECK_RESPONSE(response, cluster)) - goto exit; - - /* Extract power states for required cluster */ - power_state = *(((uint16_t *) SCPI_RES_PAYLOAD_SCP_TO_AP) + cluster); - if (CLUSTER_ID(power_state) != cluster) - goto exit; - - /* Update power state via. pointers */ - if (cluster_state_p) - *cluster_state_p = CLUSTER_POWER_STATE(power_state); - if (cpu_state_p) - *cpu_state_p = CPU_POWER_STATE(power_state); - rc = 0; - -exit: - scpi_secure_message_end(); - return rc; -} - -uint32_t scpi_sys_power_state(scpi_system_state_t system_state) -{ - scpi_cmd_t *cmd; - uint8_t *payload_addr; - scpi_cmd_t response; - - scpi_secure_message_start(); - - /* Populate the command header */ - cmd = SCPI_CMD_HEADER_AP_TO_SCP; - cmd->id = SCPI_CMD_SYS_POWER_STATE; - cmd->set = 0; - cmd->sender = 0; - cmd->size = sizeof(*payload_addr); - /* Populate the command payload */ - payload_addr = SCPI_CMD_PAYLOAD_AP_TO_SCP; - *payload_addr = system_state & 0xff; - scpi_secure_message_send(sizeof(*payload_addr)); - - scpi_secure_message_receive(&response); - - scpi_secure_message_end(); - - return response.status; -} diff --git a/plat/arm/css/drivers/scpi/css_scpi.h b/plat/arm/css/drivers/scpi/css_scpi.h deleted file mode 100644 index 68fc60a..0000000 --- a/plat/arm/css/drivers/scpi/css_scpi.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef CSS_SCPI_H -#define CSS_SCPI_H - -#include -#include - -/* - * An SCPI command consists of a header and a payload. - * The following structure describes the header. It is 64-bit long. - */ -typedef struct { - /* Command ID */ - uint32_t id : 7; - /* Set ID. Identifies whether this is a standard or extended command. */ - uint32_t set : 1; - /* Sender ID to match a reply. The value is sender specific. */ - uint32_t sender : 8; - /* Size of the payload in bytes (0 - 511) */ - uint32_t size : 9; - uint32_t reserved : 7; - /* - * Status indicating the success of a command. - * See the enum below. - */ - uint32_t status; -} scpi_cmd_t; - -typedef enum { - SCPI_SET_NORMAL = 0, /* Normal SCPI commands */ - SCPI_SET_EXTENDED /* Extended SCPI commands */ -} scpi_set_t; - -enum { - SCP_OK = 0, /* Success */ - SCP_E_PARAM, /* Invalid parameter(s) */ - SCP_E_ALIGN, /* Invalid alignment */ - SCP_E_SIZE, /* Invalid size */ - SCP_E_HANDLER, /* Invalid handler or callback */ - SCP_E_ACCESS, /* Invalid access or permission denied */ - SCP_E_RANGE, /* Value out of range */ - SCP_E_TIMEOUT, /* Time out has ocurred */ - SCP_E_NOMEM, /* Invalid memory area or pointer */ - SCP_E_PWRSTATE, /* Invalid power state */ - SCP_E_SUPPORT, /* Feature not supported or disabled */ - SCPI_E_DEVICE, /* Device error */ - SCPI_E_BUSY, /* Device is busy */ -}; - -typedef uint32_t scpi_status_t; - -typedef enum { - SCPI_CMD_SCP_READY = 0x01, - SCPI_CMD_SET_CSS_POWER_STATE = 0x03, - SCPI_CMD_GET_CSS_POWER_STATE = 0x04, - SCPI_CMD_SYS_POWER_STATE = 0x05 -} scpi_command_t; - -/* - * Macros to parse SCP response to GET_CSS_POWER_STATE command - * - * [3:0] : cluster ID - * [7:4] : cluster state: 0 = on; 3 = off; rest are reserved - * [15:8]: on/off state for individual CPUs in the cluster - * - * Payload is in little-endian - */ -#define CLUSTER_ID(_resp) ((_resp) & 0xf) -#define CLUSTER_POWER_STATE(_resp) (((_resp) >> 4) & 0xf) - -/* Result is a bit mask of CPU on/off states in the cluster */ -#define CPU_POWER_STATE(_resp) (((_resp) >> 8) & 0xff) - -/* - * For GET_CSS_POWER_STATE, SCP returns the power states of every cluster. The - * size of response depends on the number of clusters in the system. The - * SCP-to-AP payload contains 2 bytes per cluster. Make sure the response is - * large enough to contain power states of a given cluster - */ -#define CHECK_RESPONSE(_resp, _clus) \ - (_resp.size >= (((_clus) + 1) * 2)) - -typedef enum { - scpi_power_on = 0, - scpi_power_retention = 1, - scpi_power_off = 3, -} scpi_power_state_t; - -typedef enum { - scpi_system_shutdown = 0, - scpi_system_reboot = 1, - scpi_system_reset = 2 -} scpi_system_state_t; - -int scpi_wait_ready(void); -void scpi_set_css_power_state(unsigned int mpidr, - scpi_power_state_t cpu_state, - scpi_power_state_t cluster_state, - scpi_power_state_t css_state); -int scpi_get_css_power_state(unsigned int mpidr, unsigned int *cpu_state_p, - unsigned int *cluster_state_p); -uint32_t scpi_sys_power_state(scpi_system_state_t system_state); - -#endif /* CSS_SCPI_H */ diff --git a/plat/arm/css/drivers/sds/aarch32/sds_helpers.S b/plat/arm/css/drivers/sds/aarch32/sds_helpers.S deleted file mode 100644 index f68cb35..0000000 --- a/plat/arm/css/drivers/sds/aarch32/sds_helpers.S +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include "../sds.h" -#include "../sds_private.h" - - .globl sds_get_primary_cpu_id - - /* - * int sds_get_primary_cpu_id(void); - * Return the primary CPU ID from SDS Structure - * Returns CPUID on success or -1 on failure - */ -func sds_get_primary_cpu_id - ldr r0, =PLAT_ARM_SDS_MEM_BASE - ldr r2, =SDS_REGION_SIGNATURE - ldr r1, [r0] - ubfx r3, r1, #0, #16 - - /* Check if the SDS region signature found */ - cmp r2, r3 - bne 2f - - /* Get the structure count from region descriptor in r1 */ - ubfx r1, r1, #SDS_REGION_STRUCT_COUNT_SHIFT, #SDS_REGION_STRUCT_COUNT_WIDTH - cmp r1, #0 - beq 2f - add r0, r0, #SDS_REGION_DESC_SIZE - - /* Initialize the loop iterator count in r3 */ - mov r3, #0 -loop_begin: - ldrh r2, [r0] - cmp r2, #SDS_AP_CPU_INFO_STRUCT_ID - bne continue_loop - - /* We have found the required structure */ - ldr r0, [r0,#(SDS_HEADER_SIZE + SDS_AP_CPU_INFO_PRIMARY_CPUID_OFFSET)] - bx lr -continue_loop: - /* Increment the loop counter and exit loop if counter == structure count */ - add r3, r3, #0x1 - cmp r1, r3 - beq 2f - - /* Read the 2nd word in header */ - ldr r2, [r0,#4] - /* Get the structure size from header */ - ubfx r2, r2, #SDS_HEADER_STRUCT_SIZE_SHIFT, #SDS_HEADER_STRUCT_SIZE_WIDTH - /* Add the structure size and SDS HEADER SIZE to point to next header */ - add r2, r2, #SDS_HEADER_SIZE - add r0, r0, r2 - b loop_begin -2: - mov r0, #0xffffffff - bx lr -endfunc sds_get_primary_cpu_id diff --git a/plat/arm/css/drivers/sds/aarch64/sds_helpers.S b/plat/arm/css/drivers/sds/aarch64/sds_helpers.S deleted file mode 100644 index 3b9c562..0000000 --- a/plat/arm/css/drivers/sds/aarch64/sds_helpers.S +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include "../sds.h" -#include "../sds_private.h" - - .globl sds_get_primary_cpu_id - - /* - * int sds_get_primary_cpu_id(void); - * Return the primary CPI ID from SDS Structure - * Returns CPUID on success or -1 on failure - */ -func sds_get_primary_cpu_id - mov_imm x0, PLAT_ARM_SDS_MEM_BASE - mov w2, #SDS_REGION_SIGNATURE - ldr w1, [x0] - - /* Check if the SDS region signature found */ - cmp w2, w1, uxth - b.ne 2f - - /* Get the structure count from region descriptor in `w1 */ - ubfx w1, w1, #SDS_REGION_STRUCT_COUNT_SHIFT, #SDS_REGION_STRUCT_COUNT_WIDTH - cbz w1, 2f - add x0, x0, #SDS_REGION_DESC_SIZE - - /* Initialize the loop iterator count in w3 */ - mov w3, #0 -loop_begin: - ldrh w2, [x0] - cmp w2, #SDS_AP_CPU_INFO_STRUCT_ID - b.ne continue_loop - - /* We have found the required structure */ - ldr w0, [x0,#(SDS_HEADER_SIZE + SDS_AP_CPU_INFO_PRIMARY_CPUID_OFFSET)] - ret -continue_loop: - /* Increment the loop counter and exit loop if counter == structure count */ - add w3, w3, #0x1 - cmp w1, w3 - b.eq 2f - - /* Read the 2nd word in header */ - ldr w2, [x0,#4] - /* Get the structure size from header */ - ubfx x2, x2, #SDS_HEADER_STRUCT_SIZE_SHIFT, #SDS_HEADER_STRUCT_SIZE_WIDTH - /* Add the structure size and SDS HEADER SIZE to point to next header */ - add x2, x2, #SDS_HEADER_SIZE - add x0, x0, x2 - b loop_begin -2: - mov w0, #0xffffffff - ret -endfunc sds_get_primary_cpu_id diff --git a/plat/arm/css/drivers/sds/sds.c b/plat/arm/css/drivers/sds/sds.c deleted file mode 100644 index eb2f48e..0000000 --- a/plat/arm/css/drivers/sds/sds.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include - -#include -#include -#include - -#include "sds.h" -#include "sds_private.h" - -/* - * Variables used to track and maintain the state of the memory region reserved - * for usage by the SDS framework. - */ - -/* Pointer to the base of the SDS memory region */ -static uintptr_t sds_mem_base; - -/* Size of the SDS memory region in bytes */ -static size_t sds_mem_size; - -/* - * Perform some non-exhaustive tests to determine whether any of the fields - * within a Structure Header contain obviously invalid data. - * Returns SDS_OK on success, SDS_ERR_FAIL on error. - */ -static int sds_struct_is_valid(uintptr_t header) -{ - size_t struct_size = GET_SDS_HEADER_STRUCT_SIZE(header); - - /* Zero is not a valid identifier */ - if (GET_SDS_HEADER_ID(header) == 0) - return SDS_ERR_FAIL; - - /* Check SDS Schema version */ - if (GET_SDS_HEADER_VERSION(header) == SDS_REGION_SCH_VERSION) - return SDS_ERR_FAIL; - - /* The SDS Structure sizes have to be multiple of 8 */ - if ((struct_size == 0) || ((struct_size % 8) != 0)) - return SDS_ERR_FAIL; - - if (struct_size > sds_mem_size) - return SDS_ERR_FAIL; - - return SDS_OK; -} - -/* - * Validate the SDS structure headers. - * Returns SDS_OK on success, SDS_ERR_FAIL on error. - */ -static int validate_sds_struct_headers(void) -{ - unsigned int i, structure_count; - uintptr_t header; - - structure_count = GET_SDS_REGION_STRUCTURE_COUNT(sds_mem_base); - - if (structure_count == 0) - return SDS_ERR_FAIL; - - header = sds_mem_base + SDS_REGION_DESC_SIZE; - - /* Iterate over structure headers and validate each one */ - for (i = 0; i < structure_count; i++) { - if (sds_struct_is_valid(header) != SDS_OK) { - WARN("SDS: Invalid structure header detected\n"); - return SDS_ERR_FAIL; - } - header += GET_SDS_HEADER_STRUCT_SIZE(header) + SDS_HEADER_SIZE; - } - return SDS_OK; -} - -/* - * Get the structure header pointer corresponding to the structure ID. - * Returns SDS_OK on success, SDS_ERR_STRUCT_NOT_FOUND on error. - */ -static int get_struct_header(uint32_t structure_id, struct_header_t **header) -{ - unsigned int i, structure_count; - uintptr_t current_header; - - assert(header); - - structure_count = GET_SDS_REGION_STRUCTURE_COUNT(sds_mem_base); - if (structure_count == 0) - return SDS_ERR_STRUCT_NOT_FOUND; - - current_header = ((uintptr_t)sds_mem_base) + SDS_REGION_DESC_SIZE; - - /* Iterate over structure headers to find one with a matching ID */ - for (i = 0; i < structure_count; i++) { - if (GET_SDS_HEADER_ID(current_header) == structure_id) { - *header = (struct_header_t *)current_header; - return SDS_OK; - } - current_header += GET_SDS_HEADER_STRUCT_SIZE(current_header) + - SDS_HEADER_SIZE; - } - - *header = NULL; - return SDS_ERR_STRUCT_NOT_FOUND; -} - -/* - * Check if a structure header corresponding to the structure ID exists. - * Returns SDS_OK if structure header exists else SDS_ERR_STRUCT_NOT_FOUND - * if not found. - */ -int sds_struct_exists(unsigned int structure_id) -{ - struct_header_t *header = NULL; - int ret; - - ret = get_struct_header(structure_id, &header); - if (ret == SDS_OK) { - assert(header); - } - - return ret; -} - -/* - * Read from field in the structure corresponding to `structure_id`. - * `fld_off` is the offset to the field in the structure and `mode` - * indicates whether cache maintenance need to performed prior to the read. - * The `data` is the pointer to store the read data of size specified by `size`. - * Returns SDS_OK on success or corresponding error codes on failure. - */ -int sds_struct_read(uint32_t structure_id, unsigned int fld_off, - void *data, size_t size, sds_access_mode_t mode) -{ - int status; - uintptr_t field_base; - struct_header_t *header = NULL; - - if (!data) - return SDS_ERR_INVALID_PARAMS; - - /* Check if a structure with this ID exists */ - status = get_struct_header(structure_id, &header); - if (status != SDS_OK) - return status; - - assert(header); - - if (mode == SDS_ACCESS_MODE_CACHED) - inv_dcache_range((uintptr_t)header, SDS_HEADER_SIZE + size); - - if (!IS_SDS_HEADER_VALID(header)) { - WARN("SDS: Reading from un-finalized structure 0x%x\n", - structure_id); - return SDS_ERR_STRUCT_NOT_FINALIZED; - } - - if ((fld_off + size) > GET_SDS_HEADER_STRUCT_SIZE(header)) - return SDS_ERR_FAIL; - - field_base = (uintptr_t)header + SDS_HEADER_SIZE + fld_off; - if (check_uptr_overflow(field_base, size - 1)) - return SDS_ERR_FAIL; - - /* Copy the required field in the struct */ - memcpy(data, (void *)field_base, size); - - return SDS_OK; -} - -/* - * Write to the field in the structure corresponding to `structure_id`. - * `fld_off` is the offset to the field in the structure and `mode` - * indicates whether cache maintenance need to performed for the write. - * The `data` is the pointer to data of size specified by `size`. - * Returns SDS_OK on success or corresponding error codes on failure. - */ -int sds_struct_write(uint32_t structure_id, unsigned int fld_off, - void *data, size_t size, sds_access_mode_t mode) -{ - int status; - uintptr_t field_base; - struct_header_t *header = NULL; - - if (!data) - return SDS_ERR_INVALID_PARAMS; - - /* Check if a structure with this ID exists */ - status = get_struct_header(structure_id, &header); - if (status != SDS_OK) - return status; - - assert(header); - - if (mode == SDS_ACCESS_MODE_CACHED) - inv_dcache_range((uintptr_t)header, SDS_HEADER_SIZE + size); - - if (!IS_SDS_HEADER_VALID(header)) { - WARN("SDS: Writing to un-finalized structure 0x%x\n", - structure_id); - return SDS_ERR_STRUCT_NOT_FINALIZED; - } - - if ((fld_off + size) > GET_SDS_HEADER_STRUCT_SIZE(header)) - return SDS_ERR_FAIL; - - field_base = (uintptr_t)header + SDS_HEADER_SIZE + fld_off; - if (check_uptr_overflow(field_base, size - 1)) - return SDS_ERR_FAIL; - - /* Copy the required field in the struct */ - memcpy((void *)field_base, data, size); - - if (mode == SDS_ACCESS_MODE_CACHED) - flush_dcache_range((uintptr_t)field_base, size); - - return SDS_OK; -} - -/* - * Initialize the SDS driver. Also verifies the SDS version and sanity of - * the SDS structure headers. - * Returns SDS_OK on success, SDS_ERR_FAIL on error. - */ -int sds_init(void) -{ - sds_mem_base = (uintptr_t)PLAT_ARM_SDS_MEM_BASE; - - if (!IS_SDS_REGION_VALID(sds_mem_base)) { - WARN("SDS: No valid SDS Memory Region found\n"); - return SDS_ERR_FAIL; - } - - if (GET_SDS_REGION_SCHEMA_VERSION(sds_mem_base) - != SDS_REGION_SCH_VERSION) { - WARN("SDS: Unsupported SDS schema version\n"); - return SDS_ERR_FAIL; - } - - sds_mem_size = GET_SDS_REGION_SIZE(sds_mem_base); - if (sds_mem_size > PLAT_ARM_SDS_MEM_SIZE_MAX) { - WARN("SDS: SDS Memory Region exceeds size limit\n"); - return SDS_ERR_FAIL; - } - - INFO("SDS: Detected SDS Memory Region (%zu bytes)\n", sds_mem_size); - - if (validate_sds_struct_headers() != SDS_OK) - return SDS_ERR_FAIL; - - return SDS_OK; -} diff --git a/plat/arm/css/drivers/sds/sds.h b/plat/arm/css/drivers/sds/sds.h deleted file mode 100644 index 114ae92..0000000 --- a/plat/arm/css/drivers/sds/sds.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef SDS_H -#define SDS_H - -/* SDS Structure Identifier defines */ -/* AP CPU INFO defines */ -#define SDS_AP_CPU_INFO_STRUCT_ID 1 -#define SDS_AP_CPU_INFO_PRIMARY_CPUID_OFFSET 0x0 -#define SDS_AP_CPU_INFO_PRIMARY_CPUID_SIZE 0x4 - -/* ROM Firmware Version defines */ -#define SDS_ROM_VERSION_STRUCT_ID 2 -#define SDS_ROM_VERSION_OFFSET 0x0 -#define SDS_ROM_VERSION_SIZE 0x4 - -/* RAM Firmware version defines */ -#define SDS_RAM_VERSION_STRUCT_ID 3 -#define SDS_RAM_VERSION_OFFSET 0x0 -#define SDS_RAM_VERSION_SIZE 0x4 - -/* Platform Identity defines */ -#define SDS_PLATFORM_IDENTITY_STRUCT_ID 4 -#define SDS_PLATFORM_IDENTITY_ID_OFFSET 0x0 -#define SDS_PLATFORM_IDENTITY_ID_SIZE 0x4 -#define SDS_PLATFORM_IDENTITY_ID_CONFIG_SHIFT 28 -#define SDS_PLATFORM_IDENTITY_ID_CONFIG_WIDTH 4 -#define SDS_PLATFORM_IDENTITY_ID_CONFIG_MASK \ - ((1 << SDS_PLATFORM_IDENTITY_ID_CONFIG_WIDTH) - 1) - -#define SDS_PLATFORM_IDENTITY_PLAT_TYPE_OFFSET 0x4 -#define SDS_PLATFORM_IDENTITY_PLAT_TYPE_SIZE 0x4 - -/* Reset Syndrome defines */ -#define SDS_RESET_SYNDROME_STRUCT_ID 5 -#define SDS_RESET_SYNDROME_OFFSET 0 -#define SDS_RESET_SYNDROME_SIZE 4 -#define SDS_RESET_SYNDROME_POW_ON_RESET_BIT (1 << 0) -#define SDS_RESET_SYNDROME_SCP_WD_RESET_BIT (1 << 1) -#define SDS_RESET_SYNDROME_AP_WD_RESET_BIT (1 << 2) -#define SDS_RESET_SYNDROME_SYS_RESET_REQ_BIT (1 << 3) -#define SDS_RESET_SYNDROME_M3_LOCKUP_BIT (1 << 4) - -/* SCP Firmware Feature Availability defines */ -#define SDS_FEATURE_AVAIL_STRUCT_ID 6 -#define SDS_FEATURE_AVAIL_OFFSET 0 -#define SDS_FEATURE_AVAIL_SIZE 4 -#define SDS_FEATURE_AVAIL_SCP_RAM_READY_BIT (1 << 0) -#define SDS_FEATURE_AVAIL_DMC_READY_BIT (1 << 1) -#define SDS_FEATURE_AVAIL_MSG_IF_READY_BIT (1 << 2) - -/* SCP BL2 Image Metadata defines */ -#define SDS_SCP_IMG_STRUCT_ID 9 -#define SDS_SCP_IMG_FLAG_OFFSET 0 -#define SDS_SCP_IMG_FLAG_SIZE 4 -#define SDS_SCP_IMG_VALID_FLAG_BIT (1 << 0) -#define SDS_SCP_IMG_ADDR_OFFSET 4 -#define SDS_SCP_IMG_ADDR_SIZE 4 -#define SDS_SCP_IMG_SIZE_OFFSET 8 -#define SDS_SCP_IMG_SIZE_SIZE 4 - -/* SDS Driver Error Codes */ -#define SDS_OK 0 -#define SDS_ERR_FAIL -1 -#define SDS_ERR_INVALID_PARAMS -2 -#define SDS_ERR_STRUCT_NOT_FOUND -3 -#define SDS_ERR_STRUCT_NOT_FINALIZED -4 - -#ifndef __ASSEMBLY__ -#include -#include - -typedef enum { - SDS_ACCESS_MODE_NON_CACHED, - SDS_ACCESS_MODE_CACHED, -} sds_access_mode_t; - -int sds_init(void); -int sds_struct_exists(unsigned int structure_id); -int sds_struct_read(uint32_t structure_id, unsigned int fld_off, void *data, - size_t size, sds_access_mode_t mode); -int sds_struct_write(uint32_t structure_id, unsigned int fld_off, void *data, - size_t size, sds_access_mode_t mode); -#endif /*__ASSEMBLY__ */ - -#endif /* SDS_H */ diff --git a/plat/arm/css/drivers/sds/sds_private.h b/plat/arm/css/drivers/sds/sds_private.h deleted file mode 100644 index 2101dd0..0000000 --- a/plat/arm/css/drivers/sds/sds_private.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef SDS_PRIVATE_H -#define SDS_PRIVATE_H - -/* SDS Header defines */ -#define SDS_HEADER_ID_SHIFT 0 -#define SDS_HEADER_ID_WIDTH 16 -#define SDS_HEADER_ID_MASK ((1 << SDS_HEADER_ID_WIDTH) - 1) - -#define SDS_HEADER_MINOR_VERSION_WIDTH 8 -#define SDS_HEADER_MINOR_VERSION_SHIFT 16 -#define SDS_HEADER_MAJOR_VERSION_WIDTH 8 - -#define MAKE_SDS_HEADER_VERSION(major, minor) \ - (((((major) & 0xff) << SDS_HEADER_MINOR_VERSION_WIDTH) | ((minor) & 0xff))) -#define SDS_HEADER_VERSION_MASK \ - ((1 << (SDS_HEADER_MINOR_VERSION_WIDTH + SDS_HEADER_MAJOR_VERSION_WIDTH)) - 1) - -#define SDS_HEADER_VERSION MAKE_SDS_HEADER_VERSION(1, 0) -#define SDS_HEADER_STRUCT_SIZE_WIDTH 23 -#define SDS_HEADER_STRUCT_SIZE_SHIFT 1 -#define SDS_HEADER_STRUCT_SIZE_MASK ((1 << SDS_HEADER_STRUCT_SIZE_WIDTH) - 1) -#define SDS_HEADER_VALID_MASK 0x1 -#define SDS_HEADER_VALID_SHIFT 0 -#define SDS_HEADER_SIZE 0x8 - -/* Arbitrary, 16 bit value that indicates a valid SDS Memory Region */ -#define SDS_REGION_SIGNATURE 0xAA7A -#define SDS_REGION_SIGNATURE_WIDTH 16 -#define SDS_REGION_SIGNATURE_SHIFT 0 -#define SDS_REGION_SIGNATURE_MASK ((1 << SDS_REGION_SIGNATURE_WIDTH) - 1) - -#define SDS_REGION_STRUCT_COUNT_SHIFT 16 -#define SDS_REGION_STRUCT_COUNT_WIDTH 8 -#define SDS_REGION_STRUCT_COUNT_MASK ((1 << SDS_REGION_STRUCT_COUNT_WIDTH) - 1) - -#define SDS_REGION_SCH_MINOR_SHIFT 24 -#define SDS_REGION_SCH_MINOR_WIDTH 4 -#define SDS_REGION_SCH_MINOR_MASK ((1 << SDS_REGION_SCH_MINOR_WIDTH) - 1) - -#define SDS_REGION_SCH_MAJOR_SHIFT 28 -#define SDS_REGION_SCH_MAJOR_WIDTH 4 -#define SDS_REGION_SCH_MAJOR_MASK ((1 << SDS_REGION_SCH_MAJOR_WIDTH) - 1) - -#define SDS_REGION_SCH_VERSION_MASK \ - ((1 << (SDS_REGION_SCH_MINOR_WIDTH + SDS_REGION_SCH_MAJOR_WIDTH)) - 1) - -#define MAKE_SDS_REGION_SCH_VERSION(maj, min) \ - ((((maj) & SDS_REGION_SCH_MAJOR_MASK) << SDS_REGION_SCH_MINOR_WIDTH) | \ - ((min) & SDS_REGION_SCH_MINOR_MASK)) - -#define SDS_REGION_SCH_VERSION MAKE_SDS_REGION_SCH_VERSION(1, 0) -#define SDS_REGION_REGIONSIZE_OFFSET 0x4 -#define SDS_REGION_DESC_SIZE 0x8 - -#ifndef __ASSEMBLY__ -#include -#include - -/* Header containing Shared Data Structure metadata */ -typedef struct structure_header { - uint32_t reg[2]; -} struct_header_t; - -#define GET_SDS_HEADER_ID(_header) \ - ((((struct_header_t *)(_header))->reg[0]) & SDS_HEADER_ID_MASK) -#define GET_SDS_HEADER_VERSION(_header) \ - (((((struct_header_t *)(_header))->reg[0]) >> SDS_HEADER_MINOR_VERSION_SHIFT)\ - & SDS_HEADER_VERSION_MASK) -#define GET_SDS_HEADER_STRUCT_SIZE(_header) \ - (((((struct_header_t *)(_header))->reg[1]) >> SDS_HEADER_STRUCT_SIZE_SHIFT)\ - & SDS_HEADER_STRUCT_SIZE_MASK) -#define IS_SDS_HEADER_VALID(_header) \ - ((((struct_header_t *)(_header))->reg[1]) & SDS_HEADER_VALID_MASK) -#define GET_SDS_STRUCT_FIELD(_header, _field_offset) \ - ((((uint8_t *)(_header)) + sizeof(struct_header_t)) + (_field_offset)) - -/* Region Descriptor describing the SDS Memory Region */ -typedef struct region_descriptor { - uint32_t reg[2]; -} region_desc_t; - -#define IS_SDS_REGION_VALID(region) \ - (((((region_desc_t *)(region))->reg[0]) & SDS_REGION_SIGNATURE_MASK) == SDS_REGION_SIGNATURE) -#define GET_SDS_REGION_STRUCTURE_COUNT(region) \ - (((((region_desc_t *)(region))->reg[0]) >> SDS_REGION_STRUCT_COUNT_SHIFT)\ - & SDS_REGION_STRUCT_COUNT_MASK) -#define GET_SDS_REGION_SCHEMA_VERSION(region) \ - (((((region_desc_t *)(region))->reg[0]) >> SDS_REGION_SCH_MINOR_SHIFT)\ - & SDS_REGION_SCH_VERSION_MASK) -#define GET_SDS_REGION_SIZE(region) ((((region_desc_t *)(region))->reg[1])) - -#endif /* __ASSEMBLY__ */ - -#endif /* SDS_PRIVATE_H */ diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h index 4afaae1..c0e6555 100644 --- a/plat/arm/css/sgi/include/sgi_base_platform_def.h +++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h @@ -9,15 +9,14 @@ #include #include +#include +#include +#include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include - #define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \ CSS_SGI_MAX_CPUS_PER_CLUSTER * \ CSS_SGI_MAX_PE_PER_CPU) diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c index 617a62b..bfcb521 100644 --- a/plat/arm/css/sgi/sgi_bl31_setup.c +++ b/plat/arm/css/sgi/sgi_bl31_setup.c @@ -10,14 +10,13 @@ #include #include +#include +#include +#include -#include #include #include -#include "../../css/drivers/scmi/scmi.h" -#include "../../css/drivers/mhu/css_mhu_doorbell.h" - sgi_platform_info_t sgi_plat_info; static scmi_channel_plat_info_t sgi575_scmi_plat_info = { diff --git a/plat/arm/css/sgi/sgi_image_load.c b/plat/arm/css/sgi/sgi_image_load.c index e52124f..a2f10dc 100644 --- a/plat/arm/css/sgi/sgi_image_load.c +++ b/plat/arm/css/sgi/sgi_image_load.c @@ -9,9 +9,9 @@ #include #include #include +#include #include -#include #include /******************************************************************************* diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c index 72cda7f..83ca30c 100644 --- a/plat/arm/css/sgi/sgi_plat.c +++ b/plat/arm/css/sgi/sgi_plat.c @@ -11,11 +11,10 @@ #include #include #include +#include #include #include -#include - #if USE_COHERENT_MEM /* * The next 2 constants identify the extents of the coherent memory region. diff --git a/plat/arm/css/sgi/sgi_ras.c b/plat/arm/css/sgi/sgi_ras.c index a6a32d1..0001ffd 100644 --- a/plat/arm/css/sgi/sgi_ras.c +++ b/plat/arm/css/sgi/sgi_ras.c @@ -10,12 +10,12 @@ #include #include #include +#include #include #include #include #include -#include #include static int sgi_ras_intr_handler(const struct err_record_info *err_rec, diff --git a/plat/arm/css/sgi/sgi_topology.c b/plat/arm/css/sgi/sgi_topology.c index 2921c0c..dafaf40 100644 --- a/plat/arm/css/sgi/sgi_topology.c +++ b/plat/arm/css/sgi/sgi_topology.c @@ -4,7 +4,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include + #include /* Topology */ diff --git a/plat/arm/css/sgm/include/platform_oid.h b/plat/arm/css/sgm/include/platform_oid.h index 18d41e3..fd1854a 100644 --- a/plat/arm/css/sgm/include/platform_oid.h +++ b/plat/arm/css/sgm/include/platform_oid.h @@ -3,7 +3,8 @@ * * SPDX-License-Identifier: BSD-3-Clause */ -#include "../../../../../include/plat/arm/board/common/board_arm_oid.h" + +#include /* * Required platform OIDs diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h index e3fa3f3..4647e74 100644 --- a/plat/arm/css/sgm/include/sgm_base_platform_def.h +++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h @@ -9,14 +9,13 @@ #include #include +#include +#include +#include +#include +#include #include -#include -#include -#include -#include -#include - /* CPU topology */ #define PLAT_ARM_CLUSTER_COUNT 1 #define PLAT_ARM_CLUSTER_CORE_COUNT 8 diff --git a/plat/arm/css/sgm/sgm_bl1_setup.c b/plat/arm/css/sgm/sgm_bl1_setup.c index 8b7c5da..2036515 100644 --- a/plat/arm/css/sgm/sgm_bl1_setup.c +++ b/plat/arm/css/sgm/sgm_bl1_setup.c @@ -6,10 +6,10 @@ #include #include +#include +#include -#include #include -#include void bl1_early_platform_setup(void) { diff --git a/plat/arm/css/sgm/sgm_bl31_setup.c b/plat/arm/css/sgm/sgm_bl31_setup.c index 7967cb5..7e92ac8 100644 --- a/plat/arm/css/sgm/sgm_bl31_setup.c +++ b/plat/arm/css/sgm/sgm_bl31_setup.c @@ -6,13 +6,12 @@ #include #include +#include +#include +#include -#include #include -#include "../../css/drivers/scmi/scmi.h" -#include "../../css/drivers/mhu/css_mhu_doorbell.h" - static scmi_channel_plat_info_t sgm775_scmi_plat_info = { .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE, .db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF, diff --git a/plat/arm/css/sgm/sgm_mmap_config.c b/plat/arm/css/sgm/sgm_mmap_config.c index 763f36a..e5b4b03 100644 --- a/plat/arm/css/sgm/sgm_mmap_config.c +++ b/plat/arm/css/sgm/sgm_mmap_config.c @@ -8,8 +8,8 @@ #include #include +#include -#include #include /* diff --git a/plat/arm/css/sgm/sgm_plat_config.c b/plat/arm/css/sgm/sgm_plat_config.c index 2a43487..d9e65c5 100644 --- a/plat/arm/css/sgm/sgm_plat_config.c +++ b/plat/arm/css/sgm/sgm_plat_config.c @@ -10,8 +10,8 @@ #include #include +#include -#include #include #include diff --git a/plat/arm/css/sgm/sgm_security.c b/plat/arm/css/sgm/sgm_security.c index 548ec7b..21d5306 100644 --- a/plat/arm/css/sgm/sgm_security.c +++ b/plat/arm/css/sgm/sgm_security.c @@ -6,10 +6,10 @@ #include #include +#include +#include -#include #include -#include /* Is populated with the DMC-500 controllers base addresses */ static tzc_dmc500_driver_data_t plat_driver_data; diff --git a/plat/arm/css/sgm/sgm_topology.c b/plat/arm/css/sgm/sgm_topology.c index ce72464..2d9552d 100644 --- a/plat/arm/css/sgm/sgm_topology.c +++ b/plat/arm/css/sgm/sgm_topology.c @@ -4,7 +4,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include + #include /******************************************************************************* diff --git a/plat/arm/css/sgm/tsp/sgm_tsp_setup.c b/plat/arm/css/sgm/tsp/sgm_tsp_setup.c index 39bba94..5f40c4c 100644 --- a/plat/arm/css/sgm/tsp/sgm_tsp_setup.c +++ b/plat/arm/css/sgm/tsp/sgm_tsp_setup.c @@ -4,7 +4,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include + #include void tsp_early_platform_setup(void) diff --git a/plat/arm/soc/common/soc_css.mk b/plat/arm/soc/common/soc_css.mk index e009467..8cad2a5 100644 --- a/plat/arm/soc/common/soc_css.mk +++ b/plat/arm/soc/common/soc_css.mk @@ -4,8 +4,6 @@ # SPDX-License-Identifier: BSD-3-Clause # -PLAT_INCLUDES += -Iinclude/plat/arm/soc/common/ - #PLAT_BL_COMMON_SOURCES += BL1_SOURCES += plat/arm/soc/common/soc_css_security.c diff --git a/plat/arm/soc/common/soc_css_security.c b/plat/arm/soc/common/soc_css_security.c index b48357a..4f6bf61 100644 --- a/plat/arm/soc/common/soc_css_security.c +++ b/plat/arm/soc/common/soc_css_security.c @@ -8,8 +8,7 @@ #include #include - -#include +#include void soc_css_init_nic400(void) { diff --git a/plat/mediatek/mt8173/bl31_plat_setup.c b/plat/mediatek/mt8173/bl31_plat_setup.c index bd384a1..dd23e63 100644 --- a/plat/mediatek/mt8173/bl31_plat_setup.c +++ b/plat/mediatek/mt8173/bl31_plat_setup.c @@ -11,13 +11,13 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include diff --git a/plat/mediatek/mt8173/plat_pm.c b/plat/mediatek/mt8173/plat_pm.c index 9673d2c..1b52470 100644 --- a/plat/mediatek/mt8173/plat_pm.c +++ b/plat/mediatek/mt8173/plat_pm.c @@ -15,11 +15,11 @@ #include #include #include +#include #include #include #include /* generic_timer_backup() */ -#include #include #include #include diff --git a/plat/mediatek/mt8173/platform.mk b/plat/mediatek/mt8173/platform.mk index 294aea4..0726efe 100644 --- a/plat/mediatek/mt8173/platform.mk +++ b/plat/mediatek/mt8173/platform.mk @@ -9,7 +9,6 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ -I${MTK_PLAT}/common/drivers/uart/ \ - -Iinclude/plat/arm/common \ -Iinclude/plat/arm/common/aarch64 \ -I${MTK_PLAT_SOC}/drivers/crypt/ \ -I${MTK_PLAT_SOC}/drivers/mtcmos/ \ diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c index 8ecd6d7..b0eb66c 100644 --- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c +++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c @@ -11,10 +11,11 @@ #include #include #include -#include -#include +#include #include +#include + #define BL31_END (unsigned long)(&__BL31_END__) static entry_point_info_t bl32_image_ep_info; diff --git a/plat/xilinx/zynqmp/plat_psci.c b/plat/xilinx/zynqmp/plat_psci.c index 8522d3e..a32e089 100644 --- a/plat/xilinx/zynqmp/plat_psci.c +++ b/plat/xilinx/zynqmp/plat_psci.c @@ -12,10 +12,10 @@ #include #include #include -#include +#include #include -#include +#include #include "pm_api_sys.h" #include "pm_client.h" diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk index d147916..b2f91cd 100644 --- a/plat/xilinx/zynqmp/platform.mk +++ b/plat/xilinx/zynqmp/platform.mk @@ -45,8 +45,7 @@ $(eval $(call add_define,ZYNQMP_WDT_RESTART)) endif -PLAT_INCLUDES := -Iinclude/plat/arm/common/ \ - -Iinclude/plat/arm/common/aarch64/ \ +PLAT_INCLUDES := -Iinclude/plat/arm/common/aarch64/ \ -Iplat/xilinx/common/include/ \ -Iplat/xilinx/zynqmp/include/ \ -Iplat/xilinx/zynqmp/pm_service/ \ diff --git a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c index 97718d6..902e4b3 100644 --- a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c +++ b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c @@ -7,8 +7,8 @@ #include #include #include +#include -#include #include #include