diff options
Diffstat (limited to 'plat/amlogic/common')
-rw-r--r-- | plat/amlogic/common/aarch64/aml_helpers.S | 97 | ||||
-rw-r--r-- | plat/amlogic/common/aml_console.c | 33 | ||||
-rw-r--r-- | plat/amlogic/common/aml_efuse.c | 25 | ||||
-rw-r--r-- | plat/amlogic/common/aml_mhu.c | 52 | ||||
-rw-r--r-- | plat/amlogic/common/aml_scpi.c | 234 | ||||
-rw-r--r-- | plat/amlogic/common/aml_sip_svc.c | 99 | ||||
-rw-r--r-- | plat/amlogic/common/aml_thermal.c | 27 | ||||
-rw-r--r-- | plat/amlogic/common/aml_topology.c | 53 | ||||
-rw-r--r-- | plat/amlogic/common/include/aml_private.h | 41 | ||||
-rw-r--r-- | plat/amlogic/common/include/plat_macros.S | 71 |
10 files changed, 732 insertions, 0 deletions
diff --git a/plat/amlogic/common/aarch64/aml_helpers.S b/plat/amlogic/common/aarch64/aml_helpers.S new file mode 100644 index 0000000..159c7d1 --- /dev/null +++ b/plat/amlogic/common/aarch64/aml_helpers.S @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <asm_macros.S> +#include <assert_macros.S> +#include <platform_def.h> + + .globl plat_crash_console_flush + .globl plat_crash_console_init + .globl plat_crash_console_putc + .globl platform_mem_init + .globl plat_is_my_cpu_primary + .globl plat_my_core_pos + .globl plat_reset_handler + .globl plat_calc_core_pos + + /* ----------------------------------------------------- + * unsigned int plat_my_core_pos(void); + * ----------------------------------------------------- + */ +func plat_my_core_pos + mrs x0, mpidr_el1 + b plat_calc_core_pos +endfunc plat_my_core_pos + + /* ----------------------------------------------------- + * unsigned int plat_calc_core_pos(u_register_t mpidr); + * ----------------------------------------------------- + */ +func plat_calc_core_pos + and x0, x0, #MPIDR_CPU_MASK + ret +endfunc plat_calc_core_pos + + /* ----------------------------------------------------- + * unsigned int plat_is_my_cpu_primary(void); + * ----------------------------------------------------- + */ +func plat_is_my_cpu_primary + mrs x0, mpidr_el1 + and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) + cmp x0, #AML_PRIMARY_CPU + cset w0, eq + ret +endfunc plat_is_my_cpu_primary + + /* --------------------------------------------- + * void platform_mem_init(void); + * --------------------------------------------- + */ +func platform_mem_init + ret +endfunc platform_mem_init + + /* --------------------------------------------- + * int plat_crash_console_init(void) + * --------------------------------------------- + */ +func plat_crash_console_init + mov_imm x0, AML_UART0_AO_BASE + mov_imm x1, AML_UART0_AO_CLK_IN_HZ + mov_imm x2, AML_UART_BAUDRATE + b console_meson_init +endfunc plat_crash_console_init + + /* --------------------------------------------- + * int plat_crash_console_putc(int c) + * Clobber list : x1, x2 + * --------------------------------------------- + */ +func plat_crash_console_putc + mov_imm x1, AML_UART0_AO_BASE + b console_meson_core_putc +endfunc plat_crash_console_putc + + /* --------------------------------------------- + * void plat_crash_console_flush() + * Out : void. + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func plat_crash_console_flush + mov_imm x0, AML_UART0_AO_BASE + b console_meson_core_flush +endfunc plat_crash_console_flush + + /* --------------------------------------------- + * void plat_reset_handler(void); + * --------------------------------------------- + */ +func plat_reset_handler + ret +endfunc plat_reset_handler diff --git a/plat/amlogic/common/aml_console.c b/plat/amlogic/common/aml_console.c new file mode 100644 index 0000000..e21d707 --- /dev/null +++ b/plat/amlogic/common/aml_console.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2019, Carlo Caione <ccaione@baylibre.com> + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <meson_console.h> +#include <platform_def.h> + +/******************************************************************************* + * Function that sets up the console + ******************************************************************************/ +static console_t aml_console; + +void aml_console_init(void) +{ + int rc = console_meson_register(AML_UART0_AO_BASE, + AML_UART0_AO_CLK_IN_HZ, + AML_UART_BAUDRATE, + &aml_console); + if (rc == 0) { + /* + * The crash console doesn't use the multi console API, it uses + * the core console functions directly. It is safe to call panic + * and let it print debug information. + */ + panic(); + } + + console_set_scope(&aml_console, + CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME); +} diff --git a/plat/amlogic/common/aml_efuse.c b/plat/amlogic/common/aml_efuse.c new file mode 100644 index 0000000..00884eb --- /dev/null +++ b/plat/amlogic/common/aml_efuse.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdint.h> + +#include "aml_private.h" + +#define EFUSE_BASE 0x140 +#define EFUSE_SIZE 0xC0 + +uint64_t aml_efuse_read(void *dst, uint32_t offset, uint32_t size) +{ + if ((uint64_t)(offset + size) > (uint64_t)EFUSE_SIZE) + return 0; + + return aml_scpi_efuse_read(dst, offset + EFUSE_BASE, size); +} + +uint64_t aml_efuse_user_max(void) +{ + return EFUSE_SIZE; +} diff --git a/plat/amlogic/common/aml_mhu.c b/plat/amlogic/common/aml_mhu.c new file mode 100644 index 0000000..001686a --- /dev/null +++ b/plat/amlogic/common/aml_mhu.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <lib/bakery_lock.h> +#include <lib/mmio.h> +#include <platform_def.h> + +static DEFINE_BAKERY_LOCK(mhu_lock); + +void aml_mhu_secure_message_start(void) +{ + bakery_lock_get(&mhu_lock); + + while (mmio_read_32(AML_HIU_MAILBOX_STAT_3) != 0) + ; +} + +void aml_mhu_secure_message_send(uint32_t msg) +{ + mmio_write_32(AML_HIU_MAILBOX_SET_3, msg); + + while (mmio_read_32(AML_HIU_MAILBOX_STAT_3) != 0) + ; +} + +uint32_t aml_mhu_secure_message_wait(void) +{ + uint32_t val; + + do { + val = mmio_read_32(AML_HIU_MAILBOX_STAT_0); + } while (val == 0); + + return val; +} + +void aml_mhu_secure_message_end(void) +{ + mmio_write_32(AML_HIU_MAILBOX_CLR_0, 0xFFFFFFFF); + + bakery_lock_release(&mhu_lock); +} + +void aml_mhu_secure_init(void) +{ + bakery_lock_init(&mhu_lock); + + mmio_write_32(AML_HIU_MAILBOX_CLR_3, 0xFFFFFFFF); +} diff --git a/plat/amlogic/common/aml_scpi.c b/plat/amlogic/common/aml_scpi.c new file mode 100644 index 0000000..c8a6772 --- /dev/null +++ b/plat/amlogic/common/aml_scpi.c @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <crypto/sha_dma.h> +#include <lib/mmio.h> +#include <plat/common/platform.h> +#include <platform_def.h> +#include <string.h> + +#include "aml_private.h" + +#define SIZE_SHIFT 20 +#define SIZE_MASK 0x1FF +#define SIZE_FWBLK 0x200UL + +/* + * Note: The Amlogic SCP firmware uses the legacy SCPI protocol. + */ +#define SCPI_CMD_SET_CSS_POWER_STATE 0x04 +#define SCPI_CMD_SET_SYS_POWER_STATE 0x08 + +#define SCPI_CMD_JTAG_SET_STATE 0xC0 +#define SCPI_CMD_EFUSE_READ 0xC2 +#define SCPI_CMD_CHIP_ID 0xC6 + +#define SCPI_CMD_COPY_FW 0xd4 +#define SCPI_CMD_SET_FW_ADDR 0xd3 +#define SCPI_CMD_FW_SIZE 0xd2 + +static inline uint32_t aml_scpi_cmd(uint32_t command, uint32_t size) +{ + return command | (size << SIZE_SHIFT); +} + +static void aml_scpi_secure_message_send(uint32_t command, uint32_t size) +{ + aml_mhu_secure_message_send(aml_scpi_cmd(command, size)); +} + +static uint32_t aml_scpi_secure_message_receive(void **message_out, size_t *size_out) +{ + uint32_t response = aml_mhu_secure_message_wait(); + + size_t size = (response >> SIZE_SHIFT) & SIZE_MASK; + + response &= ~(SIZE_MASK << SIZE_SHIFT); + + if (size_out != NULL) + *size_out = size; + + if (message_out != NULL) + *message_out = (void *)AML_MHU_SECURE_SCP_TO_AP_PAYLOAD; + + return response; +} + +void aml_scpi_set_css_power_state(u_register_t mpidr, uint32_t cpu_state, + uint32_t cluster_state, uint32_t css_state) +{ + uint32_t state = (mpidr & 0x0F) | /* CPU ID */ + ((mpidr & 0xF00) >> 4) | /* Cluster ID */ + (cpu_state << 8) | + (cluster_state << 12) | + (css_state << 16); + + aml_mhu_secure_message_start(); + mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD, state); + aml_mhu_secure_message_send(aml_scpi_cmd(SCPI_CMD_SET_CSS_POWER_STATE, 4)); + aml_mhu_secure_message_wait(); + aml_mhu_secure_message_end(); +} + +uint32_t aml_scpi_sys_power_state(uint64_t system_state) +{ + uint32_t *response; + size_t size; + + aml_mhu_secure_message_start(); + mmio_write_8(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD, system_state); + aml_mhu_secure_message_send(aml_scpi_cmd(SCPI_CMD_SET_SYS_POWER_STATE, 1)); + aml_scpi_secure_message_receive((void *)&response, &size); + aml_mhu_secure_message_end(); + + return *response; +} + +void aml_scpi_jtag_set_state(uint32_t state, uint8_t select) +{ + assert(state <= AML_JTAG_STATE_OFF); + + if (select > AML_JTAG_A53_EE) { + WARN("BL31: Invalid JTAG select (0x%x).\n", select); + return; + } + + aml_mhu_secure_message_start(); + mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD, + (state << 8) | (uint32_t)select); + aml_mhu_secure_message_send(aml_scpi_cmd(SCPI_CMD_JTAG_SET_STATE, 4)); + aml_mhu_secure_message_wait(); + aml_mhu_secure_message_end(); +} + +uint32_t aml_scpi_efuse_read(void *dst, uint32_t base, uint32_t size) +{ + uint32_t *response; + size_t resp_size; + + if (size > 0x1FC) + return 0; + + aml_mhu_secure_message_start(); + mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD, base); + mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD + 4, size); + aml_mhu_secure_message_send(aml_scpi_cmd(SCPI_CMD_EFUSE_READ, 8)); + aml_scpi_secure_message_receive((void *)&response, &resp_size); + aml_mhu_secure_message_end(); + + /* + * response[0] is the size of the response message. + * response[1 ... N] are the contents. + */ + if (*response != 0) + memcpy(dst, response + 1, *response); + + return *response; +} + +void aml_scpi_unknown_thermal(uint32_t arg0, uint32_t arg1, + uint32_t arg2, uint32_t arg3) +{ + aml_mhu_secure_message_start(); + mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0x0, arg0); + mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0x4, arg1); + mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0x8, arg2); + mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0xC, arg3); + aml_mhu_secure_message_send(aml_scpi_cmd(0xC3, 16)); + aml_mhu_secure_message_wait(); + aml_mhu_secure_message_end(); +} + +uint32_t aml_scpi_get_chip_id(uint8_t *obuff, uint32_t osize) +{ + uint32_t *response; + size_t resp_size; + + if ((osize != 16) && (osize != 12)) + return 0; + + aml_mhu_secure_message_start(); + aml_mhu_secure_message_send(aml_scpi_cmd(SCPI_CMD_CHIP_ID, osize)); + aml_scpi_secure_message_receive((void *)&response, &resp_size); + aml_mhu_secure_message_end(); + + if (!((resp_size == 16) && (osize == 16)) && + !((resp_size == 0) && (osize == 12))) + return 0; + + memcpy((void *)obuff, (const void *)response, osize); + + return osize; +} + +static inline void aml_scpi_copy_scp_data(uint8_t *data, size_t len) +{ + void *dst = (void *)AML_MHU_SECURE_AP_TO_SCP_PAYLOAD; + size_t sz; + + mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD, len); + aml_scpi_secure_message_send(SCPI_CMD_FW_SIZE, len); + aml_mhu_secure_message_wait(); + + for (sz = 0; sz < len; sz += SIZE_FWBLK) { + memcpy(dst, data + sz, MIN(SIZE_FWBLK, len - sz)); + aml_mhu_secure_message_send(SCPI_CMD_COPY_FW); + } +} + +static inline void aml_scpi_set_scp_addr(uint64_t addr, size_t len) +{ + volatile uint64_t *dst = (uint64_t *)AML_MHU_SECURE_AP_TO_SCP_PAYLOAD; + + /* + * It is ok as AML_MHU_SECURE_AP_TO_SCP_PAYLOAD is mapped as + * non cachable + */ + *dst = addr; + aml_scpi_secure_message_send(SCPI_CMD_SET_FW_ADDR, sizeof(addr)); + aml_mhu_secure_message_wait(); + + mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD, len); + aml_scpi_secure_message_send(SCPI_CMD_FW_SIZE, len); + aml_mhu_secure_message_wait(); +} + +static inline void aml_scpi_send_fw_hash(uint8_t hash[], size_t len) +{ + void *dst = (void *)AML_MHU_SECURE_AP_TO_SCP_PAYLOAD; + + memcpy(dst, hash, len); + aml_mhu_secure_message_send(0xd0); + aml_mhu_secure_message_send(0xd1); + aml_mhu_secure_message_send(0xd5); + aml_mhu_secure_message_end(); +} + +/** + * Upload a FW to SCP. + * + * @param addr: firmware data address + * @param size: size of firmware + * @param send: If set, actually copy the firmware in SCP memory otherwise only + * send the firmware address. + */ +void aml_scpi_upload_scp_fw(uintptr_t addr, size_t size, int send) +{ + struct asd_ctx ctx; + + asd_sha_init(&ctx, ASM_SHA256); + asd_sha_update(&ctx, (void *)addr, size); + asd_sha_finalize(&ctx); + + aml_mhu_secure_message_start(); + if (send == 0) + aml_scpi_set_scp_addr(addr, size); + else + aml_scpi_copy_scp_data((void *)addr, size); + + aml_scpi_send_fw_hash(ctx.digest, sizeof(ctx.digest)); +} diff --git a/plat/amlogic/common/aml_sip_svc.c b/plat/amlogic/common/aml_sip_svc.c new file mode 100644 index 0000000..ab4c015 --- /dev/null +++ b/plat/amlogic/common/aml_sip_svc.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <common/runtime_svc.h> +#include <lib/mmio.h> +#include <platform_def.h> +#include <stdint.h> +#include <string.h> + +#include "aml_private.h" + +struct aml_cpu_info { + uint32_t version; + uint8_t chip_id[16]; +}; + +static int aml_sip_get_chip_id(uint64_t version) +{ + struct aml_cpu_info *info = (void *)AML_SHARE_MEM_OUTPUT_BASE; + uint32_t size; + + if (version > 2) + return -1; + + memset(info, 0, sizeof(struct aml_cpu_info)); + + if (version == 2) { + info->version = 2; + size = 16; + } else { + info->version = 1; + size = 12; + } + + if (aml_scpi_get_chip_id(info->chip_id, size) == 0) + return -1; + + return 0; +} + +/******************************************************************************* + * This function is responsible for handling all SiP calls + ******************************************************************************/ +static uintptr_t aml_sip_handler(uint32_t smc_fid, + u_register_t x1, u_register_t x2, + u_register_t x3, u_register_t x4, + void *cookie, void *handle, + u_register_t flags) +{ + switch (smc_fid) { + + case AML_SM_GET_SHARE_MEM_INPUT_BASE: + SMC_RET1(handle, AML_SHARE_MEM_INPUT_BASE); + + case AML_SM_GET_SHARE_MEM_OUTPUT_BASE: + SMC_RET1(handle, AML_SHARE_MEM_OUTPUT_BASE); + + case AML_SM_EFUSE_READ: + { + void *dst = (void *)AML_SHARE_MEM_OUTPUT_BASE; + uint64_t ret = aml_efuse_read(dst, (uint32_t)x1, x2); + + SMC_RET1(handle, ret); + } + case AML_SM_EFUSE_USER_MAX: + SMC_RET1(handle, aml_efuse_user_max()); + + case AML_SM_JTAG_ON: + aml_scpi_jtag_set_state(AML_JTAG_STATE_ON, x1); + SMC_RET1(handle, 0); + + case AML_SM_JTAG_OFF: + aml_scpi_jtag_set_state(AML_JTAG_STATE_OFF, x1); + SMC_RET1(handle, 0); + + case AML_SM_GET_CHIP_ID: + SMC_RET1(handle, aml_sip_get_chip_id(x1)); + + default: + ERROR("BL31: Unhandled SIP SMC: 0x%08x\n", smc_fid); + break; + } + + SMC_RET1(handle, SMC_UNK); +} + +DECLARE_RT_SVC( + aml_sip_handler, + + OEN_SIP_START, + OEN_SIP_END, + SMC_TYPE_FAST, + NULL, + aml_sip_handler +); diff --git a/plat/amlogic/common/aml_thermal.c b/plat/amlogic/common/aml_thermal.c new file mode 100644 index 0000000..53ed103 --- /dev/null +++ b/plat/amlogic/common/aml_thermal.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdint.h> + +#include "aml_private.h" + +static int32_t modules_initialized = -1; + +/******************************************************************************* + * Unknown commands related to something thermal-related + ******************************************************************************/ +void aml_thermal_unknown(void) +{ + uint16_t ret; + + if (modules_initialized == -1) { + aml_scpi_efuse_read(&ret, 0, 2); + modules_initialized = ret; + } + + aml_scpi_unknown_thermal(10, 2, /* thermal */ + 13, 1); /* thermalver */ +} diff --git a/plat/amlogic/common/aml_topology.c b/plat/amlogic/common/aml_topology.c new file mode 100644 index 0000000..0a04c11 --- /dev/null +++ b/plat/amlogic/common/aml_topology.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <platform_def.h> +#include <stdint.h> + +#include "aml_private.h" + +/* The power domain tree descriptor */ +static unsigned char power_domain_tree_desc[] = { + /* Number of root nodes */ + PLATFORM_CLUSTER_COUNT, + /* Number of children for the first node */ + PLATFORM_CLUSTER0_CORE_COUNT +}; + +/******************************************************************************* + * This function returns the ARM default topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return power_domain_tree_desc; +} + +/******************************************************************************* + * This function implements a part of the critical interface between the psci + * generic layer and the platform that allows the former to query the platform + * to convert an MPIDR to a unique linear index. An error code (-1) is returned + * in case the MPIDR is invalid. + ******************************************************************************/ +int plat_core_pos_by_mpidr(u_register_t mpidr) +{ + unsigned int cluster_id, cpu_id; + + mpidr &= MPIDR_AFFINITY_MASK; + if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) + return -1; + + cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; + cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK; + + if (cluster_id >= PLATFORM_CLUSTER_COUNT) + return -1; + + if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER) + return -1; + + return plat_calc_core_pos(mpidr); +} diff --git a/plat/amlogic/common/include/aml_private.h b/plat/amlogic/common/include/aml_private.h new file mode 100644 index 0000000..724f382 --- /dev/null +++ b/plat/amlogic/common/include/aml_private.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef AML_PRIVATE_H +#define AML_PRIVATE_H + +#include <stddef.h> +#include <stdint.h> + +/* Utility functions */ +unsigned int plat_calc_core_pos(u_register_t mpidr); +void aml_console_init(void); +void aml_setup_page_tables(void); + +/* MHU functions */ +void aml_mhu_secure_message_start(void); +void aml_mhu_secure_message_send(uint32_t msg); +uint32_t aml_mhu_secure_message_wait(void); +void aml_mhu_secure_message_end(void); +void aml_mhu_secure_init(void); + +/* SCPI functions */ +void aml_scpi_set_css_power_state(u_register_t mpidr, uint32_t cpu_state, + uint32_t cluster_state, uint32_t css_state); +uint32_t aml_scpi_sys_power_state(uint64_t system_state); +void aml_scpi_jtag_set_state(uint32_t state, uint8_t select); +uint32_t aml_scpi_efuse_read(void *dst, uint32_t base, uint32_t size); +void aml_scpi_unknown_thermal(uint32_t arg0, uint32_t arg1, + uint32_t arg2, uint32_t arg3); +void aml_scpi_upload_scp_fw(uintptr_t addr, size_t size, int send); +uint32_t aml_scpi_get_chip_id(uint8_t *obuff, uint32_t osize); + +/* Peripherals */ +void aml_thermal_unknown(void); +uint64_t aml_efuse_read(void *dst, uint32_t offset, uint32_t size); +uint64_t aml_efuse_user_max(void); + +#endif /* AML_PRIVATE_H */ diff --git a/plat/amlogic/common/include/plat_macros.S b/plat/amlogic/common/include/plat_macros.S new file mode 100644 index 0000000..d620fcf --- /dev/null +++ b/plat/amlogic/common/include/plat_macros.S @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_MACROS_S +#define PLAT_MACROS_S + +#include <drivers/arm/gicv2.h> +#include <platform_def.h> + +.section .rodata.gic_reg_name, "aS" + +gicc_regs: + .asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", "" +gicd_pend_reg: + .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n Offset:\t\t\tvalue\n" +newline: + .asciz "\n" +spacer: + .asciz ":\t\t0x" + + /* --------------------------------------------- + * The below required platform porting macro + * prints out relevant GIC and CCI registers + * whenever an unhandled exception is taken in + * BL31. + * Clobbers: x0 - x10, x16, x17, sp + * --------------------------------------------- + */ + .macro plat_crash_print_regs + + /* GICC registers */ + + mov_imm x17, AML_GICC_BASE + + adr x6, gicc_regs + ldr w8, [x17, #GICC_HPPIR] + ldr w9, [x17, #GICC_AHPPIR] + ldr w10, [x17, #GICC_CTLR] + bl str_in_crash_buf_print + + /* GICD registers */ + + mov_imm x16, AML_GICD_BASE + + add x7, x16, #GICD_ISPENDR + adr x4, gicd_pend_reg + bl asm_print_str + +gicd_ispendr_loop: + sub x4, x7, x16 + cmp x4, #0x280 + b.eq exit_print_gic_regs + bl asm_print_hex + + adr x4, spacer + bl asm_print_str + + ldr x4, [x7], #8 + bl asm_print_hex + + adr x4, newline + bl asm_print_str + b gicd_ispendr_loop +exit_print_gic_regs: + + .endm + +#endif /* PLAT_MACROS_S */ |