diff options
60 files changed, 4133 insertions, 873 deletions
@@ -100,6 +100,13 @@ else LOG_LEVEL := 20 endif +# Enable backtrace by default in DEBUG AArch64 builds +ifeq (${ARCH},aarch32) + ENABLE_BACKTRACE := 0 +else + ENABLE_BACKTRACE := ${DEBUG} +endif + # Default build string (git branch and commit) ifeq (${BUILD_STRING},) BUILD_STRING := $(shell git describe --always --dirty --tags 2> /dev/null) @@ -166,6 +173,14 @@ TF_CFLAGS_aarch64 = -march=armv8-a LD = $(LINKER) endif +ifeq (${AARCH32_INSTRUCTION_SET},A32) +TF_CFLAGS_aarch32 += -marm +else ifeq (${AARCH32_INSTRUCTION_SET},T32) +TF_CFLAGS_aarch32 += -mthumb +else +$(error Error: Unknown AArch32 instruction set ${AARCH32_INSTRUCTION_SET}) +endif + TF_CFLAGS_aarch32 += -mno-unaligned-access TF_CFLAGS_aarch64 += -mgeneral-regs-only -mstrict-align @@ -188,6 +203,11 @@ ifneq ($(PIE_FOUND),) TF_CFLAGS += -fno-PIE endif +# Force the compiler to include the frame pointer +ifeq (${ENABLE_BACKTRACE},1) +TF_CFLAGS += -fno-omit-frame-pointer +endif + TF_LDFLAGS += --fatal-warnings -O1 TF_LDFLAGS += --gc-sections TF_LDFLAGS += $(TF_LDFLAGS_$(ARCH)) @@ -215,6 +235,10 @@ ifeq ($(notdir $(CC)),armclang) BL_COMMON_SOURCES += lib/${ARCH}/armclang_printf.S endif +ifeq (${ENABLE_BACKTRACE},1) +BL_COMMON_SOURCES += common/backtrace.c +endif + INCLUDES += -Iinclude \ -Iinclude/bl1 \ -Iinclude/bl2 \ @@ -345,6 +369,15 @@ endif # Check incompatible options ################################################################################ +ifeq (${ARCH},aarch32) + ifeq (${ENABLE_BACKTRACE},1) + ifneq (${AARCH32_INSTRUCTION_SET},A32) + $(error Error: AARCH32_INSTRUCTION_SET=A32 is needed \ + for ENABLE_BACKTRACE when compiling for AArch32.) + endif + endif +endif + ifdef EL3_PAYLOAD_BASE ifdef PRELOADED_BL33_BASE $(warning "PRELOADED_BL33_BASE and EL3_PAYLOAD_BASE are \ @@ -551,6 +584,7 @@ $(eval $(call assert_boolean,DYN_DISABLE_AUTH)) $(eval $(call assert_boolean,EL3_EXCEPTION_HANDLING)) $(eval $(call assert_boolean,ENABLE_AMU)) $(eval $(call assert_boolean,ENABLE_ASSERTIONS)) +$(eval $(call assert_boolean,ENABLE_BACKTRACE)) $(eval $(call assert_boolean,ENABLE_MPAM_FOR_LOWER_ELS)) $(eval $(call assert_boolean,ENABLE_PLAT_COMPAT)) $(eval $(call assert_boolean,ENABLE_PMF)) @@ -603,6 +637,7 @@ $(eval $(call add_define,CTX_INCLUDE_FPREGS)) $(eval $(call add_define,EL3_EXCEPTION_HANDLING)) $(eval $(call add_define,ENABLE_AMU)) $(eval $(call add_define,ENABLE_ASSERTIONS)) +$(eval $(call add_define,ENABLE_BACKTRACE)) $(eval $(call add_define,ENABLE_MPAM_FOR_LOWER_ELS)) $(eval $(call add_define,ENABLE_PLAT_COMPAT)) $(eval $(call add_define,ENABLE_PMF)) diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c index 06647412..650181dd 100644 --- a/bl31/bl31_main.c +++ b/bl31/bl31_main.c @@ -103,9 +103,14 @@ void bl31_main(void) /* * If SPD had registerd an init hook, invoke it. */ - if (bl32_init) { + if (bl32_init != NULL) { INFO("BL31: Initializing BL32\n"); - (*bl32_init)(); + + int32_t rc = (*bl32_init)(); + + if (rc != 0) { + ERROR("BL31: BL32 initialization failed (rc = %d)", rc); + } } /* * We are ready to enter the next EL. Prepare entry into the image @@ -167,7 +172,7 @@ void bl31_prepare_next_image_entry(void) /* Program EL3 registers to enable entry into the next EL */ next_image_info = bl31_plat_get_next_image_ep_info(image_type); - assert(next_image_info); + assert(next_image_info != NULL); assert(image_type == GET_SECURITY_STATE(next_image_info->h.attr)); INFO("BL31: Preparing for EL3 exit to %s world\n", diff --git a/bl31/interrupt_mgmt.c b/bl31/interrupt_mgmt.c index b885a66a..0df50b6d 100644 --- a/bl31/interrupt_mgmt.c +++ b/bl31/interrupt_mgmt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,7 +10,6 @@ #include <errno.h> #include <interrupt_mgmt.h> #include <platform.h> -#include <stdio.h> /******************************************************************************* * Local structure and corresponding array to keep track of the state of the @@ -47,8 +46,8 @@ static intr_type_desc_t intr_type_descs[MAX_INTR_TYPES]; ******************************************************************************/ static int32_t validate_interrupt_type(uint32_t type) { - if (type == INTR_TYPE_S_EL1 || type == INTR_TYPE_NS || - type == INTR_TYPE_EL3) + if ((type == INTR_TYPE_S_EL1) || (type == INTR_TYPE_NS) || + (type == INTR_TYPE_EL3)) return 0; return -EINVAL; @@ -59,17 +58,16 @@ static int32_t validate_interrupt_type(uint32_t type) ******************************************************************************/ static int32_t validate_routing_model(uint32_t type, uint32_t flags) { - flags >>= INTR_RM_FLAGS_SHIFT; - flags &= INTR_RM_FLAGS_MASK; + uint32_t rm_flags = (flags >> INTR_RM_FLAGS_SHIFT) & INTR_RM_FLAGS_MASK; if (type == INTR_TYPE_S_EL1) - return validate_sel1_interrupt_rm(flags); + return validate_sel1_interrupt_rm(rm_flags); if (type == INTR_TYPE_NS) - return validate_ns_interrupt_rm(flags); + return validate_ns_interrupt_rm(rm_flags); if (type == INTR_TYPE_EL3) - return validate_el3_interrupt_rm(flags); + return validate_el3_interrupt_rm(rm_flags); return -EINVAL; } @@ -106,10 +104,12 @@ static void set_scr_el3_from_rm(uint32_t type, bit_pos = plat_interrupt_type_to_line(type, security_state); intr_type_descs[type].scr_el3[security_state] = flag << bit_pos; - /* Update scr_el3 only if there is a context available. If not, it + /* + * Update scr_el3 only if there is a context available. If not, it * will be updated later during context initialization which will obtain - * the scr_el3 value to be used via get_scr_el3_from_routing_model() */ - if (cm_get_context(security_state)) + * the scr_el3 value to be used via get_scr_el3_from_routing_model() + */ + if (cm_get_context(security_state) != NULL) cm_write_scr_el3_bit(security_state, bit_pos, flag); } @@ -124,11 +124,11 @@ int32_t set_routing_model(uint32_t type, uint32_t flags) int32_t rc; rc = validate_interrupt_type(type); - if (rc) + if (rc != 0) return rc; rc = validate_routing_model(type, flags); - if (rc) + if (rc != 0) return rc; /* Update the routing model in internal data structures */ @@ -149,7 +149,7 @@ int disable_intr_rm_local(uint32_t type, uint32_t security_state) { uint32_t bit_pos, flag; - assert(intr_type_descs[type].handler); + assert(intr_type_descs[type].handler != NULL); flag = get_interrupt_rm_flag(INTR_DEFAULT_RM, security_state); @@ -167,7 +167,7 @@ int enable_intr_rm_local(uint32_t type, uint32_t security_state) { uint32_t bit_pos, flag; - assert(intr_type_descs[type].handler); + assert(intr_type_descs[type].handler != NULL); flag = get_interrupt_rm_flag(intr_type_descs[type].flags, security_state); @@ -190,19 +190,19 @@ int32_t register_interrupt_type_handler(uint32_t type, int32_t rc; /* Validate the 'handler' parameter */ - if (!handler) + if (handler == NULL) return -EINVAL; /* Validate the 'flags' parameter */ - if (flags & INTR_TYPE_FLAGS_MASK) + if ((flags & INTR_TYPE_FLAGS_MASK) != 0U) return -EINVAL; /* Check if a handler has already been registered */ - if (intr_type_descs[type].handler) + if (intr_type_descs[type].handler != NULL) return -EALREADY; rc = set_routing_model(type, flags); - if (rc) + if (rc != 0) return rc; /* Save the handler */ @@ -218,7 +218,7 @@ int32_t register_interrupt_type_handler(uint32_t type, ******************************************************************************/ interrupt_type_handler_t get_interrupt_type_handler(uint32_t type) { - if (validate_interrupt_type(type)) + if (validate_interrupt_type(type) != 0) return NULL; return intr_type_descs[type].handler; diff --git a/common/backtrace.c b/common/backtrace.c new file mode 100644 index 00000000..a91d0657 --- /dev/null +++ b/common/backtrace.c @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch_helpers.h> +#include <assert.h> +#include <console.h> +#include <debug.h> +#include <stdbool.h> +#include <stdint.h> + +/* Maximum number of entries in the backtrace to display */ +#define UNWIND_LIMIT 20U + +/* + * If -fno-omit-frame-pointer is used: + * + * - AArch64: The AAPCS defines the format of the frame records and mandates the + * usage of r29 as frame pointer. + * + * - AArch32: The format of the frame records is not defined in the AAPCS. + * However, at least GCC and Clang use the same format. When they are forced + * to only generate A32 code (with -marm), they use r11 as frame pointer and a + * similar format as in AArch64. If interworking with T32 is enabled, the + * frame pointer is r7 and the format is different. This is not supported by + * this implementation of backtrace, so it is needed to use -marm. + */ + +/* Frame records form a linked list in the stack */ +struct frame_record { + /* Previous frame record in the list */ + struct frame_record *parent; + /* Return address of the function at this level */ + uintptr_t return_addr; +}; + +static const char *get_el_str(unsigned int el) +{ + if (el == 3U) { + return "EL3"; + } else if (el == 2U) { + return "EL2"; + } else { + return "S-EL1"; + } +} + +/* + * Returns true if the address points to a virtual address that can be read at + * the current EL, false otherwise. + */ +#ifdef AARCH64 +static bool is_address_readable(uintptr_t addr) +{ + unsigned int el = get_current_el(); + + if (el == 3U) { + ats1e3r(addr); + } else if (el == 2U) { + ats1e2r(addr); + } else { + ats1e1r(addr); + } + + isb(); + + /* If PAR.F == 1 the address translation was aborted. */ + if ((read_par_el1() & PAR_F_MASK) != 0U) + return false; + + return true; +} +#else /* if AARCH32 */ +static bool is_address_readable(uintptr_t addr) +{ + unsigned int el = get_current_el(); + + if (el == 3U) { + write_ats1cpr(addr); + } else if (el == 2U) { + write_ats1hr(addr); + } else { + write_ats1cpr(addr); + } + + isb(); + + /* If PAR.F == 1 the address translation was aborted. */ + if ((read64_par() & PAR_F_MASK) != 0U) + return false; + + return true; +} +#endif + +/* + * Returns true if all the bytes in a given object are in mapped memory and an + * LDR using this pointer would succeed, false otherwise. + */ +static bool is_valid_object(uintptr_t addr, size_t size) +{ + assert(size > 0U); + + if (addr == 0U) + return false; + + /* Detect overflows */ + if ((addr + size) < addr) + return false; + + /* A pointer not aligned properly could trigger an alignment fault. */ + if ((addr & (sizeof(uintptr_t) - 1U)) != 0U) + return false; + + /* Check that all the object is readable */ + for (size_t i = 0; i < size; i++) { + if (!is_address_readable(addr + i)) + return false; + } + + return true; +} + +/* + * Returns true if the specified address is correctly aligned and points to a + * valid memory region. + */ +static bool is_valid_jump_address(uintptr_t addr) +{ + if (addr == 0U) + return false; + + /* Check alignment. Both A64 and A32 use 32-bit opcodes */ + if ((addr & (sizeof(uint32_t) - 1U)) != 0U) + return false; + + if (!is_address_readable(addr)) + return false; + + return true; +} + +/* + * Returns true if the pointer points at a valid frame record, false otherwise. + */ +static bool is_valid_frame_record(struct frame_record *fr) +{ + return is_valid_object((uintptr_t)fr, sizeof(struct frame_record)); +} + +/* + * Adjust the frame-pointer-register value by 4 bytes on AArch32 to have the + * same layout as AArch64. + */ +static struct frame_record *adjust_frame_record(struct frame_record *fr) +{ +#ifdef AARCH64 + return fr; +#else + return (struct frame_record *)((uintptr_t)fr - 4U); +#endif +} + +static void unwind_stack(struct frame_record *fr, uintptr_t current_pc, + uintptr_t link_register) +{ + uintptr_t call_site; + static const char *backtrace_str = "%u: %s: 0x%lx\n"; + const char *el_str = get_el_str(get_current_el()); + + if (!is_valid_frame_record(fr)) { + printf("ERROR: Corrupted frame pointer (frame record address = %p)\n", + fr); + return; + } + + if (fr->return_addr != link_register) { + printf("ERROR: Corrupted stack (frame record address = %p)\n", + fr); + return; + } + + /* The level 0 of the backtrace is the current backtrace function */ + printf(backtrace_str, 0U, el_str, current_pc); + + /* + * The last frame record pointer in the linked list at the beginning of + * the stack should be NULL unless stack is corrupted. + */ + for (unsigned int i = 1U; i < UNWIND_LIMIT; i++) { + /* If an invalid frame record is found, exit. */ + if (!is_valid_frame_record(fr)) + return; + /* + * A32 and A64 are fixed length so the address from where the + * call was made is the instruction before the return address, + * which is always 4 bytes before it. + */ + call_site = fr->return_addr - 4U; + + /* + * If the address is invalid it means that the frame record is + * probably corrupted. + */ + if (!is_valid_jump_address(call_site)) + return; + + printf(backtrace_str, i, el_str, call_site); + + fr = adjust_frame_record(fr->parent); + } + + printf("ERROR: Max backtrace depth reached\n"); +} + +/* + * Display a backtrace. The cookie string parameter is displayed along the + * trace to help filter the log messages. + * + * Many things can prevent displaying the expected backtrace. For example, + * compiler optimizations can use a branch instead of branch with link when it + * detects a tail call. The backtrace level for this caller will not be + * displayed, as it does not appear in the call stack anymore. Also, assembly + * functions will not be displayed unless they setup AAPCS compliant frame + * records on AArch64 and compliant with GCC-specific frame record format on + * AArch32. + * + * Usage of the trace: addr2line can be used to map the addresses to function + * and source code location when given the ELF file compiled with debug + * information. The "-i" flag is highly recommended to improve display of + * inlined function. The *.dump files generated when buildidng each image can + * also be used. + * + * WARNING: In case of corrupted stack, this function could display security + * sensitive information past the beginning of the stack so it must not be used + * in production build. This function is only compiled in when ENABLE_BACKTRACE + * is set to 1. + */ +void backtrace(const char *cookie) +{ + uintptr_t return_address = (uintptr_t)__builtin_return_address(0U); + struct frame_record *fr = __builtin_frame_address(0U); + + /* Printing the backtrace may crash the system, flush before starting */ + (void)console_flush(); + + fr = adjust_frame_record(fr); + + printf("BACKTRACE: START: %s\n", cookie); + + unwind_stack(fr, (uintptr_t)&backtrace, return_address); + + printf("BACKTRACE: END: %s\n", cookie); +} diff --git a/common/runtime_svc.c b/common/runtime_svc.c index f997c74a..ad564f56 100644 --- a/common/runtime_svc.c +++ b/common/runtime_svc.c @@ -20,7 +20,6 @@ * 'rt_svc_descs' array which contains the SMC handler. ******************************************************************************/ uint8_t rt_svc_descs_indices[MAX_RT_SVCS]; -static rt_svc_desc_t *rt_svc_descs; #define RT_SVC_DECS_NUM ((RT_SVC_DESCS_END - RT_SVC_DESCS_START)\ / sizeof(rt_svc_desc_t)) @@ -98,6 +97,7 @@ void runtime_svc_init(void) { int rc = 0; unsigned int index, start_idx, end_idx; + rt_svc_desc_t *rt_svc_descs; /* Assert the number of descriptors detected are less than maximum indices */ assert((RT_SVC_DESCS_END >= RT_SVC_DESCS_START) && diff --git a/common/tf_log.c b/common/tf_log.c index 6da1e85b..422959f6 100644 --- a/common/tf_log.c +++ b/common/tf_log.c @@ -28,19 +28,21 @@ void tf_log(const char *fmt, ...) log_level = fmt[0]; /* Verify that log_level is one of LOG_MARKER_* macro defined in debug.h */ - assert(log_level && log_level <= LOG_LEVEL_VERBOSE); - assert(log_level % 10 == 0); + assert((log_level > 0U) && (log_level <= LOG_LEVEL_VERBOSE)); + assert((log_level % 10U) == 0U); if (log_level > max_log_level) return; prefix_str = plat_log_get_prefix(log_level); - while (*prefix_str) - putchar(*prefix_str++); + while (*prefix_str != '\0') { + (void)putchar(*prefix_str); + prefix_str++; + } va_start(args, fmt); - vprintf(fmt + 1, args); + (void)vprintf(fmt + 1, args); va_end(args); } @@ -52,10 +54,9 @@ void tf_log(const char *fmt, ...) void tf_log_set_max_level(unsigned int log_level) { assert(log_level <= LOG_LEVEL_VERBOSE); - assert((log_level % 10) == 0); + assert((log_level % 10U) == 0U); /* Cap log_level to the compile time maximum. */ - if (log_level < LOG_LEVEL) + if (log_level < (unsigned int)LOG_LEVEL) max_log_level = log_level; - } diff --git a/docs/user-guide.rst b/docs/user-guide.rst index 3f8170fd..b8bb4a19 100644 --- a/docs/user-guide.rst +++ b/docs/user-guide.rst @@ -75,7 +75,7 @@ In addition, the following optional packages and tools may be needed: - To create and modify the diagram files included in the documentation, `Dia`_. This tool can be found in most Linux distributions. Inkscape is needed to - generate the actual *.png files. + generate the actual \*.png files. Getting the TF-A source code ---------------------------- @@ -212,6 +212,10 @@ performed. Common build options ^^^^^^^^^^^^^^^^^^^^ +- ``AARCH32_INSTRUCTION_SET``: Choose the AArch32 instruction set that the + compiler should use. Valid values are T32 and A32. It defaults to T32 due to + code having a smaller resulting size. + - ``AARCH32_SP`` : Choose the AArch32 Secure Payload component to be built as as the BL32 image when ``ARCH=aarch32``. The value should be the path to the directory containing the SP source, relative to the ``bl32/``; the directory @@ -351,6 +355,16 @@ Common build options that is only required for the assertion and does not fit in the assertion itself. +- ``ENABLE_BACKTRACE``: This option controls whether to enables backtrace + dumps or not. It is supported in both AArch64 and AArch32. However, in + AArch32 the format of the frame records are not defined in the AAPCS and they + are defined by the implementation. This implementation of backtrace only + supports the format used by GCC when T32 interworking is disabled. For this + reason enabling this option in AArch32 will force the compiler to only + generate A32 code. This option is enabled by default only in AArch64 debug + builds, but this behaviour can be overriden in each platform's Makefile or in + the build command line. + - ``ENABLE_MPAM_FOR_LOWER_ELS``: Boolean option to enable lower ELs to use MPAM feature. MPAM is an optional Armv8.4 extension that enables various memory system components and resources to define partitions; software running at @@ -457,8 +471,10 @@ Common build options .. __: `platform-interrupt-controller-API.rst` .. __: `interrupt-framework-design.rst` -- ``HANDLE_EA_EL3_FIRST``: When defined External Aborts and SError Interrupts - will be always trapped in EL3 i.e. in BL31 at runtime. +- ``HANDLE_EA_EL3_FIRST``: When set to ``1``, External Aborts and SError + Interrupts will be always trapped in EL3 i.e. in BL31 at runtime. When set to + ``0`` (default), these exceptions will be trapped in the current exception + level (or in EL1 if the current exception level is EL0). - ``HW_ASSISTED_COHERENCY``: On most Arm systems to-date, platform-specific software operations are required for CPUs to enter and exit coherency. diff --git a/drivers/arm/cci/cci.c b/drivers/arm/cci/cci.c index a6ee77a5..91245d46 100644 --- a/drivers/arm/cci/cci.c +++ b/drivers/arm/cci/cci.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,11 +10,12 @@ #include <cci.h> #include <debug.h> #include <mmio.h> +#include <stdbool.h> #include <stdint.h> -#define MAKE_CCI_PART_NUMBER(hi, lo) ((hi << 8) | lo) -#define CCI_PART_LO_MASK 0xff -#define CCI_PART_HI_MASK 0xf +#define MAKE_CCI_PART_NUMBER(hi, lo) (((hi) << 8) | (lo)) +#define CCI_PART_LO_MASK U(0xff) +#define CCI_PART_HI_MASK U(0xf) /* CCI part number codes read from Peripheral ID registers 0 and 1 */ #define CCI400_PART_NUM 0x420 @@ -32,14 +33,14 @@ static const int *cci_slave_if_map; static unsigned int max_master_id; static int cci_num_slave_ports; -static int validate_cci_map(const int *map) +static bool validate_cci_map(const int *map) { - unsigned int valid_cci_map = 0; + unsigned int valid_cci_map = 0U; int slave_if_id; - int i; + unsigned int i; /* Validate the map */ - for (i = 0; i <= max_master_id; i++) { + for (i = 0U; i <= max_master_id; i++) { slave_if_id = map[i]; if (slave_if_id < 0) @@ -47,22 +48,22 @@ static int validate_cci_map(const int *map) if (slave_if_id >= cci_num_slave_ports) { ERROR("Slave interface ID is invalid\n"); - return 0; + return false; } - if (valid_cci_map & (1 << slave_if_id)) { + if ((valid_cci_map & (1U << slave_if_id)) != 0U) { ERROR("Multiple masters are assigned same slave interface ID\n"); - return 0; + return false; } - valid_cci_map |= 1 << slave_if_id; + valid_cci_map |= 1U << slave_if_id; } - if (!valid_cci_map) { + if (valid_cci_map == 0U) { ERROR("No master is assigned a valid slave interface\n"); - return 0; + return false; } - return 1; + return true; } /* @@ -108,8 +109,8 @@ static int get_slave_ports(unsigned int part_num) void cci_init(uintptr_t base, const int *map, unsigned int num_cci_masters) { - assert(map); - assert(base); + assert(map != NULL); + assert(base != 0U); cci_base = base; cci_slave_if_map = map; @@ -119,7 +120,7 @@ void cci_init(uintptr_t base, const int *map, unsigned int num_cci_masters) * Master Id's are assigned from zero, So in an array of size n * the max master id is (n - 1). */ - max_master_id = num_cci_masters - 1; + max_master_id = num_cci_masters - 1U; cci_num_slave_ports = get_slave_ports(read_cci_part_number(base)); #endif assert(cci_num_slave_ports >= 0); @@ -133,7 +134,7 @@ void cci_enable_snoop_dvm_reqs(unsigned int master_id) assert(master_id <= max_master_id); assert((slave_if_id < cci_num_slave_ports) && (slave_if_id >= 0)); - assert(cci_base); + assert(cci_base != 0U); /* * Enable Snoops and DVM messages, no need for Read/Modify/Write as @@ -150,7 +151,7 @@ void cci_enable_snoop_dvm_reqs(unsigned int master_id) dsbish(); /* Wait for the dust to settle down */ - while (mmio_read_32(cci_base + STATUS_REG) & CHANGE_PENDING_BIT) + while ((mmio_read_32(cci_base + STATUS_REG) & CHANGE_PENDING_BIT) != 0U) ; } @@ -160,7 +161,7 @@ void cci_disable_snoop_dvm_reqs(unsigned int master_id) assert(master_id <= max_master_id); assert((slave_if_id < cci_num_slave_ports) && (slave_if_id >= 0)); - assert(cci_base); + assert(cci_base != 0U); /* * Disable Snoops and DVM messages, no need for Read/Modify/Write as @@ -177,7 +178,7 @@ void cci_disable_snoop_dvm_reqs(unsigned int master_id) dsbish(); /* Wait for the dust to settle down */ - while (mmio_read_32(cci_base + STATUS_REG) & CHANGE_PENDING_BIT) + while ((mmio_read_32(cci_base + STATUS_REG) & CHANGE_PENDING_BIT) != 0U) ; } diff --git a/drivers/arm/gic/common/gic_common.c b/drivers/arm/gic/common/gic_common.c index 07ed63d7..589de5da 100644 --- a/drivers/arm/gic/common/gic_common.c +++ b/drivers/arm/gic/common/gic_common.c @@ -18,7 +18,8 @@ */ unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id) { - unsigned n = id >> IGROUPR_SHIFT; + unsigned int n = id >> IGROUPR_SHIFT; + return mmio_read_32(base + GICD_IGROUPR + (n << 2)); } @@ -28,7 +29,8 @@ unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id) */ unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id) { - unsigned n = id >> ISENABLER_SHIFT; + unsigned int n = id >> ISENABLER_SHIFT; + return mmio_read_32(base + GICD_ISENABLER + (n << 2)); } @@ -38,7 +40,8 @@ unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id) */ unsigned int gicd_read_icenabler(uintptr_t base, unsigned int id) { - unsigned n = id >> ICENABLER_SHIFT; + unsigned int n = id >> ICENABLER_SHIFT; + return mmio_read_32(base + GICD_ICENABLER + (n << 2)); } @@ -48,7 +51,8 @@ unsigned int gicd_read_icenabler(uintptr_t base, unsigned int id) */ unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id) { - unsigned n = id >> ISPENDR_SHIFT; + unsigned int n = id >> ISPENDR_SHIFT; + return mmio_read_32(base + GICD_ISPENDR + (n << 2)); } @@ -58,7 +62,8 @@ unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id) */ unsigned int gicd_read_icpendr(uintptr_t base, unsigned int id) { - unsigned n = id >> ICPENDR_SHIFT; + unsigned int n = id >> ICPENDR_SHIFT; + return mmio_read_32(base + GICD_ICPENDR + (n << 2)); } @@ -68,7 +73,8 @@ unsigned int gicd_read_icpendr(uintptr_t base, unsigned int id) */ unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id) { - unsigned n = id >> ISACTIVER_SHIFT; + unsigned int n = id >> ISACTIVER_SHIFT; + return mmio_read_32(base + GICD_ISACTIVER + (n << 2)); } @@ -78,7 +84,8 @@ unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id) */ unsigned int gicd_read_icactiver(uintptr_t base, unsigned int id) { - unsigned n = id >> ICACTIVER_SHIFT; + unsigned int n = id >> ICACTIVER_SHIFT; + return mmio_read_32(base + GICD_ICACTIVER + (n << 2)); } @@ -88,7 +95,8 @@ unsigned int gicd_read_icactiver(uintptr_t base, unsigned int id) */ unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id) { - unsigned n = id >> IPRIORITYR_SHIFT; + unsigned int n = id >> IPRIORITYR_SHIFT; + return mmio_read_32(base + GICD_IPRIORITYR + (n << 2)); } @@ -98,7 +106,8 @@ unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id) */ unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id) { - unsigned n = id >> ICFGR_SHIFT; + unsigned int n = id >> ICFGR_SHIFT; + return mmio_read_32(base + GICD_ICFGR + (n << 2)); } @@ -108,7 +117,8 @@ unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id) */ unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id) { - unsigned n = id >> NSACR_SHIFT; + unsigned int n = id >> NSACR_SHIFT; + return mmio_read_32(base + GICD_NSACR + (n << 2)); } @@ -121,7 +131,8 @@ unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id) */ void gicd_write_igroupr(uintptr_t base, unsigned int id, unsigned int val) { - unsigned n = id >> IGROUPR_SHIFT; + unsigned int n = id >> IGROUPR_SHIFT; + mmio_write_32(base + GICD_IGROUPR + (n << 2), val); } @@ -131,7 +142,8 @@ void gicd_write_igroupr(uintptr_t base, unsigned int id, unsigned int val) */ void gicd_write_isenabler(uintptr_t base, unsigned int id, unsigned int val) { - unsigned n = id >> ISENABLER_SHIFT; + unsigned int n = id >> ISENABLER_SHIFT; + mmio_write_32(base + GICD_ISENABLER + (n << 2), val); } @@ -141,7 +153,8 @@ void gicd_write_isenabler(uintptr_t base, unsigned int id, unsigned int val) */ void gicd_write_icenabler(uintptr_t base, unsigned int id, unsigned int val) { - unsigned n = id >> ICENABLER_SHIFT; + unsigned int n = id >> ICENABLER_SHIFT; + mmio_write_32(base + GICD_ICENABLER + (n << 2), val); } @@ -151,7 +164,8 @@ void gicd_write_icenabler(uintptr_t base, unsigned int id, unsigned int val) */ void gicd_write_ispendr(uintptr_t base, unsigned int id, unsigned int val) { - unsigned n = id >> ISPENDR_SHIFT; + unsigned int n = id >> ISPENDR_SHIFT; + mmio_write_32(base + GICD_ISPENDR + (n << 2), val); } @@ -161,7 +175,8 @@ void gicd_write_ispendr(uintptr_t base, unsigned int id, unsigned int val) */ void gicd_write_icpendr(uintptr_t base, unsigned int id, unsigned int val) { - unsigned n = id >> ICPENDR_SHIFT; + unsigned int n = id >> ICPENDR_SHIFT; + mmio_write_32(base + GICD_ICPENDR + (n << 2), val); } @@ -171,7 +186,8 @@ void gicd_write_icpendr(uintptr_t base, unsigned int id, unsigned int val) */ void gicd_write_isactiver(uintptr_t base, unsigned int id, unsigned int val) { - unsigned n = id >> ISACTIVER_SHIFT; + unsigned int n = id >> ISACTIVER_SHIFT; + mmio_write_32(base + GICD_ISACTIVER + (n << 2), val); } @@ -181,7 +197,8 @@ void gicd_write_isactiver(uintptr_t base, unsigned int id, unsigned int val) */ void gicd_write_icactiver(uintptr_t base, unsigned int id, unsigned int val) { - unsigned n = id >> ICACTIVER_SHIFT; + unsigned int n = id >> ICACTIVER_SHIFT; + mmio_write_32(base + GICD_ICACTIVER + (n << 2), val); } @@ -191,7 +208,8 @@ void gicd_write_icactiver(uintptr_t base, unsigned int id, unsigned int val) */ void gicd_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) { - unsigned n = id >> IPRIORITYR_SHIFT; + unsigned int n = id >> IPRIORITYR_SHIFT; + mmio_write_32(base + GICD_IPRIORITYR + (n << 2), val); } @@ -201,7 +219,8 @@ void gicd_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) */ void gicd_write_icfgr(uintptr_t base, unsigned int id, unsigned int val) { - unsigned n = id >> ICFGR_SHIFT; + unsigned int n = id >> ICFGR_SHIFT; + mmio_write_32(base + GICD_ICFGR + (n << 2), val); } @@ -211,7 +230,8 @@ void gicd_write_icfgr(uintptr_t base, unsigned int id, unsigned int val) */ void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val) { - unsigned n = id >> NSACR_SHIFT; + unsigned int n = id >> NSACR_SHIFT; + mmio_write_32(base + GICD_NSACR + (n << 2), val); } @@ -223,87 +243,89 @@ void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val) ******************************************************************************/ unsigned int gicd_get_igroupr(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); + unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); unsigned int reg_val = gicd_read_igroupr(base, id); - return (reg_val >> bit_num) & 0x1; + return (reg_val >> bit_num) & 0x1U; } void gicd_set_igroupr(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); + unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); unsigned int reg_val = gicd_read_igroupr(base, id); - gicd_write_igroupr(base, id, reg_val | (1 << bit_num)); + gicd_write_igroupr(base, id, reg_val | (1U << bit_num)); } void gicd_clr_igroupr(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); + unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); unsigned int reg_val = gicd_read_igroupr(base, id); - gicd_write_igroupr(base, id, reg_val & ~(1 << bit_num)); + gicd_write_igroupr(base, id, reg_val & ~(1U << bit_num)); } void gicd_set_isenabler(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << ISENABLER_SHIFT) - 1); + unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U); - gicd_write_isenabler(base, id, (1 << bit_num)); + gicd_write_isenabler(base, id, (1U << bit_num)); } void gicd_set_icenabler(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << ICENABLER_SHIFT) - 1); + unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U); - gicd_write_icenabler(base, id, (1 << bit_num)); + gicd_write_icenabler(base, id, (1U << bit_num)); } void gicd_set_ispendr(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << ISPENDR_SHIFT) - 1); + unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U); - gicd_write_ispendr(base, id, (1 << bit_num)); + gicd_write_ispendr(base, id, (1U << bit_num)); } void gicd_set_icpendr(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << ICPENDR_SHIFT) - 1); + unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U); - gicd_write_icpendr(base, id, (1 << bit_num)); + gicd_write_icpendr(base, id, (1U << bit_num)); } unsigned int gicd_get_isactiver(uintptr_t base, unsigned int id) { - unsigned int bit_num = id & ((1 << ISACTIVER_SHIFT) - 1); + unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U); unsigned int reg_val = gicd_read_isactiver(base, id); - return (reg_val >> bit_num) & 0x1; + return (reg_val >> bit_num) & 0x1U; } void gicd_set_isactiver(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << ISACTIVER_SHIFT) - 1); + unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U); - gicd_write_isactiver(base, id, (1 << bit_num)); + gicd_write_isactiver(base, id, (1U << bit_num)); } void gicd_set_icactiver(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << ICACTIVER_SHIFT) - 1); + unsigned int bit_num = id & ((1U << ICACTIVER_SHIFT) - 1U); - gicd_write_icactiver(base, id, (1 << bit_num)); + gicd_write_icactiver(base, id, (1U << bit_num)); } void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) { - mmio_write_8(base + GICD_IPRIORITYR + id, pri & GIC_PRI_MASK); + uint8_t val = pri & GIC_PRI_MASK; + + mmio_write_8(base + GICD_IPRIORITYR + id, val); } void gicd_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg) { /* Interrupt configuration is a 2-bit field */ - unsigned int bit_num = id & ((1 << ICFGR_SHIFT) - 1); + unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U); unsigned int bit_shift = bit_num << 1; uint32_t reg_val = gicd_read_icfgr(base, id); diff --git a/drivers/arm/gic/v2/gicv2_helpers.c b/drivers/arm/gic/v2/gicv2_helpers.c index 421669fc..221f1b53 100644 --- a/drivers/arm/gic/v2/gicv2_helpers.c +++ b/drivers/arm/gic/v2/gicv2_helpers.c @@ -94,24 +94,24 @@ void gicv2_spis_configure_defaults(uintptr_t gicd_base) num_ints = gicd_read_typer(gicd_base); num_ints &= TYPER_IT_LINES_NO_MASK; - num_ints = (num_ints + 1) << 5; + num_ints = (num_ints + 1U) << 5; /* * Treat all SPIs as G1NS by default. The number of interrupts is * calculated as 32 * (IT_LINES + 1). We do 32 at a time. */ - for (index = MIN_SPI_ID; index < num_ints; index += 32) + for (index = MIN_SPI_ID; index < num_ints; index += 32U) gicd_write_igroupr(gicd_base, index, ~0U); /* Setup the default SPI priorities doing four at a time */ - for (index = MIN_SPI_ID; index < num_ints; index += 4) + for (index = MIN_SPI_ID; index < num_ints; index += 4U) gicd_write_ipriorityr(gicd_base, index, GICD_IPRIORITYR_DEF_VAL); /* Treat all SPIs as level triggered by default, 16 at a time */ - for (index = MIN_SPI_ID; index < num_ints; index += 16) - gicd_write_icfgr(gicd_base, index, 0); + for (index = MIN_SPI_ID; index < num_ints; index += 16U) + gicd_write_icfgr(gicd_base, index, 0U); } #if !ERROR_DEPRECATED @@ -125,7 +125,8 @@ void gicv2_secure_spis_configure(uintptr_t gicd_base, unsigned int index, irq_num; /* If `num_ints` is not 0, ensure that `sec_intr_list` is not NULL */ - assert(num_ints ? (uintptr_t)sec_intr_list : 1); + if (num_ints != 0U) + assert(sec_intr_list != NULL); for (index = 0; index < num_ints; index++) { irq_num = sec_intr_list[index]; @@ -161,7 +162,8 @@ void gicv2_secure_spis_configure_props(uintptr_t gicd_base, const interrupt_prop_t *prop_desc; /* Make sure there's a valid property array */ - assert(interrupt_props_num != 0 ? (uintptr_t) interrupt_props : 1); + if (interrupt_props_num != 0U) + assert(interrupt_props != NULL); for (i = 0; i < interrupt_props_num; i++) { prop_desc = &interrupt_props[i]; @@ -252,20 +254,21 @@ void gicv2_secure_ppi_sgi_setup_props(uintptr_t gicd_base, const interrupt_prop_t *prop_desc; /* Make sure there's a valid property array */ - assert(interrupt_props_num != 0 ? (uintptr_t) interrupt_props : 1); + if (interrupt_props_num != 0U) + assert(interrupt_props != NULL); /* * Disable all SGIs (imp. def.)/PPIs before configuring them. This is a * more scalable approach as it avoids clearing the enable bits in the * GICD_CTLR. */ - gicd_write_icenabler(gicd_base, 0, ~0); + gicd_write_icenabler(gicd_base, 0U, ~0U); /* Setup the default PPI/SGI priorities doing four at a time */ - for (i = 0; i < MIN_SPI_ID; i += 4) + for (i = 0U; i < MIN_SPI_ID; i += 4U) gicd_write_ipriorityr(gicd_base, i, GICD_IPRIORITYR_DEF_VAL); - for (i = 0; i < interrupt_props_num; i++) { + for (i = 0U; i < interrupt_props_num; i++) { prop_desc = &interrupt_props[i]; if (prop_desc->intr_num >= MIN_SPI_ID) diff --git a/drivers/arm/gic/v2/gicv2_main.c b/drivers/arm/gic/v2/gicv2_main.c index 7cf6c76e..311e77e9 100644 --- a/drivers/arm/gic/v2/gicv2_main.c +++ b/drivers/arm/gic/v2/gicv2_main.c @@ -12,6 +12,8 @@ #include <gicv2.h> #include <interrupt_props.h> #include <spinlock.h> +#include <stdbool.h> + #include "../common/gic_common_private.h" #include "gicv2_private.h" @@ -32,8 +34,8 @@ void gicv2_cpuif_enable(void) { unsigned int val; - assert(driver_data); - assert(driver_data->gicc_base); + assert(driver_data != NULL); + assert(driver_data->gicc_base != 0U); /* * Enable the Group 0 interrupts, FIQEn and disable Group 0/1 @@ -55,8 +57,8 @@ void gicv2_cpuif_disable(void) { unsigned int val; - assert(driver_data); - assert(driver_data->gicc_base); + assert(driver_data != NULL); + assert(driver_data->gicc_base != 0U); /* Disable secure, non-secure interrupts and disable their bypass */ val = gicc_read_ctlr(driver_data->gicc_base); @@ -74,8 +76,8 @@ void gicv2_pcpu_distif_init(void) { unsigned int ctlr; - assert(driver_data); - assert(driver_data->gicd_base); + assert(driver_data != NULL); + assert(driver_data->gicd_base != 0U); #if !ERROR_DEPRECATED if (driver_data->interrupt_props != NULL) { @@ -101,7 +103,7 @@ void gicv2_pcpu_distif_init(void) /* Enable G0 interrupts if not already */ ctlr = gicd_read_ctlr(driver_data->gicd_base); - if ((ctlr & CTLR_ENABLE_G0_BIT) == 0) { + if ((ctlr & CTLR_ENABLE_G0_BIT) == 0U) { gicd_write_ctlr(driver_data->gicd_base, ctlr | CTLR_ENABLE_G0_BIT); } @@ -116,8 +118,8 @@ void gicv2_distif_init(void) { unsigned int ctlr; - assert(driver_data); - assert(driver_data->gicd_base); + assert(driver_data != NULL); + assert(driver_data->gicd_base != 0U); /* Disable the distributor before going further */ ctlr = gicd_read_ctlr(driver_data->gicd_base); @@ -162,9 +164,10 @@ void gicv2_distif_init(void) void gicv2_driver_init(const gicv2_driver_data_t *plat_driver_data) { unsigned int gic_version; - assert(plat_driver_data); - assert(plat_driver_data->gicd_base); - assert(plat_driver_data->gicc_base); + + assert(plat_driver_data != NULL); + assert(plat_driver_data->gicd_base != 0U); + assert(plat_driver_data->gicc_base != 0U); #if !ERROR_DEPRECATED if (plat_driver_data->interrupt_props == NULL) { @@ -212,7 +215,8 @@ void gicv2_driver_init(const gicv2_driver_data_t *plat_driver_data) * - interrupt priority drop. * - interrupt signal bypass. */ - assert(gic_version == ARCH_REV_GICV2 || gic_version == ARCH_REV_GICV1); + assert((gic_version == ARCH_REV_GICV2) || + (gic_version == ARCH_REV_GICV1)); driver_data = plat_driver_data; @@ -238,11 +242,11 @@ unsigned int gicv2_is_fiq_enabled(void) { unsigned int gicc_ctlr; - assert(driver_data); - assert(driver_data->gicc_base); + assert(driver_data != NULL); + assert(driver_data->gicc_base != 0U); gicc_ctlr = gicc_read_ctlr(driver_data->gicc_base); - return (gicc_ctlr >> FIQ_EN_SHIFT) & 0x1; + return (gicc_ctlr >> FIQ_EN_SHIFT) & 0x1U; } /******************************************************************************* @@ -255,8 +259,8 @@ unsigned int gicv2_is_fiq_enabled(void) ******************************************************************************/ unsigned int gicv2_get_pending_interrupt_type(void) { - assert(driver_data); - assert(driver_data->gicc_base); + assert(driver_data != NULL); + assert(driver_data->gicc_base != 0U); return gicc_read_hppir(driver_data->gicc_base) & INT_ID_MASK; } @@ -270,8 +274,8 @@ unsigned int gicv2_get_pending_interrupt_id(void) { unsigned int id; - assert(driver_data); - assert(driver_data->gicc_base); + assert(driver_data != NULL); + assert(driver_data->gicc_base != 0U); id = gicc_read_hppir(driver_data->gicc_base) & INT_ID_MASK; @@ -292,8 +296,8 @@ unsigned int gicv2_get_pending_interrupt_id(void) ******************************************************************************/ unsigned int gicv2_acknowledge_interrupt(void) { - assert(driver_data); - assert(driver_data->gicc_base); + assert(driver_data != NULL); + assert(driver_data->gicc_base != 0U); return gicc_read_IAR(driver_data->gicc_base); } @@ -304,8 +308,8 @@ unsigned int gicv2_acknowledge_interrupt(void) ******************************************************************************/ void gicv2_end_of_interrupt(unsigned int id) { - assert(driver_data); - assert(driver_data->gicc_base); + assert(driver_data != NULL); + assert(driver_data->gicc_base != 0U); gicc_write_EOIR(driver_data->gicc_base, id); } @@ -318,8 +322,8 @@ void gicv2_end_of_interrupt(unsigned int id) ******************************************************************************/ unsigned int gicv2_get_interrupt_group(unsigned int id) { - assert(driver_data); - assert(driver_data->gicd_base); + assert(driver_data != NULL); + assert(driver_data->gicd_base != 0U); return gicd_get_igroupr(driver_data->gicd_base, id); } @@ -330,8 +334,8 @@ unsigned int gicv2_get_interrupt_group(unsigned int id) ******************************************************************************/ unsigned int gicv2_get_running_priority(void) { - assert(driver_data); - assert(driver_data->gicc_base); + assert(driver_data != NULL); + assert(driver_data->gicc_base != 0U); return gicc_read_rpr(driver_data->gicc_base); } @@ -344,21 +348,21 @@ unsigned int gicv2_get_running_priority(void) ******************************************************************************/ void gicv2_set_pe_target_mask(unsigned int proc_num) { - assert(driver_data); - assert(driver_data->gicd_base); - assert(driver_data->target_masks); - assert(proc_num < GICV2_MAX_TARGET_PE); - assert(proc_num < driver_data->target_masks_num); + assert(driver_data != NULL); + assert(driver_data->gicd_base != 0U); + assert(driver_data->target_masks != NULL); + assert((unsigned int)proc_num < GICV2_MAX_TARGET_PE); + assert((unsigned int)proc_num < driver_data->target_masks_num); /* Return if the target mask is already populated */ - if (driver_data->target_masks[proc_num]) + if (driver_data->target_masks[proc_num] != 0U) return; /* * Update target register corresponding to this CPU and flush for it to * be visible to other CPUs. */ - if (driver_data->target_masks[proc_num] == 0) { + if (driver_data->target_masks[proc_num] == 0U) { driver_data->target_masks[proc_num] = gicv2_get_cpuif_id(driver_data->gicd_base); #if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY) @@ -382,8 +386,8 @@ void gicv2_set_pe_target_mask(unsigned int proc_num) ******************************************************************************/ unsigned int gicv2_get_interrupt_active(unsigned int id) { - assert(driver_data); - assert(driver_data->gicd_base); + assert(driver_data != NULL); + assert(driver_data->gicd_base != 0U); assert(id <= MAX_SPI_ID); return gicd_get_isactiver(driver_data->gicd_base, id); @@ -394,8 +398,8 @@ unsigned int gicv2_get_interrupt_active(unsigned int id) ******************************************************************************/ void gicv2_enable_interrupt(unsigned int id) { - assert(driver_data); - assert(driver_data->gicd_base); + assert(driver_data != NULL); + assert(driver_data->gicd_base != 0U); assert(id <= MAX_SPI_ID); /* @@ -411,8 +415,8 @@ void gicv2_enable_interrupt(unsigned int id) ******************************************************************************/ void gicv2_disable_interrupt(unsigned int id) { - assert(driver_data); - assert(driver_data->gicd_base); + assert(driver_data != NULL); + assert(driver_data->gicd_base != 0U); assert(id <= MAX_SPI_ID); /* @@ -429,8 +433,8 @@ void gicv2_disable_interrupt(unsigned int id) ******************************************************************************/ void gicv2_set_interrupt_priority(unsigned int id, unsigned int priority) { - assert(driver_data); - assert(driver_data->gicd_base); + assert(driver_data != NULL); + assert(driver_data->gicd_base != 0U); assert(id <= MAX_SPI_ID); gicd_set_ipriorityr(driver_data->gicd_base, id, priority); @@ -442,8 +446,8 @@ void gicv2_set_interrupt_priority(unsigned int id, unsigned int priority) ******************************************************************************/ void gicv2_set_interrupt_type(unsigned int id, unsigned int type) { - assert(driver_data); - assert(driver_data->gicd_base); + assert(driver_data != NULL); + assert(driver_data->gicd_base != 0U); assert(id <= MAX_SPI_ID); /* Serialize read-modify-write to Distributor registers */ @@ -456,7 +460,7 @@ void gicv2_set_interrupt_type(unsigned int id, unsigned int type) gicd_clr_igroupr(driver_data->gicd_base, id); break; default: - assert(0); + assert(false); break; } spin_unlock(&gic_lock); @@ -472,20 +476,20 @@ void gicv2_raise_sgi(int sgi_num, int proc_num) { unsigned int sgir_val, target; - assert(driver_data); - assert(proc_num < GICV2_MAX_TARGET_PE); - assert(driver_data->gicd_base); + assert(driver_data != NULL); + assert((unsigned int)proc_num < GICV2_MAX_TARGET_PE); + assert(driver_data->gicd_base != 0U); /* * Target masks array must have been supplied, and the core position * should be valid. */ - assert(driver_data->target_masks); - assert(proc_num < driver_data->target_masks_num); + assert(driver_data->target_masks != NULL); + assert((unsigned int)proc_num < driver_data->target_masks_num); /* Don't raise SGI if the mask hasn't been populated */ target = driver_data->target_masks[proc_num]; - assert(target != 0); + assert(target != 0U); sgir_val = GICV2_SGIR_VALUE(SGIR_TGT_SPECIFIC, target, sgi_num); @@ -505,20 +509,20 @@ void gicv2_raise_sgi(int sgi_num, int proc_num) ******************************************************************************/ void gicv2_set_spi_routing(unsigned int id, int proc_num) { - int target; + unsigned int target; - assert(driver_data); - assert(driver_data->gicd_base); + assert(driver_data != NULL); + assert(driver_data->gicd_base != 0U); - assert(id >= MIN_SPI_ID && id <= MAX_SPI_ID); + assert((id >= MIN_SPI_ID) && (id <= MAX_SPI_ID)); /* * Target masks array must have been supplied, and the core position * should be valid. */ - assert(driver_data->target_masks); - assert(proc_num < GICV2_MAX_TARGET_PE); - assert(proc_num < driver_data->target_masks_num); + assert(driver_data->target_masks != NULL); + assert((unsigned int)proc_num < GICV2_MAX_TARGET_PE); + assert((unsigned int)proc_num < driver_data->target_masks_num); if (proc_num < 0) { /* Target all PEs */ @@ -526,7 +530,7 @@ void gicv2_set_spi_routing(unsigned int id, int proc_num) } else { /* Don't route interrupt if the mask hasn't been populated */ target = driver_data->target_masks[proc_num]; - assert(target != 0); + assert(target != 0U); } gicd_set_itargetsr(driver_data->gicd_base, id, target); @@ -537,8 +541,8 @@ void gicv2_set_spi_routing(unsigned int id, int proc_num) ******************************************************************************/ void gicv2_clear_interrupt_pending(unsigned int id) { - assert(driver_data); - assert(driver_data->gicd_base); + assert(driver_data != NULL); + assert(driver_data->gicd_base != 0U); /* SGIs can't be cleared pending */ assert(id >= MIN_PPI_ID); @@ -556,8 +560,8 @@ void gicv2_clear_interrupt_pending(unsigned int id) ******************************************************************************/ void gicv2_set_interrupt_pending(unsigned int id) { - assert(driver_data); - assert(driver_data->gicd_base); + assert(driver_data != NULL); + assert(driver_data->gicd_base != 0U); /* SGIs can't be cleared pending */ assert(id >= MIN_PPI_ID); @@ -578,8 +582,8 @@ unsigned int gicv2_set_pmr(unsigned int mask) { unsigned int old_mask; - assert(driver_data); - assert(driver_data->gicc_base); + assert(driver_data != NULL); + assert(driver_data->gicc_base != 0U); old_mask = gicc_read_pmr(driver_data->gicc_base); diff --git a/drivers/arm/gic/v2/gicv2_private.h b/drivers/arm/gic/v2/gicv2_private.h index 25600deb..fadc9600 100644 --- a/drivers/arm/gic/v2/gicv2_private.h +++ b/drivers/arm/gic/v2/gicv2_private.h @@ -50,7 +50,9 @@ static inline unsigned int gicd_get_itargetsr(uintptr_t base, unsigned int id) static inline void gicd_set_itargetsr(uintptr_t base, unsigned int id, unsigned int target) { - mmio_write_8(base + GICD_ITARGETSR + id, target & GIC_TARGET_CPU_MASK); + uint8_t val = target & GIC_TARGET_CPU_MASK; + + mmio_write_8(base + GICD_ITARGETSR + id, val); } static inline void gicd_write_sgir(uintptr_t base, unsigned int val) diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c index 2ea8c727..1953a37b 100644 --- a/drivers/arm/gic/v3/gicv3_helpers.c +++ b/drivers/arm/gic/v3/gicv3_helpers.c @@ -19,7 +19,8 @@ */ unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id) { - unsigned n = id >> IGRPMODR_SHIFT; + unsigned int n = id >> IGRPMODR_SHIFT; + return mmio_read_32(base + GICD_IGRPMODR + (n << 2)); } @@ -29,7 +30,8 @@ unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id) */ void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val) { - unsigned n = id >> IGRPMODR_SHIFT; + unsigned int n = id >> IGRPMODR_SHIFT; + mmio_write_32(base + GICD_IGRPMODR + (n << 2), val); } @@ -39,10 +41,10 @@ void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val) */ unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1); + unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); unsigned int reg_val = gicd_read_igrpmodr(base, id); - return (reg_val >> bit_num) & 0x1; + return (reg_val >> bit_num) & 0x1U; } /* @@ -51,10 +53,10 @@ unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id) */ void gicd_set_igrpmodr(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1); + unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); unsigned int reg_val = gicd_read_igrpmodr(base, id); - gicd_write_igrpmodr(base, id, reg_val | (1 << bit_num)); + gicd_write_igrpmodr(base, id, reg_val | (1U << bit_num)); } /* @@ -63,10 +65,10 @@ void gicd_set_igrpmodr(uintptr_t base, unsigned int id) */ void gicd_clr_igrpmodr(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1); + unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); unsigned int reg_val = gicd_read_igrpmodr(base, id); - gicd_write_igrpmodr(base, id, reg_val & ~(1 << bit_num)); + gicd_write_igrpmodr(base, id, reg_val & ~(1U << bit_num)); } /* @@ -75,7 +77,8 @@ void gicd_clr_igrpmodr(uintptr_t base, unsigned int id) */ unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id) { - unsigned n = id >> IPRIORITYR_SHIFT; + unsigned int n = id >> IPRIORITYR_SHIFT; + return mmio_read_32(base + GICR_IPRIORITYR + (n << 2)); } @@ -85,7 +88,8 @@ unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id) */ void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) { - unsigned n = id >> IPRIORITYR_SHIFT; + unsigned int n = id >> IPRIORITYR_SHIFT; + mmio_write_32(base + GICR_IPRIORITYR + (n << 2), val); } @@ -95,10 +99,10 @@ void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) */ unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); + unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); unsigned int reg_val = gicr_read_igroupr0(base); - return (reg_val >> bit_num) & 0x1; + return (reg_val >> bit_num) & 0x1U; } /* @@ -107,10 +111,10 @@ unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id) */ void gicr_set_igroupr0(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); + unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); unsigned int reg_val = gicr_read_igroupr0(base); - gicr_write_igroupr0(base, reg_val | (1 << bit_num)); + gicr_write_igroupr0(base, reg_val | (1U << bit_num)); } /* @@ -119,10 +123,10 @@ void gicr_set_igroupr0(uintptr_t base, unsigned int id) */ void gicr_clr_igroupr0(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); + unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); unsigned int reg_val = gicr_read_igroupr0(base); - gicr_write_igroupr0(base, reg_val & ~(1 << bit_num)); + gicr_write_igroupr0(base, reg_val & ~(1U << bit_num)); } /* @@ -131,10 +135,10 @@ void gicr_clr_igroupr0(uintptr_t base, unsigned int id) */ unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1); + unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); unsigned int reg_val = gicr_read_igrpmodr0(base); - return (reg_val >> bit_num) & 0x1; + return (reg_val >> bit_num) & 0x1U; } /* @@ -143,10 +147,10 @@ unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id) */ void gicr_set_igrpmodr0(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1); + unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); unsigned int reg_val = gicr_read_igrpmodr0(base); - gicr_write_igrpmodr0(base, reg_val | (1 << bit_num)); + gicr_write_igrpmodr0(base, reg_val | (1U << bit_num)); } /* @@ -155,10 +159,10 @@ void gicr_set_igrpmodr0(uintptr_t base, unsigned int id) */ void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1); + unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); unsigned int reg_val = gicr_read_igrpmodr0(base); - gicr_write_igrpmodr0(base, reg_val & ~(1 << bit_num)); + gicr_write_igrpmodr0(base, reg_val & ~(1U << bit_num)); } /* @@ -167,9 +171,9 @@ void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id) */ void gicr_set_isenabler0(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << ISENABLER_SHIFT) - 1); + unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U); - gicr_write_isenabler0(base, (1 << bit_num)); + gicr_write_isenabler0(base, (1U << bit_num)); } /* @@ -178,9 +182,9 @@ void gicr_set_isenabler0(uintptr_t base, unsigned int id) */ void gicr_set_icenabler0(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << ICENABLER_SHIFT) - 1); + unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U); - gicr_write_icenabler0(base, (1 << bit_num)); + gicr_write_icenabler0(base, (1U << bit_num)); } /* @@ -189,10 +193,10 @@ void gicr_set_icenabler0(uintptr_t base, unsigned int id) */ unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << ISACTIVER_SHIFT) - 1); + unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U); unsigned int reg_val = gicr_read_isactiver0(base); - return (reg_val >> bit_num) & 0x1; + return (reg_val >> bit_num) & 0x1U; } /* @@ -201,9 +205,9 @@ unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id) */ void gicr_set_icpendr0(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << ICPENDR_SHIFT) - 1); + unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U); - gicr_write_icpendr0(base, (1 << bit_num)); + gicr_write_icpendr0(base, (1U << bit_num)); } /* @@ -212,9 +216,9 @@ void gicr_set_icpendr0(uintptr_t base, unsigned int id) */ void gicr_set_ispendr0(uintptr_t base, unsigned int id) { - unsigned bit_num = id & ((1 << ISPENDR_SHIFT) - 1); + unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U); - gicr_write_ispendr0(base, (1 << bit_num)); + gicr_write_ispendr0(base, (1U << bit_num)); } /* @@ -223,7 +227,9 @@ void gicr_set_ispendr0(uintptr_t base, unsigned int id) */ void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) { - mmio_write_8(base + GICR_IPRIORITYR + id, pri & GIC_PRI_MASK); + uint8_t val = pri & GIC_PRI_MASK; + + mmio_write_8(base + GICR_IPRIORITYR + id, val); } /* @@ -233,8 +239,8 @@ void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg) { /* Interrupt configuration is a 2-bit field */ - unsigned int bit_num = id & ((1 << ICFGR_SHIFT) - 1); - unsigned int bit_shift = bit_num << 1; + unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U); + unsigned int bit_shift = bit_num << 1U; uint32_t reg_val = gicr_read_icfgr0(base); @@ -252,8 +258,8 @@ void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg) void gicr_set_icfgr1(uintptr_t base, unsigned int id, unsigned int cfg) { /* Interrupt configuration is a 2-bit field */ - unsigned int bit_num = id & ((1 << ICFGR_SHIFT) - 1); - unsigned int bit_shift = bit_num << 1; + unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U); + unsigned int bit_shift = bit_num << 1U; uint32_t reg_val = gicr_read_icfgr1(base); @@ -274,13 +280,13 @@ void gicv3_rdistif_mark_core_awake(uintptr_t gicr_base) * The WAKER_PS_BIT should be changed to 0 * only when WAKER_CA_BIT is 1. */ - assert(gicr_read_waker(gicr_base) & WAKER_CA_BIT); + assert((gicr_read_waker(gicr_base) & WAKER_CA_BIT) != 0U); /* Mark the connected core as awake */ gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) & ~WAKER_PS_BIT); /* Wait till the WAKER_CA_BIT changes to 0 */ - while (gicr_read_waker(gicr_base) & WAKER_CA_BIT) + while ((gicr_read_waker(gicr_base) & WAKER_CA_BIT) != 0U) ; } @@ -295,7 +301,7 @@ void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base) gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) | WAKER_PS_BIT); /* Wait till the WAKER_CA_BIT changes to 1 */ - while (!(gicr_read_waker(gicr_base) & WAKER_CA_BIT)) + while ((gicr_read_waker(gicr_base) & WAKER_CA_BIT) == 0U) ; } @@ -312,10 +318,10 @@ void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs, { u_register_t mpidr; unsigned int proc_num; - unsigned long long typer_val; + uint64_t typer_val; uintptr_t rdistif_base = gicr_base; - assert(rdistif_base_addrs); + assert(rdistif_base_addrs != NULL); /* * Iterate over the Redistributor frames. Store the base address of each @@ -326,7 +332,7 @@ void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs, */ do { typer_val = gicr_read_typer(rdistif_base); - if (mpidr_to_core_pos) { + if (mpidr_to_core_pos != NULL) { mpidr = mpidr_from_gicr_typer(typer_val); proc_num = mpidr_to_core_pos(mpidr); } else { @@ -335,8 +341,8 @@ void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs, } assert(proc_num < rdistif_num); rdistif_base_addrs[proc_num] = rdistif_base; - rdistif_base += (1 << GICR_PCPUBASE_SHIFT); - } while (!(typer_val & TYPER_LAST_BIT)); + rdistif_base += (1U << GICR_PCPUBASE_SHIFT); + } while ((typer_val & TYPER_LAST_BIT) == 0U); } /******************************************************************************* @@ -348,17 +354,17 @@ void gicv3_spis_config_defaults(uintptr_t gicd_base) num_ints = gicd_read_typer(gicd_base); num_ints &= TYPER_IT_LINES_NO_MASK; - num_ints = (num_ints + 1) << 5; + num_ints = (num_ints + 1U) << 5; /* * Treat all SPIs as G1NS by default. The number of interrupts is * calculated as 32 * (IT_LINES + 1). We do 32 at a time. */ - for (index = MIN_SPI_ID; index < num_ints; index += 32) + for (index = MIN_SPI_ID; index < num_ints; index += 32U) gicd_write_igroupr(gicd_base, index, ~0U); /* Setup the default SPI priorities doing four at a time */ - for (index = MIN_SPI_ID; index < num_ints; index += 4) + for (index = MIN_SPI_ID; index < num_ints; index += 4U) gicd_write_ipriorityr(gicd_base, index, GICD_IPRIORITYR_DEF_VAL); @@ -367,8 +373,8 @@ void gicv3_spis_config_defaults(uintptr_t gicd_base) * Treat all SPIs as level triggered by default, write 16 at * a time */ - for (index = MIN_SPI_ID; index < num_ints; index += 16) - gicd_write_icfgr(gicd_base, index, 0); + for (index = MIN_SPI_ID; index < num_ints; index += 16U) + gicd_write_icfgr(gicd_base, index, 0U); } #if !ERROR_DEPRECATED @@ -385,9 +391,10 @@ void gicv3_secure_spis_config(uintptr_t gicd_base, assert((int_grp == INTR_GROUP1S) || (int_grp == INTR_GROUP0)); /* If `num_ints` is not 0, ensure that `sec_intr_list` is not NULL */ - assert(num_ints ? (uintptr_t)sec_intr_list : 1); + if (num_ints != 0U) + assert(sec_intr_list != NULL); - for (index = 0; index < num_ints; index++) { + for (index = 0U; index < num_ints; index++) { irq_num = sec_intr_list[index]; if (irq_num >= MIN_SPI_ID) { @@ -407,7 +414,7 @@ void gicv3_secure_spis_config(uintptr_t gicd_base, /* Target SPIs to the primary CPU */ gic_affinity_val = - gicd_irouter_val_from_mpidr(read_mpidr(), 0); + gicd_irouter_val_from_mpidr(read_mpidr(), 0U); gicd_write_irouter(gicd_base, irq_num, gic_affinity_val); @@ -430,12 +437,13 @@ unsigned int gicv3_secure_spis_config_props(uintptr_t gicd_base, unsigned int i; const interrupt_prop_t *current_prop; unsigned long long gic_affinity_val; - unsigned int ctlr_enable = 0; + unsigned int ctlr_enable = 0U; /* Make sure there's a valid property array */ - assert(interrupt_props_num > 0 ? interrupt_props != NULL : 1); + if (interrupt_props_num > 0U) + assert(interrupt_props != NULL); - for (i = 0; i < interrupt_props_num; i++) { + for (i = 0U; i < interrupt_props_num; i++) { current_prop = &interrupt_props[i]; if (current_prop->intr_num < MIN_SPI_ID) @@ -464,7 +472,8 @@ unsigned int gicv3_secure_spis_config_props(uintptr_t gicd_base, current_prop->intr_pri); /* Target SPIs to the primary CPU */ - gic_affinity_val = gicd_irouter_val_from_mpidr(read_mpidr(), 0); + gic_affinity_val = + gicd_irouter_val_from_mpidr(read_mpidr(), 0U); gicd_write_irouter(gicd_base, current_prop->intr_num, gic_affinity_val); @@ -487,20 +496,20 @@ void gicv3_ppi_sgi_config_defaults(uintptr_t gicr_base) * more scalable approach as it avoids clearing the enable bits in the * GICD_CTLR */ - gicr_write_icenabler0(gicr_base, ~0); + gicr_write_icenabler0(gicr_base, ~0U); gicr_wait_for_pending_write(gicr_base); /* Treat all SGIs/PPIs as G1NS by default. */ gicr_write_igroupr0(gicr_base, ~0U); /* Setup the default PPI/SGI priorities doing four at a time */ - for (index = 0; index < MIN_SPI_ID; index += 4) + for (index = 0U; index < MIN_SPI_ID; index += 4U) gicr_write_ipriorityr(gicr_base, index, GICD_IPRIORITYR_DEF_VAL); /* Configure all PPIs as level triggered by default */ - gicr_write_icfgr1(gicr_base, 0); + gicr_write_icfgr1(gicr_base, 0U); } #if !ERROR_DEPRECATED @@ -516,7 +525,8 @@ void gicv3_secure_ppi_sgi_config(uintptr_t gicr_base, assert((int_grp == INTR_GROUP1S) || (int_grp == INTR_GROUP0)); /* If `num_ints` is not 0, ensure that `sec_intr_list` is not NULL */ - assert(num_ints ? (uintptr_t)sec_intr_list : 1); + if (num_ints != 0U) + assert(sec_intr_list != NULL); for (index = 0; index < num_ints; index++) { irq_num = sec_intr_list[index]; @@ -552,12 +562,13 @@ unsigned int gicv3_secure_ppi_sgi_config_props(uintptr_t gicr_base, { unsigned int i; const interrupt_prop_t *current_prop; - unsigned int ctlr_enable = 0; + unsigned int ctlr_enable = 0U; /* Make sure there's a valid property array */ - assert(interrupt_props_num > 0 ? interrupt_props != NULL : 1); + if (interrupt_props_num > 0U) + assert(interrupt_props != NULL); - for (i = 0; i < interrupt_props_num; i++) { + for (i = 0U; i < interrupt_props_num; i++) { current_prop = &interrupt_props[i]; if (current_prop->intr_num >= MIN_SPI_ID) diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c index 40d14aba..d764eb28 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -34,21 +34,21 @@ static spinlock_t gic_lock; /* Helper macros to save and restore GICD registers to and from the context */ #define RESTORE_GICD_REGS(base, ctx, intr_num, reg, REG) \ do { \ - for (unsigned int int_id = MIN_SPI_ID; int_id < intr_num; \ - int_id += (1 << REG##_SHIFT)) { \ + for (unsigned int int_id = MIN_SPI_ID; int_id < (intr_num); \ + int_id += (1U << REG##_SHIFT)) { \ gicd_write_##reg(base, int_id, \ ctx->gicd_##reg[(int_id - MIN_SPI_ID) >> REG##_SHIFT]); \ } \ - } while (0) + } while (false) #define SAVE_GICD_REGS(base, ctx, intr_num, reg, REG) \ do { \ - for (unsigned int int_id = MIN_SPI_ID; int_id < intr_num; \ - int_id += (1 << REG##_SHIFT)) { \ + for (unsigned int int_id = MIN_SPI_ID; int_id < (intr_num); \ + int_id += (1U << REG##_SHIFT)) { \ ctx->gicd_##reg[(int_id - MIN_SPI_ID) >> REG##_SHIFT] =\ gicd_read_##reg(base, int_id); \ } \ - } while (0) + } while (false) /******************************************************************************* @@ -59,11 +59,11 @@ void gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data) { unsigned int gic_version; - assert(plat_driver_data); - assert(plat_driver_data->gicd_base); - assert(plat_driver_data->gicr_base); - assert(plat_driver_data->rdistif_num); - assert(plat_driver_data->rdistif_base_addrs); + assert(plat_driver_data != NULL); + assert(plat_driver_data->gicd_base != 0U); + assert(plat_driver_data->gicr_base != 0U); + assert(plat_driver_data->rdistif_num != 0U); + assert(plat_driver_data->rdistif_base_addrs != NULL); assert(IS_IN_EL3()); @@ -109,10 +109,10 @@ void gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data) /* Check for system register support */ #ifdef AARCH32 - assert(read_id_pfr1() & (ID_PFR1_GIC_MASK << ID_PFR1_GIC_SHIFT)); + assert((read_id_pfr1() & (ID_PFR1_GIC_MASK << ID_PFR1_GIC_SHIFT)) != 0U); #else - assert(read_id_aa64pfr0_el1() & - (ID_AA64PFR0_GIC_MASK << ID_AA64PFR0_GIC_SHIFT)); + assert((read_id_aa64pfr0_el1() & + (ID_AA64PFR0_GIC_MASK << ID_AA64PFR0_GIC_SHIFT)) != 0U); #endif /* AARCH32 */ /* The GIC version should be 3.0 */ @@ -170,8 +170,8 @@ void gicv3_distif_init(void) { unsigned int bitmap = 0; - assert(gicv3_driver_data); - assert(gicv3_driver_data->gicd_base); + assert(gicv3_driver_data != NULL); + assert(gicv3_driver_data->gicd_base != 0U); assert(IS_IN_EL3()); @@ -245,16 +245,16 @@ void gicv3_distif_init(void) void gicv3_rdistif_init(unsigned int proc_num) { uintptr_t gicr_base; - unsigned int bitmap = 0; + unsigned int bitmap = 0U; uint32_t ctlr; - assert(gicv3_driver_data); + assert(gicv3_driver_data != NULL); assert(proc_num < gicv3_driver_data->rdistif_num); - assert(gicv3_driver_data->rdistif_base_addrs); - assert(gicv3_driver_data->gicd_base); + assert(gicv3_driver_data->rdistif_base_addrs != NULL); + assert(gicv3_driver_data->gicd_base != 0U); ctlr = gicd_read_ctlr(gicv3_driver_data->gicd_base); - assert(ctlr & CTLR_ARE_S_BIT); + assert((ctlr & CTLR_ARE_S_BIT) != 0U); assert(IS_IN_EL3()); @@ -333,9 +333,9 @@ void gicv3_cpuif_enable(unsigned int proc_num) unsigned int scr_el3; unsigned int icc_sre_el3; - assert(gicv3_driver_data); + assert(gicv3_driver_data != NULL); assert(proc_num < gicv3_driver_data->rdistif_num); - assert(gicv3_driver_data->rdistif_base_addrs); + assert(gicv3_driver_data->rdistif_base_addrs != NULL); assert(IS_IN_EL3()); /* Mark the connected core as awake */ @@ -353,7 +353,7 @@ void gicv3_cpuif_enable(unsigned int proc_num) icc_sre_el3 |= (ICC_SRE_EN_BIT | ICC_SRE_SRE_BIT); write_icc_sre_el3(read_icc_sre_el3() | icc_sre_el3); - scr_el3 = read_scr_el3(); + scr_el3 = (uint32_t) read_scr_el3(); /* * Switch to NS state to write Non secure ICC_SRE_EL1 and @@ -393,9 +393,9 @@ void gicv3_cpuif_disable(unsigned int proc_num) { uintptr_t gicr_base; - assert(gicv3_driver_data); + assert(gicv3_driver_data != NULL); assert(proc_num < gicv3_driver_data->rdistif_num); - assert(gicv3_driver_data->rdistif_base_addrs); + assert(gicv3_driver_data->rdistif_base_addrs != NULL); assert(IS_IN_EL3()); @@ -429,14 +429,14 @@ unsigned int gicv3_get_pending_interrupt_id(void) unsigned int id; assert(IS_IN_EL3()); - id = read_icc_hppir0_el1() & HPPIR0_EL1_INTID_MASK; + id = (uint32_t)read_icc_hppir0_el1() & HPPIR0_EL1_INTID_MASK; /* * If the ID is special identifier corresponding to G1S or G1NS * interrupt, then read the highest pending group 1 interrupt. */ if ((id == PENDING_G1S_INTID) || (id == PENDING_G1NS_INTID)) - return read_icc_hppir1_el1() & HPPIR1_EL1_INTID_MASK; + return (uint32_t)read_icc_hppir1_el1() & HPPIR1_EL1_INTID_MASK; return id; } @@ -453,7 +453,7 @@ unsigned int gicv3_get_pending_interrupt_id(void) unsigned int gicv3_get_pending_interrupt_type(void) { assert(IS_IN_EL3()); - return read_icc_hppir0_el1() & HPPIR0_EL1_INTID_MASK; + return (uint32_t)read_icc_hppir0_el1() & HPPIR0_EL1_INTID_MASK; } /******************************************************************************* @@ -473,10 +473,10 @@ unsigned int gicv3_get_interrupt_type(unsigned int id, uintptr_t gicr_base; assert(IS_IN_EL3()); - assert(gicv3_driver_data); + assert(gicv3_driver_data != NULL); /* Ensure the parameters are valid */ - assert(id < PENDING_G1S_INTID || id >= MIN_LPI_ID); + assert((id < PENDING_G1S_INTID) || (id >= MIN_LPI_ID)); assert(proc_num < gicv3_driver_data->rdistif_num); /* All LPI interrupts are Group 1 non secure */ @@ -484,12 +484,12 @@ unsigned int gicv3_get_interrupt_type(unsigned int id, return INTR_GROUP1NS; if (id < MIN_SPI_ID) { - assert(gicv3_driver_data->rdistif_base_addrs); + assert(gicv3_driver_data->rdistif_base_addrs != 0U); gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; igroup = gicr_get_igroupr0(gicr_base, id); grpmodr = gicr_get_igrpmodr0(gicr_base, id); } else { - assert(gicv3_driver_data->gicd_base); + assert(gicv3_driver_data->gicd_base != 0U); igroup = gicd_get_igroupr(gicv3_driver_data->gicd_base, id); grpmodr = gicd_get_igrpmodr(gicv3_driver_data->gicd_base, id); } @@ -498,11 +498,11 @@ unsigned int gicv3_get_interrupt_type(unsigned int id, * If the IGROUP bit is set, then it is a Group 1 Non secure * interrupt */ - if (igroup) + if (igroup != 0U) return INTR_GROUP1NS; /* If the GRPMOD bit is set, then it is a Group 1 Secure interrupt */ - if (grpmodr) + if (grpmodr != 0U) return INTR_GROUP1S; /* Else it is a Group 0 Secure interrupt */ @@ -522,12 +522,12 @@ unsigned int gicv3_get_interrupt_type(unsigned int id, *****************************************************************************/ void gicv3_its_save_disable(uintptr_t gits_base, gicv3_its_ctx_t * const its_ctx) { - int i; + unsigned int i; - assert(gicv3_driver_data); + assert(gicv3_driver_data != NULL); assert(IS_IN_EL3()); - assert(its_ctx); - assert(gits_base); + assert(its_ctx != NULL); + assert(gits_base != 0U); its_ctx->gits_ctlr = gits_read_ctlr(gits_base); @@ -555,16 +555,16 @@ void gicv3_its_save_disable(uintptr_t gits_base, gicv3_its_ctx_t * const its_ctx *****************************************************************************/ void gicv3_its_restore(uintptr_t gits_base, const gicv3_its_ctx_t * const its_ctx) { - int i; + unsigned int i; - assert(gicv3_driver_data); + assert(gicv3_driver_data != NULL); assert(IS_IN_EL3()); - assert(its_ctx); - assert(gits_base); + assert(its_ctx != NULL); + assert(gits_base != 0U); /* Assert that the GITS is disabled and quiescent */ - assert((gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT) == 0); - assert((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) != 0); + assert((gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT) == 0U); + assert((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) != 0U); gits_write_cbaser(gits_base, its_ctx->gits_cbaser); gits_write_cwriter(gits_base, its_ctx->gits_cwriter); @@ -586,11 +586,11 @@ void gicv3_rdistif_save(unsigned int proc_num, gicv3_redist_ctx_t * const rdist_ uintptr_t gicr_base; unsigned int int_id; - assert(gicv3_driver_data); + assert(gicv3_driver_data != NULL); assert(proc_num < gicv3_driver_data->rdistif_num); - assert(gicv3_driver_data->rdistif_base_addrs); + assert(gicv3_driver_data->rdistif_base_addrs != NULL); assert(IS_IN_EL3()); - assert(rdist_ctx); + assert(rdist_ctx != NULL); gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; @@ -614,7 +614,7 @@ void gicv3_rdistif_save(unsigned int proc_num, gicv3_redist_ctx_t * const rdist_ rdist_ctx->gicr_igrpmodr0 = gicr_read_igrpmodr0(gicr_base); rdist_ctx->gicr_nsacr = gicr_read_nsacr(gicr_base); for (int_id = MIN_SGI_ID; int_id < TOTAL_PCPU_INTR_NUM; - int_id += (1 << IPRIORITYR_SHIFT)) { + int_id += (1U << IPRIORITYR_SHIFT)) { rdist_ctx->gicr_ipriorityr[(int_id - MIN_SGI_ID) >> IPRIORITYR_SHIFT] = gicr_read_ipriorityr(gicr_base, int_id); } @@ -641,11 +641,11 @@ void gicv3_rdistif_init_restore(unsigned int proc_num, uintptr_t gicr_base; unsigned int int_id; - assert(gicv3_driver_data); + assert(gicv3_driver_data != NULL); assert(proc_num < gicv3_driver_data->rdistif_num); - assert(gicv3_driver_data->rdistif_base_addrs); + assert(gicv3_driver_data->rdistif_base_addrs != NULL); assert(IS_IN_EL3()); - assert(rdist_ctx); + assert(rdist_ctx != NULL); gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; @@ -664,7 +664,7 @@ void gicv3_rdistif_init_restore(unsigned int proc_num, * more scalable approach as it avoids clearing the enable bits in the * GICD_CTLR */ - gicr_write_icenabler0(gicr_base, ~0); + gicr_write_icenabler0(gicr_base, ~0U); /* Wait for pending writes to GICR_ICENABLER */ gicr_wait_for_pending_write(gicr_base); @@ -682,7 +682,7 @@ void gicv3_rdistif_init_restore(unsigned int proc_num, gicr_write_igroupr0(gicr_base, rdist_ctx->gicr_igroupr0); for (int_id = MIN_SGI_ID; int_id < TOTAL_PCPU_INTR_NUM; - int_id += (1 << IPRIORITYR_SHIFT)) { + int_id += (1U << IPRIORITYR_SHIFT)) { gicr_write_ipriorityr(gicr_base, int_id, rdist_ctx->gicr_ipriorityr[ (int_id - MIN_SGI_ID) >> IPRIORITYR_SHIFT]); @@ -722,18 +722,18 @@ void gicv3_distif_save(gicv3_dist_ctx_t * const dist_ctx) { unsigned int num_ints; - assert(gicv3_driver_data); - assert(gicv3_driver_data->gicd_base); + assert(gicv3_driver_data != NULL); + assert(gicv3_driver_data->gicd_base != 0U); assert(IS_IN_EL3()); - assert(dist_ctx); + assert(dist_ctx != NULL); uintptr_t gicd_base = gicv3_driver_data->gicd_base; num_ints = gicd_read_typer(gicd_base); num_ints &= TYPER_IT_LINES_NO_MASK; - num_ints = (num_ints + 1) << 5; + num_ints = (num_ints + 1U) << 5; - assert(num_ints <= MAX_SPI_ID + 1); + assert(num_ints <= (MAX_SPI_ID + 1U)); /* Wait for pending write to complete */ gicd_wait_for_pending_write(gicd_base); @@ -784,12 +784,12 @@ void gicv3_distif_save(gicv3_dist_ctx_t * const dist_ctx) *****************************************************************************/ void gicv3_distif_init_restore(const gicv3_dist_ctx_t * const dist_ctx) { - unsigned int num_ints = 0; + unsigned int num_ints = 0U; - assert(gicv3_driver_data); - assert(gicv3_driver_data->gicd_base); + assert(gicv3_driver_data != NULL); + assert(gicv3_driver_data->gicd_base != 0U); assert(IS_IN_EL3()); - assert(dist_ctx); + assert(dist_ctx != NULL); uintptr_t gicd_base = gicv3_driver_data->gicd_base; @@ -809,9 +809,9 @@ void gicv3_distif_init_restore(const gicv3_dist_ctx_t * const dist_ctx) num_ints = gicd_read_typer(gicd_base); num_ints &= TYPER_IT_LINES_NO_MASK; - num_ints = (num_ints + 1) << 5; + num_ints = (num_ints + 1U) << 5; - assert(num_ints <= MAX_SPI_ID + 1); + assert(num_ints <= (MAX_SPI_ID + 1U)); /* Restore GICD_IGROUPR for INTIDs 32 - 1020 */ RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, igroupr, IGROUPR); @@ -857,7 +857,7 @@ void gicv3_distif_init_restore(const gicv3_dist_ctx_t * const dist_ctx) ******************************************************************************/ unsigned int gicv3_get_running_priority(void) { - return read_icc_rpr_el1(); + return (unsigned int)read_icc_rpr_el1(); } /******************************************************************************* @@ -870,10 +870,10 @@ unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num) { unsigned int value; - assert(gicv3_driver_data); - assert(gicv3_driver_data->gicd_base); + assert(gicv3_driver_data != NULL); + assert(gicv3_driver_data->gicd_base != 0U); assert(proc_num < gicv3_driver_data->rdistif_num); - assert(gicv3_driver_data->rdistif_base_addrs); + assert(gicv3_driver_data->rdistif_base_addrs != NULL); assert(id <= MAX_SPI_ID); if (id < MIN_SPI_ID) { @@ -894,10 +894,10 @@ unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num) ******************************************************************************/ void gicv3_enable_interrupt(unsigned int id, unsigned int proc_num) { - assert(gicv3_driver_data); - assert(gicv3_driver_data->gicd_base); + assert(gicv3_driver_data != NULL); + assert(gicv3_driver_data->gicd_base != 0U); assert(proc_num < gicv3_driver_data->rdistif_num); - assert(gicv3_driver_data->rdistif_base_addrs); + assert(gicv3_driver_data->rdistif_base_addrs != NULL); assert(id <= MAX_SPI_ID); /* @@ -922,10 +922,10 @@ void gicv3_enable_interrupt(unsigned int id, unsigned int proc_num) ******************************************************************************/ void gicv3_disable_interrupt(unsigned int id, unsigned int proc_num) { - assert(gicv3_driver_data); - assert(gicv3_driver_data->gicd_base); + assert(gicv3_driver_data != NULL); + assert(gicv3_driver_data->gicd_base != 0U); assert(proc_num < gicv3_driver_data->rdistif_num); - assert(gicv3_driver_data->rdistif_base_addrs); + assert(gicv3_driver_data->rdistif_base_addrs != NULL); assert(id <= MAX_SPI_ID); /* @@ -960,10 +960,10 @@ void gicv3_set_interrupt_priority(unsigned int id, unsigned int proc_num, { uintptr_t gicr_base; - assert(gicv3_driver_data); - assert(gicv3_driver_data->gicd_base); + assert(gicv3_driver_data != NULL); + assert(gicv3_driver_data->gicd_base != 0U); assert(proc_num < gicv3_driver_data->rdistif_num); - assert(gicv3_driver_data->rdistif_base_addrs); + assert(gicv3_driver_data->rdistif_base_addrs != NULL); assert(id <= MAX_SPI_ID); if (id < MIN_SPI_ID) { @@ -982,29 +982,29 @@ void gicv3_set_interrupt_priority(unsigned int id, unsigned int proc_num, void gicv3_set_interrupt_type(unsigned int id, unsigned int proc_num, unsigned int type) { - unsigned int igroup = 0, grpmod = 0; + bool igroup = false, grpmod = false; uintptr_t gicr_base; - assert(gicv3_driver_data); - assert(gicv3_driver_data->gicd_base); + assert(gicv3_driver_data != NULL); + assert(gicv3_driver_data->gicd_base != 0U); assert(proc_num < gicv3_driver_data->rdistif_num); - assert(gicv3_driver_data->rdistif_base_addrs); + assert(gicv3_driver_data->rdistif_base_addrs != NULL); switch (type) { case INTR_GROUP1S: - igroup = 0; - grpmod = 1; + igroup = false; + grpmod = true; break; case INTR_GROUP0: - igroup = 0; - grpmod = 0; + igroup = false; + grpmod = false; break; case INTR_GROUP1NS: - igroup = 1; - grpmod = 0; + igroup = true; + grpmod = false; break; default: - assert(0); + assert(false); break; } @@ -1040,7 +1040,7 @@ void gicv3_set_interrupt_type(unsigned int id, unsigned int proc_num, * * The target parameter must be a valid MPIDR in the system. ******************************************************************************/ -void gicv3_raise_secure_g0_sgi(int sgi_num, u_register_t target) +void gicv3_raise_secure_g0_sgi(unsigned int sgi_num, u_register_t target) { unsigned int tgt, aff3, aff2, aff1, aff0; uint64_t sgi_val; @@ -1059,7 +1059,7 @@ void gicv3_raise_secure_g0_sgi(int sgi_num, u_register_t target) * this PE. */ assert(aff0 < GICV3_MAX_SGI_TARGETS); - tgt = BIT(aff0); + tgt = BIT_32(aff0); /* Raise SGI to PE specified by its affinity */ sgi_val = GICV3_SGIR_VALUE(aff3, aff2, aff1, sgi_num, SGIR_IRM_TO_AFF, @@ -1090,11 +1090,11 @@ void gicv3_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr unsigned long long aff; uint64_t router; - assert(gicv3_driver_data); - assert(gicv3_driver_data->gicd_base); + assert(gicv3_driver_data != NULL); + assert(gicv3_driver_data->gicd_base != 0U); assert((irm == GICV3_IRM_ANY) || (irm == GICV3_IRM_PE)); - assert(id >= MIN_SPI_ID && id <= MAX_SPI_ID); + assert((id >= MIN_SPI_ID) && (id <= MAX_SPI_ID)); aff = gicd_irouter_val_from_mpidr(mpidr, irm); gicd_write_irouter(gicv3_driver_data->gicd_base, id, aff); @@ -1105,7 +1105,7 @@ void gicv3_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr */ if (irm == GICV3_IRM_ANY) { router = gicd_read_irouter(gicv3_driver_data->gicd_base, id); - if (!((router >> IROUTER_IRM_SHIFT) & IROUTER_IRM_MASK)) { + if (((router >> IROUTER_IRM_SHIFT) & IROUTER_IRM_MASK) == 0U) { ERROR("GICv3 implementation doesn't support routing ANY\n"); panic(); } @@ -1119,10 +1119,10 @@ void gicv3_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr ******************************************************************************/ void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num) { - assert(gicv3_driver_data); - assert(gicv3_driver_data->gicd_base); + assert(gicv3_driver_data != NULL); + assert(gicv3_driver_data->gicd_base != 0U); assert(proc_num < gicv3_driver_data->rdistif_num); - assert(gicv3_driver_data->rdistif_base_addrs); + assert(gicv3_driver_data->rdistif_base_addrs != NULL); /* * Clear pending interrupt, and ensure that any shared variable updates @@ -1145,10 +1145,10 @@ void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num) ******************************************************************************/ void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num) { - assert(gicv3_driver_data); - assert(gicv3_driver_data->gicd_base); + assert(gicv3_driver_data != NULL); + assert(gicv3_driver_data->gicd_base != 0U); assert(proc_num < gicv3_driver_data->rdistif_num); - assert(gicv3_driver_data->rdistif_base_addrs); + assert(gicv3_driver_data->rdistif_base_addrs != NULL); /* * Ensure that any shared variable updates depending on out of band @@ -1172,7 +1172,7 @@ unsigned int gicv3_set_pmr(unsigned int mask) { unsigned int old_mask; - old_mask = read_icc_pmr_el1(); + old_mask = (uint32_t) read_icc_pmr_el1(); /* * Order memory updates w.r.t. PMR write, and ensure they're visible diff --git a/drivers/arm/gic/v3/gicv3_private.h b/drivers/arm/gic/v3/gicv3_private.h index e1c0775f..36d4b3ed 100644 --- a/drivers/arm/gic/v3/gicv3_private.h +++ b/drivers/arm/gic/v3/gicv3_private.h @@ -19,28 +19,36 @@ ******************************************************************************/ /* Constants to indicate the status of the RWP bit */ -#define RWP_TRUE 1 -#define RWP_FALSE 0 +#define RWP_TRUE U(1) +#define RWP_FALSE U(0) /* * Macro to convert an mpidr to a value suitable for programming into a * GICD_IROUTER. Bits[31:24] in the MPIDR are cleared as they are not relevant * to GICv3. */ -#define gicd_irouter_val_from_mpidr(_mpidr, _irm) \ - ((_mpidr & ~(0xff << 24)) | \ - (_irm & IROUTER_IRM_MASK) << IROUTER_IRM_SHIFT) +static inline u_register_t gicd_irouter_val_from_mpidr(u_register_t mpidr, + unsigned int irm) +{ + return (mpidr & ~(U(0xff) << 24)) | + ((irm & IROUTER_IRM_MASK) << IROUTER_IRM_SHIFT); +} /* * Macro to convert a GICR_TYPER affinity value into a MPIDR value. Bits[31:24] * are zeroes. */ #ifdef AARCH32 -#define mpidr_from_gicr_typer(_typer_val) (((_typer_val) >> 32) & 0xffffff) +static inline u_register_t mpidr_from_gicr_typer(uint64_t typer_val) +{ + return (((typer_val) >> 32) & U(0xffffff)); +} #else -#define mpidr_from_gicr_typer(_typer_val) \ - (((((_typer_val) >> 56) & MPIDR_AFFLVL_MASK) << MPIDR_AFF3_SHIFT) | \ - (((_typer_val) >> 32) & 0xffffff)) +static inline u_register_t mpidr_from_gicr_typer(uint64_t typer_val) +{ + return (((typer_val >> 56) & MPIDR_AFFLVL_MASK) << MPIDR_AFF3_SHIFT) | + ((typer_val >> 32) & U(0xffffff)); +} #endif /******************************************************************************* @@ -121,7 +129,7 @@ void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base); */ static inline void gicd_wait_for_pending_write(uintptr_t gicd_base) { - while (gicd_read_ctlr(gicd_base) & GICD_CTLR_RWP_BIT) + while ((gicd_read_ctlr(gicd_base) & GICD_CTLR_RWP_BIT) != 0U) ; } @@ -149,7 +157,7 @@ static inline void gicd_clr_ctlr(uintptr_t base, unsigned int rwp) { gicd_write_ctlr(base, gicd_read_ctlr(base) & ~bitmap); - if (rwp) + if (rwp != 0U) gicd_wait_for_pending_write(base); } @@ -158,21 +166,21 @@ static inline void gicd_set_ctlr(uintptr_t base, unsigned int rwp) { gicd_write_ctlr(base, gicd_read_ctlr(base) | bitmap); - if (rwp) + if (rwp != 0U) gicd_wait_for_pending_write(base); } /******************************************************************************* * GIC Redistributor interface accessors ******************************************************************************/ -static inline unsigned long long gicr_read_ctlr(uintptr_t base) +static inline uint32_t gicr_read_ctlr(uintptr_t base) { - return mmio_read_64(base + GICR_CTLR); + return mmio_read_32(base + GICR_CTLR); } -static inline void gicr_write_ctlr(uintptr_t base, uint64_t val) +static inline void gicr_write_ctlr(uintptr_t base, uint32_t val) { - mmio_write_64(base + GICR_CTLR, val); + mmio_write_32(base + GICR_CTLR, val); } static inline unsigned long long gicr_read_typer(uintptr_t base) @@ -199,13 +207,13 @@ static inline void gicr_write_waker(uintptr_t base, unsigned int val) */ static inline void gicr_wait_for_pending_write(uintptr_t gicr_base) { - while (gicr_read_ctlr(gicr_base) & GICR_CTLR_RWP_BIT) + while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_RWP_BIT) != 0U) ; } static inline void gicr_wait_for_upstream_pending_write(uintptr_t gicr_base) { - while (gicr_read_ctlr(gicr_base) & GICR_CTLR_UWP_BIT) + while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_UWP_BIT) != 0U) ; } @@ -313,24 +321,24 @@ static inline void gicr_write_icfgr1(uintptr_t base, unsigned int val) mmio_write_32(base + GICR_ICFGR1, val); } -static inline unsigned int gicr_read_propbaser(uintptr_t base) +static inline uint64_t gicr_read_propbaser(uintptr_t base) { - return mmio_read_32(base + GICR_PROPBASER); + return mmio_read_64(base + GICR_PROPBASER); } -static inline void gicr_write_propbaser(uintptr_t base, unsigned int val) +static inline void gicr_write_propbaser(uintptr_t base, uint64_t val) { - mmio_write_32(base + GICR_PROPBASER, val); + mmio_write_64(base + GICR_PROPBASER, val); } -static inline unsigned int gicr_read_pendbaser(uintptr_t base) +static inline uint64_t gicr_read_pendbaser(uintptr_t base) { - return mmio_read_32(base + GICR_PENDBASER); + return mmio_read_64(base + GICR_PENDBASER); } -static inline void gicr_write_pendbaser(uintptr_t base, unsigned int val) +static inline void gicr_write_pendbaser(uintptr_t base, uint64_t val) { - mmio_write_32(base + GICR_PENDBASER, val); + mmio_write_64(base + GICR_PENDBASER, val); } /******************************************************************************* @@ -353,7 +361,7 @@ static inline uint64_t gits_read_cbaser(uintptr_t base) static inline void gits_write_cbaser(uintptr_t base, uint64_t val) { - mmio_write_32(base + GITS_CBASER, val); + mmio_write_64(base + GITS_CBASER, val); } static inline uint64_t gits_read_cwriter(uintptr_t base) @@ -363,19 +371,19 @@ static inline uint64_t gits_read_cwriter(uintptr_t base) static inline void gits_write_cwriter(uintptr_t base, uint64_t val) { - mmio_write_32(base + GITS_CWRITER, val); + mmio_write_64(base + GITS_CWRITER, val); } static inline uint64_t gits_read_baser(uintptr_t base, unsigned int its_table_id) { - assert(its_table_id < 8); - return mmio_read_64(base + GITS_BASER + (8 * its_table_id)); + assert(its_table_id < 8U); + return mmio_read_64(base + GITS_BASER + (8U * its_table_id)); } static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id, uint64_t val) { - assert(its_table_id < 8); - mmio_write_64(base + GITS_BASER + (8 * its_table_id), val); + assert(its_table_id < 8U); + mmio_write_64(base + GITS_BASER + (8U * its_table_id), val); } /* @@ -383,8 +391,8 @@ static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id, u */ static inline void gits_wait_for_quiescent_bit(uintptr_t gits_base) { - assert(!(gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT)); - while ((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) == 0) + assert((gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT) == 0U); + while ((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) == 0U) ; } diff --git a/drivers/arm/smmu/smmu_v3.c b/drivers/arm/smmu/smmu_v3.c index 7b017e30..ddb99634 100644 --- a/drivers/arm/smmu/smmu_v3.c +++ b/drivers/arm/smmu/smmu_v3.c @@ -1,15 +1,12 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <mmio.h> #include <smmu_v3.h> - -/* Test for pending invalidate */ -#define INVAL_PENDING(_base) \ - smmuv3_read_s_init(_base) & SMMU_S_INIT_INV_ALL_MASK +#include <stdbool.h> static inline uint32_t smmuv3_read_s_idr1(uintptr_t base) { @@ -26,6 +23,12 @@ static inline void smmuv3_write_s_init(uintptr_t base, uint32_t value) mmio_write_32(base + SMMU_S_INIT, value); } +/* Test for pending invalidate */ +static inline bool smmuv3_inval_pending(uintptr_t base) +{ + return (smmuv3_read_s_init(base) & SMMU_S_INIT_INV_ALL_MASK) != 0U; +} + /* * Initialize the SMMU by invalidating all secure caches and TLBs. * @@ -41,14 +44,14 @@ int smmuv3_init(uintptr_t smmu_base) * SMMU_S_INIT register is accessed. */ idr1_reg = smmuv3_read_s_idr1(smmu_base); - if (!((idr1_reg >> SMMU_S_IDR1_SECURE_IMPL_SHIFT) & - SMMU_S_IDR1_SECURE_IMPL_MASK)) { + if (((idr1_reg >> SMMU_S_IDR1_SECURE_IMPL_SHIFT) & + SMMU_S_IDR1_SECURE_IMPL_MASK) == 0U) { return -1; } /* Initiate invalidation, and wait for it to finish */ smmuv3_write_s_init(smmu_base, SMMU_S_INIT_INV_ALL_MASK); - while (INVAL_PENDING(smmu_base)) + while (smmuv3_inval_pending(smmu_base)) ; return 0; diff --git a/include/bl31/ehf.h b/include/bl31/ehf.h index c60b04cd..f35d8100 100644 --- a/include/bl31/ehf.h +++ b/include/bl31/ehf.h @@ -14,7 +14,7 @@ #include <utils_def.h> /* Valid priorities set bit 0 of the priority handler. */ -#define EHF_PRI_VALID_ (((uintptr_t) 1) << 0) +#define EHF_PRI_VALID_ BIT(0) /* Marker for no handler registered for a valid priority */ #define EHF_NO_HANDLER_ (0U | EHF_PRI_VALID_) diff --git a/include/bl31/interrupt_mgmt.h b/include/bl31/interrupt_mgmt.h index 49ba9f73..0cdbda02 100644 --- a/include/bl31/interrupt_mgmt.h +++ b/include/bl31/interrupt_mgmt.h @@ -8,6 +8,7 @@ #define __INTERRUPT_MGMT_H__ #include <arch.h> +#include <utils_def.h> /******************************************************************************* * Constants for the types of interrupts recognised by the IM framework @@ -66,34 +67,6 @@ #define set_interrupt_rm_flag(flag, ss) ((flag) |= U(1) << (ss)) #define clr_interrupt_rm_flag(flag, ss) ((flag) &= ~(U(1) << (ss))) - -/******************************************************************************* - * Macros to validate the routing model bits in the 'flags' for a type - * of interrupt. If the model does not match one of the valid masks - * -EINVAL is returned. - ******************************************************************************/ -#define validate_sel1_interrupt_rm(x) ((x) == INTR_SEL1_VALID_RM0 ? 0 : \ - ((x) == INTR_SEL1_VALID_RM1 ? 0 :\ - -EINVAL)) - -#define validate_ns_interrupt_rm(x) ((x) == INTR_NS_VALID_RM0 ? 0 : \ - ((x) == INTR_NS_VALID_RM1 ? 0 :\ - -EINVAL)) - -#if EL3_EXCEPTION_HANDLING -/* - * With EL3 exception handling, EL3 interrupts are always routed to EL3 from - * both Secure and Non-secure, and therefore INTR_EL3_VALID_RM1 is the only - * valid routing model. - */ -#define validate_el3_interrupt_rm(x) ((x) == INTR_EL3_VALID_RM1 ? 0 : \ - -EINVAL) -#else -#define validate_el3_interrupt_rm(x) ((x) == INTR_EL3_VALID_RM0 ? 0 : \ - ((x) == INTR_EL3_VALID_RM1 ? 0 :\ - -EINVAL)) -#endif - /******************************************************************************* * Macros to set the 'flags' parameter passed to an interrupt type handler. Only * the flag to indicate the security state when the exception was generated is @@ -108,9 +81,51 @@ #ifndef __ASSEMBLY__ +#include <errno.h> #include <stdint.h> -/* Prototype for defining a handler for an interrupt type */ +/******************************************************************************* + * Helpers to validate the routing model bits in the 'flags' for a type + * of interrupt. If the model does not match one of the valid masks + * -EINVAL is returned. + ******************************************************************************/ +static inline int32_t validate_sel1_interrupt_rm(uint32_t x) +{ + if ((x == INTR_SEL1_VALID_RM0) || (x == INTR_SEL1_VALID_RM1)) + return 0; + + return -EINVAL; +} + +static inline int32_t validate_ns_interrupt_rm(uint32_t x) +{ + if ((x == INTR_NS_VALID_RM0) || (x == INTR_NS_VALID_RM1)) + return 0; + + return -EINVAL; +} + +static inline int32_t validate_el3_interrupt_rm(uint32_t x) +{ +#if EL3_EXCEPTION_HANDLING + /* + * With EL3 exception handling, EL3 interrupts are always routed to EL3 + * from both Secure and Non-secure, and therefore INTR_EL3_VALID_RM1 is + * the only valid routing model. + */ + if (x == INTR_EL3_VALID_RM1) + return 0; +#else + if ((x == INTR_EL3_VALID_RM0) || (x == INTR_EL3_VALID_RM1)) + return 0; +#endif + + return -EINVAL; +} + +/******************************************************************************* + * Prototype for defining a handler for an interrupt type + ******************************************************************************/ typedef uint64_t (*interrupt_type_handler_t)(uint32_t id, uint32_t flags, void *handle, diff --git a/include/common/debug.h b/include/common/debug.h index 4c5560f5..8ee55b88 100644 --- a/include/common/debug.h +++ b/include/common/debug.h @@ -7,6 +7,8 @@ #ifndef DEBUG_H #define DEBUG_H +#include <utils_def.h> + /* * The log output macros print output to the console. These macros produce * compiled log output only if the LOG_LEVEL defined in the makefile (or the @@ -18,16 +20,18 @@ * WARN("Warning %s.\n", "message") -> WARNING: Warning message. */ -#define LOG_LEVEL_NONE 0 -#define LOG_LEVEL_ERROR 10 -#define LOG_LEVEL_NOTICE 20 -#define LOG_LEVEL_WARNING 30 -#define LOG_LEVEL_INFO 40 -#define LOG_LEVEL_VERBOSE 50 +#define LOG_LEVEL_NONE U(0) +#define LOG_LEVEL_ERROR U(10) +#define LOG_LEVEL_NOTICE U(20) +#define LOG_LEVEL_WARNING U(30) +#define LOG_LEVEL_INFO U(40) +#define LOG_LEVEL_VERBOSE U(50) #ifndef __ASSEMBLY__ #include <cdefs.h> +#include <console.h> #include <stdarg.h> +#include <stdbool.h> #include <stdio.h> /* @@ -48,10 +52,10 @@ */ #define no_tf_log(fmt, ...) \ do { \ - if (0) { \ + if (false) { \ tf_log(fmt, ##__VA_ARGS__); \ } \ - } while (0) + } while (false) #if LOG_LEVEL >= LOG_LEVEL_NOTICE # define NOTICE(...) tf_log(LOG_MARKER_NOTICE __VA_ARGS__) @@ -83,8 +87,20 @@ # define VERBOSE(...) no_tf_log(LOG_MARKER_VERBOSE __VA_ARGS__) #endif +#if ENABLE_BACKTRACE +void backtrace(const char *cookie); +#else +#define backtrace(x) +#endif + void __dead2 do_panic(void); -#define panic() do_panic() + +#define panic() \ + do { \ + backtrace(__func__); \ + (void)console_flush(); \ + do_panic(); \ + } while (false) /* Function called when stack protection check code detects a corrupted stack */ void __dead2 __stack_chk_fail(void); diff --git a/include/common/param_header.h b/include/common/param_header.h index a5a08ec4..ec4ee4ee 100644 --- a/include/common/param_header.h +++ b/include/common/param_header.h @@ -7,25 +7,28 @@ #ifndef __PARAM_HEADER_H__ #define __PARAM_HEADER_H__ +#include <stdbool.h> +#include <utils_def.h> + /* Param header types */ -#define PARAM_EP 0x01 -#define PARAM_IMAGE_BINARY 0x02 -#define PARAM_BL31 0x03 -#define PARAM_BL_LOAD_INFO 0x04 -#define PARAM_BL_PARAMS 0x05 -#define PARAM_PSCI_LIB_ARGS 0x06 -#define PARAM_SP_IMAGE_BOOT_INFO 0x07 +#define PARAM_EP U(0x01) +#define PARAM_IMAGE_BINARY U(0x02) +#define PARAM_BL31 U(0x03) +#define PARAM_BL_LOAD_INFO U(0x04) +#define PARAM_BL_PARAMS U(0x05) +#define PARAM_PSCI_LIB_ARGS U(0x06) +#define PARAM_SP_IMAGE_BOOT_INFO U(0x07) /* Param header version */ -#define VERSION_1 0x01 -#define VERSION_2 0x02 +#define VERSION_1 U(0x01) +#define VERSION_2 U(0x02) #define SET_PARAM_HEAD(_p, _type, _ver, _attr) do { \ (_p)->h.type = (uint8_t)(_type); \ (_p)->h.version = (uint8_t)(_ver); \ (_p)->h.size = (uint16_t)sizeof(*(_p)); \ (_p)->h.attr = (uint32_t)(_attr) ; \ - } while (0) + } while (false) /* Following is used for populating structure members statically. */ #define SET_STATIC_PARAM_HEAD(_p, _type, _ver, _p_type, _attr) \ diff --git a/include/common/tbbr/tbbr_img_def.h b/include/common/tbbr/tbbr_img_def.h index 273abbea..a97914de 100644 --- a/include/common/tbbr/tbbr_img_def.h +++ b/include/common/tbbr/tbbr_img_def.h @@ -7,75 +7,77 @@ #ifndef __TBBR_IMG_DEF_H__ #define __TBBR_IMG_DEF_H__ +#include <utils_def.h> + /* Firmware Image Package */ -#define FIP_IMAGE_ID 0 +#define FIP_IMAGE_ID U(0) /* Trusted Boot Firmware BL2 */ -#define BL2_IMAGE_ID 1 +#define BL2_IMAGE_ID U(1) /* SCP Firmware SCP_BL2 */ -#define SCP_BL2_IMAGE_ID 2 +#define SCP_BL2_IMAGE_ID U(2) /* EL3 Runtime Firmware BL31 */ -#define BL31_IMAGE_ID 3 +#define BL31_IMAGE_ID U(3) /* Secure Payload BL32 (Trusted OS) */ -#define BL32_IMAGE_ID 4 +#define BL32_IMAGE_ID U(4) /* Non-Trusted Firmware BL33 */ -#define BL33_IMAGE_ID 5 +#define BL33_IMAGE_ID U(5) /* Certificates */ -#define TRUSTED_BOOT_FW_CERT_ID 6 -#define TRUSTED_KEY_CERT_ID 7 +#define TRUSTED_BOOT_FW_CERT_ID U(6) +#define TRUSTED_KEY_CERT_ID U(7) -#define SCP_FW_KEY_CERT_ID 8 -#define SOC_FW_KEY_CERT_ID 9 -#define TRUSTED_OS_FW_KEY_CERT_ID 10 -#define NON_TRUSTED_FW_KEY_CERT_ID 11 +#define SCP_FW_KEY_CERT_ID U(8) +#define SOC_FW_KEY_CERT_ID U(9) +#define TRUSTED_OS_FW_KEY_CERT_ID U(10) +#define NON_TRUSTED_FW_KEY_CERT_ID U(11) -#define SCP_FW_CONTENT_CERT_ID 12 -#define SOC_FW_CONTENT_CERT_ID 13 -#define TRUSTED_OS_FW_CONTENT_CERT_ID 14 -#define NON_TRUSTED_FW_CONTENT_CERT_ID 15 +#define SCP_FW_CONTENT_CERT_ID U(12) +#define SOC_FW_CONTENT_CERT_ID U(13) +#define TRUSTED_OS_FW_CONTENT_CERT_ID U(14) +#define NON_TRUSTED_FW_CONTENT_CERT_ID U(15) /* Non-Trusted ROM Firmware NS_BL1U */ -#define NS_BL1U_IMAGE_ID 16 +#define NS_BL1U_IMAGE_ID U(16) /* Trusted FWU Certificate */ -#define FWU_CERT_ID 17 +#define FWU_CERT_ID U(17) /* Trusted FWU SCP Firmware SCP_BL2U */ -#define SCP_BL2U_IMAGE_ID 18 +#define SCP_BL2U_IMAGE_ID U(18) /* Trusted FWU Boot Firmware BL2U */ -#define BL2U_IMAGE_ID 19 +#define BL2U_IMAGE_ID U(19) /* Non-Trusted FWU Firmware NS_BL2U */ -#define NS_BL2U_IMAGE_ID 20 +#define NS_BL2U_IMAGE_ID U(20) /* Secure Payload BL32_EXTRA1 (Trusted OS Extra1) */ -#define BL32_EXTRA1_IMAGE_ID 21 +#define BL32_EXTRA1_IMAGE_ID U(21) /* Secure Payload BL32_EXTRA2 (Trusted OS Extra2) */ -#define BL32_EXTRA2_IMAGE_ID 22 +#define BL32_EXTRA2_IMAGE_ID U(22) /* HW_CONFIG (e.g. Kernel DT) */ -#define HW_CONFIG_ID 23 +#define HW_CONFIG_ID U(23) /* TB_FW_CONFIG */ -#define TB_FW_CONFIG_ID 24 +#define TB_FW_CONFIG_ID U(24) /* SOC_FW_CONFIG */ -#define SOC_FW_CONFIG_ID 25 +#define SOC_FW_CONFIG_ID U(25) /* TOS_FW_CONFIG */ -#define TOS_FW_CONFIG_ID 26 +#define TOS_FW_CONFIG_ID U(26) /* NT_FW_CONFIG */ -#define NT_FW_CONFIG_ID 27 +#define NT_FW_CONFIG_ID U(27) /* Define size of the array */ -#define MAX_NUMBER_IDS 28 +#define MAX_NUMBER_IDS U(28) #endif /* __TBBR_IMG_DEF_H__ */ diff --git a/include/drivers/arm/cci.h b/include/drivers/arm/cci.h index 1def6a8f..41a3de25 100644 --- a/include/drivers/arm/cci.h +++ b/include/drivers/arm/cci.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,94 +7,96 @@ #ifndef __CCI_H__ #define __CCI_H__ +#include <utils_def.h> + /* Slave interface offsets from PERIPHBASE */ -#define SLAVE_IFACE6_OFFSET 0x7000 -#define SLAVE_IFACE5_OFFSET 0x6000 -#define SLAVE_IFACE4_OFFSET 0x5000 -#define SLAVE_IFACE3_OFFSET 0x4000 -#define SLAVE_IFACE2_OFFSET 0x3000 -#define SLAVE_IFACE1_OFFSET 0x2000 -#define SLAVE_IFACE0_OFFSET 0x1000 -#define SLAVE_IFACE_OFFSET(index) (SLAVE_IFACE0_OFFSET + \ - (0x1000 * (index))) +#define SLAVE_IFACE6_OFFSET UL(0x7000) +#define SLAVE_IFACE5_OFFSET UL(0x6000) +#define SLAVE_IFACE4_OFFSET UL(0x5000) +#define SLAVE_IFACE3_OFFSET UL(0x4000) +#define SLAVE_IFACE2_OFFSET UL(0x3000) +#define SLAVE_IFACE1_OFFSET UL(0x2000) +#define SLAVE_IFACE0_OFFSET UL(0x1000) +#define SLAVE_IFACE_OFFSET(index) (SLAVE_IFACE0_OFFSET + \ + (UL(0x1000) * (index))) /* Slave interface event and count register offsets from PERIPHBASE */ -#define EVENT_SELECT7_OFFSET 0x80000 -#define EVENT_SELECT6_OFFSET 0x70000 -#define EVENT_SELECT5_OFFSET 0x60000 -#define EVENT_SELECT4_OFFSET 0x50000 -#define EVENT_SELECT3_OFFSET 0x40000 -#define EVENT_SELECT2_OFFSET 0x30000 -#define EVENT_SELECT1_OFFSET 0x20000 -#define EVENT_SELECT0_OFFSET 0x10000 -#define EVENT_OFFSET(index) (EVENT_SELECT0_OFFSET + \ - (0x10000 * (index))) +#define EVENT_SELECT7_OFFSET UL(0x80000) +#define EVENT_SELECT6_OFFSET UL(0x70000) +#define EVENT_SELECT5_OFFSET UL(0x60000) +#define EVENT_SELECT4_OFFSET UL(0x50000) +#define EVENT_SELECT3_OFFSET UL(0x40000) +#define EVENT_SELECT2_OFFSET UL(0x30000) +#define EVENT_SELECT1_OFFSET UL(0x20000) +#define EVENT_SELECT0_OFFSET UL(0x10000) +#define EVENT_OFFSET(index) (EVENT_SELECT0_OFFSET + \ + (UL(0x10000) * (index))) /* Control and ID register offsets */ -#define CTRL_OVERRIDE_REG 0x0 -#define SECURE_ACCESS_REG 0x8 -#define STATUS_REG 0xc -#define IMPRECISE_ERR_REG 0x10 -#define PERFMON_CTRL_REG 0x100 -#define IFACE_MON_CTRL_REG 0x104 +#define CTRL_OVERRIDE_REG U(0x0) +#define SECURE_ACCESS_REG U(0x8) +#define STATUS_REG U(0xc) +#define IMPRECISE_ERR_REG U(0x10) +#define PERFMON_CTRL_REG U(0x100) +#define IFACE_MON_CTRL_REG U(0x104) /* Component and peripheral ID registers */ -#define PERIPHERAL_ID0 0xFE0 -#define PERIPHERAL_ID1 0xFE4 -#define PERIPHERAL_ID2 0xFE8 -#define PERIPHERAL_ID3 0xFEC -#define PERIPHERAL_ID4 0xFD0 -#define PERIPHERAL_ID5 0xFD4 -#define PERIPHERAL_ID6 0xFD8 -#define PERIPHERAL_ID7 0xFDC - -#define COMPONENT_ID0 0xFF0 -#define COMPONENT_ID1 0xFF4 -#define COMPONENT_ID2 0xFF8 -#define COMPONENT_ID3 0xFFC -#define COMPONENT_ID4 0x1000 -#define COMPONENT_ID5 0x1004 -#define COMPONENT_ID6 0x1008 -#define COMPONENT_ID7 0x100C +#define PERIPHERAL_ID0 U(0xFE0) +#define PERIPHERAL_ID1 U(0xFE4) +#define PERIPHERAL_ID2 U(0xFE8) +#define PERIPHERAL_ID3 U(0xFEC) +#define PERIPHERAL_ID4 U(0xFD0) +#define PERIPHERAL_ID5 U(0xFD4) +#define PERIPHERAL_ID6 U(0xFD8) +#define PERIPHERAL_ID7 U(0xFDC) + +#define COMPONENT_ID0 U(0xFF0) +#define COMPONENT_ID1 U(0xFF4) +#define COMPONENT_ID2 U(0xFF8) +#define COMPONENT_ID3 U(0xFFC) +#define COMPONENT_ID4 U(0x1000) +#define COMPONENT_ID5 U(0x1004) +#define COMPONENT_ID6 U(0x1008) +#define COMPONENT_ID7 U(0x100C) /* Slave interface register offsets */ -#define SNOOP_CTRL_REG 0x0 -#define SH_OVERRIDE_REG 0x4 -#define READ_CHNL_QOS_VAL_OVERRIDE_REG 0x100 -#define WRITE_CHNL_QOS_VAL_OVERRIDE_REG 0x104 -#define MAX_OT_REG 0x110 +#define SNOOP_CTRL_REG U(0x0) +#define SH_OVERRIDE_REG U(0x4) +#define READ_CHNL_QOS_VAL_OVERRIDE_REG U(0x100) +#define WRITE_CHNL_QOS_VAL_OVERRIDE_REG U(0x104) +#define MAX_OT_REG U(0x110) /* Snoop Control register bit definitions */ -#define DVM_EN_BIT (1 << 1) -#define SNOOP_EN_BIT (1 << 0) -#define SUPPORT_SNOOPS (1 << 30) -#define SUPPORT_DVM (1 << 31) +#define DVM_EN_BIT BIT_32(1) +#define SNOOP_EN_BIT BIT_32(0) +#define SUPPORT_SNOOPS BIT_32(30) +#define SUPPORT_DVM BIT_32(31) /* Status register bit definitions */ -#define CHANGE_PENDING_BIT (1 << 0) +#define CHANGE_PENDING_BIT BIT_32(0) /* Event and count register offsets */ -#define EVENT_SELECT_REG 0x0 -#define EVENT_COUNT_REG 0x4 -#define COUNT_CNTRL_REG 0x8 -#define COUNT_OVERFLOW_REG 0xC +#define EVENT_SELECT_REG U(0x0) +#define EVENT_COUNT_REG U(0x4) +#define COUNT_CNTRL_REG U(0x8) +#define COUNT_OVERFLOW_REG U(0xC) /* Slave interface monitor registers */ -#define INT_MON_REG_SI0 0x90000 -#define INT_MON_REG_SI1 0x90004 -#define INT_MON_REG_SI2 0x90008 -#define INT_MON_REG_SI3 0x9000C -#define INT_MON_REG_SI4 0x90010 -#define INT_MON_REG_SI5 0x90014 -#define INT_MON_REG_SI6 0x90018 +#define INT_MON_REG_SI0 U(0x90000) +#define INT_MON_REG_SI1 U(0x90004) +#define INT_MON_REG_SI2 U(0x90008) +#define INT_MON_REG_SI3 U(0x9000C) +#define INT_MON_REG_SI4 U(0x90010) +#define INT_MON_REG_SI5 U(0x90014) +#define INT_MON_REG_SI6 U(0x90018) /* Master interface monitor registers */ -#define INT_MON_REG_MI0 0x90100 -#define INT_MON_REG_MI1 0x90104 -#define INT_MON_REG_MI2 0x90108 -#define INT_MON_REG_MI3 0x9010c -#define INT_MON_REG_MI4 0x90110 -#define INT_MON_REG_MI5 0x90114 +#define INT_MON_REG_MI0 U(0x90100) +#define INT_MON_REG_MI1 U(0x90104) +#define INT_MON_REG_MI2 U(0x90108) +#define INT_MON_REG_MI3 U(0x9010c) +#define INT_MON_REG_MI4 U(0x90110) +#define INT_MON_REG_MI5 U(0x90114) #define SLAVE_IF_UNUSED -1 diff --git a/include/drivers/arm/gic_common.h b/include/drivers/arm/gic_common.h index 00cbd1d9..0ef11483 100644 --- a/include/drivers/arm/gic_common.h +++ b/include/drivers/arm/gic_common.h @@ -13,23 +13,23 @@ * GIC Distributor interface general definitions ******************************************************************************/ /* Constants to categorise interrupts */ -#define MIN_SGI_ID 0 -#define MIN_SEC_SGI_ID 8 -#define MIN_PPI_ID 16 -#define MIN_SPI_ID 32 -#define MAX_SPI_ID 1019 +#define MIN_SGI_ID U(0) +#define MIN_SEC_SGI_ID U(8) +#define MIN_PPI_ID U(16) +#define MIN_SPI_ID U(32) +#define MAX_SPI_ID U(1019) -#define TOTAL_SPI_INTR_NUM (MAX_SPI_ID - MIN_SPI_ID + 1) +#define TOTAL_SPI_INTR_NUM (MAX_SPI_ID - MIN_SPI_ID + U(1)) #define TOTAL_PCPU_INTR_NUM (MIN_SPI_ID - MIN_SGI_ID) /* Mask for the priority field common to all GIC interfaces */ -#define GIC_PRI_MASK 0xff +#define GIC_PRI_MASK U(0xff) /* Mask for the configuration field common to all GIC interfaces */ -#define GIC_CFG_MASK 0x3 +#define GIC_CFG_MASK U(0x3) /* Constant to indicate a spurious interrupt in all GIC versions */ -#define GIC_SPURIOUS_INTERRUPT 1023 +#define GIC_SPURIOUS_INTERRUPT U(1023) /* Interrupt configurations: 2-bit fields with LSB reserved */ #define GIC_INTR_CFG_LEVEL (0 << 1) @@ -44,38 +44,38 @@ /******************************************************************************* * GIC Distributor interface register offsets that are common to GICv3 & GICv2 ******************************************************************************/ -#define GICD_CTLR 0x0 -#define GICD_TYPER 0x4 -#define GICD_IIDR 0x8 -#define GICD_IGROUPR 0x80 -#define GICD_ISENABLER 0x100 -#define GICD_ICENABLER 0x180 -#define GICD_ISPENDR 0x200 -#define GICD_ICPENDR 0x280 -#define GICD_ISACTIVER 0x300 -#define GICD_ICACTIVER 0x380 -#define GICD_IPRIORITYR 0x400 -#define GICD_ICFGR 0xc00 -#define GICD_NSACR 0xe00 +#define GICD_CTLR U(0x0) +#define GICD_TYPER U(0x4) +#define GICD_IIDR U(0x8) +#define GICD_IGROUPR U(0x80) +#define GICD_ISENABLER U(0x100) +#define GICD_ICENABLER U(0x180) +#define GICD_ISPENDR U(0x200) +#define GICD_ICPENDR U(0x280) +#define GICD_ISACTIVER U(0x300) +#define GICD_ICACTIVER U(0x380) +#define GICD_IPRIORITYR U(0x400) +#define GICD_ICFGR U(0xc00) +#define GICD_NSACR U(0xe00) /* GICD_CTLR bit definitions */ #define CTLR_ENABLE_G0_SHIFT 0 -#define CTLR_ENABLE_G0_MASK 0x1 -#define CTLR_ENABLE_G0_BIT (1 << CTLR_ENABLE_G0_SHIFT) +#define CTLR_ENABLE_G0_MASK U(0x1) +#define CTLR_ENABLE_G0_BIT BIT_32(CTLR_ENABLE_G0_SHIFT) /******************************************************************************* * GIC Distributor interface register constants that are common to GICv3 & GICv2 ******************************************************************************/ #define PIDR2_ARCH_REV_SHIFT 4 -#define PIDR2_ARCH_REV_MASK 0xf +#define PIDR2_ARCH_REV_MASK U(0xf) /* GICv3 revision as reported by the PIDR2 register */ -#define ARCH_REV_GICV3 0x3 +#define ARCH_REV_GICV3 U(0x3) /* GICv2 revision as reported by the PIDR2 register */ -#define ARCH_REV_GICV2 0x2 +#define ARCH_REV_GICV2 U(0x2) /* GICv1 revision as reported by the PIDR2 register */ -#define ARCH_REV_GICV1 0x1 +#define ARCH_REV_GICV1 U(0x1) #define IGROUPR_SHIFT 5 #define ISENABLER_SHIFT 5 @@ -90,8 +90,8 @@ #define NSACR_SHIFT 4 /* GICD_TYPER shifts and masks */ -#define TYPER_IT_LINES_NO_SHIFT 0 -#define TYPER_IT_LINES_NO_MASK 0x1f +#define TYPER_IT_LINES_NO_SHIFT U(0) +#define TYPER_IT_LINES_NO_MASK U(0x1f) /* Value used to initialize Normal world interrupt priorities four at a time */ #define GICD_IPRIORITYR_DEF_VAL \ diff --git a/include/drivers/arm/gicv2.h b/include/drivers/arm/gicv2.h index 925d1c25..02ffa023 100644 --- a/include/drivers/arm/gicv2.h +++ b/include/drivers/arm/gicv2.h @@ -12,37 +12,37 @@ ******************************************************************************/ /* Interrupt group definitions */ -#define GICV2_INTR_GROUP0 0 -#define GICV2_INTR_GROUP1 1 +#define GICV2_INTR_GROUP0 U(0) +#define GICV2_INTR_GROUP1 U(1) /* Interrupt IDs reported by the HPPIR and IAR registers */ -#define PENDING_G1_INTID 1022 +#define PENDING_G1_INTID U(1022) /* GICv2 can only target up to 8 PEs */ -#define GICV2_MAX_TARGET_PE 8 +#define GICV2_MAX_TARGET_PE U(8) /******************************************************************************* * GICv2 specific Distributor interface register offsets and constants. ******************************************************************************/ -#define GICD_ITARGETSR 0x800 -#define GICD_SGIR 0xF00 -#define GICD_CPENDSGIR 0xF10 -#define GICD_SPENDSGIR 0xF20 -#define GICD_PIDR2_GICV2 0xFE8 +#define GICD_ITARGETSR U(0x800) +#define GICD_SGIR U(0xF00) +#define GICD_CPENDSGIR U(0xF10) +#define GICD_SPENDSGIR U(0xF20) +#define GICD_PIDR2_GICV2 U(0xFE8) #define ITARGETSR_SHIFT 2 -#define GIC_TARGET_CPU_MASK 0xff +#define GIC_TARGET_CPU_MASK U(0xff) #define CPENDSGIR_SHIFT 2 #define SPENDSGIR_SHIFT CPENDSGIR_SHIFT #define SGIR_TGTLSTFLT_SHIFT 24 -#define SGIR_TGTLSTFLT_MASK 0x3 +#define SGIR_TGTLSTFLT_MASK U(0x3) #define SGIR_TGTLST_SHIFT 16 -#define SGIR_TGTLST_MASK 0xff -#define SGIR_INTID_MASK 0xf +#define SGIR_TGTLST_MASK U(0xff) +#define SGIR_INTID_MASK ULL(0xf) -#define SGIR_TGT_SPECIFIC 0 +#define SGIR_TGT_SPECIFIC U(0) #define GICV2_SGIR_VALUE(tgt_lst_flt, tgt, intid) \ ((((tgt_lst_flt) & SGIR_TGTLSTFLT_MASK) << SGIR_TGTLSTFLT_SHIFT) | \ @@ -53,29 +53,29 @@ * GICv2 specific CPU interface register offsets and constants. ******************************************************************************/ /* Physical CPU Interface registers */ -#define GICC_CTLR 0x0 -#define GICC_PMR 0x4 -#define GICC_BPR 0x8 -#define GICC_IAR 0xC -#define GICC_EOIR 0x10 -#define GICC_RPR 0x14 -#define GICC_HPPIR 0x18 -#define GICC_AHPPIR 0x28 -#define GICC_IIDR 0xFC -#define GICC_DIR 0x1000 +#define GICC_CTLR U(0x0) +#define GICC_PMR U(0x4) +#define GICC_BPR U(0x8) +#define GICC_IAR U(0xC) +#define GICC_EOIR U(0x10) +#define GICC_RPR U(0x14) +#define GICC_HPPIR U(0x18) +#define GICC_AHPPIR U(0x28) +#define GICC_IIDR U(0xFC) +#define GICC_DIR U(0x1000) #define GICC_PRIODROP GICC_EOIR /* GICC_CTLR bit definitions */ -#define EOI_MODE_NS (1 << 10) -#define EOI_MODE_S (1 << 9) -#define IRQ_BYP_DIS_GRP1 (1 << 8) -#define FIQ_BYP_DIS_GRP1 (1 << 7) -#define IRQ_BYP_DIS_GRP0 (1 << 6) -#define FIQ_BYP_DIS_GRP0 (1 << 5) -#define CBPR (1 << 4) +#define EOI_MODE_NS BIT_32(10) +#define EOI_MODE_S BIT_32(9) +#define IRQ_BYP_DIS_GRP1 BIT_32(8) +#define FIQ_BYP_DIS_GRP1 BIT_32(7) +#define IRQ_BYP_DIS_GRP0 BIT_32(6) +#define FIQ_BYP_DIS_GRP0 BIT_32(5) +#define CBPR BIT_32(4) #define FIQ_EN_SHIFT 3 -#define FIQ_EN_BIT (1 << FIQ_EN_SHIFT) -#define ACK_CTL (1 << 2) +#define FIQ_EN_BIT BIT_32(FIQ_EN_SHIFT) +#define ACK_CTL BIT_32(2) /* GICC_IIDR bit masks and shifts */ #define GICC_IIDR_PID_SHIFT 20 @@ -83,36 +83,36 @@ #define GICC_IIDR_REV_SHIFT 12 #define GICC_IIDR_IMP_SHIFT 0 -#define GICC_IIDR_PID_MASK 0xfff -#define GICC_IIDR_ARCH_MASK 0xf -#define GICC_IIDR_REV_MASK 0xf -#define GICC_IIDR_IMP_MASK 0xfff +#define GICC_IIDR_PID_MASK U(0xfff) +#define GICC_IIDR_ARCH_MASK U(0xf) +#define GICC_IIDR_REV_MASK U(0xf) +#define GICC_IIDR_IMP_MASK U(0xfff) /* HYP view virtual CPU Interface registers */ -#define GICH_CTL 0x0 -#define GICH_VTR 0x4 -#define GICH_ELRSR0 0x30 -#define GICH_ELRSR1 0x34 -#define GICH_APR0 0xF0 -#define GICH_LR_BASE 0x100 +#define GICH_CTL U(0x0) +#define GICH_VTR U(0x4) +#define GICH_ELRSR0 U(0x30) +#define GICH_ELRSR1 U(0x34) +#define GICH_APR0 U(0xF0) +#define GICH_LR_BASE U(0x100) /* Virtual CPU Interface registers */ -#define GICV_CTL 0x0 -#define GICV_PRIMASK 0x4 -#define GICV_BP 0x8 -#define GICV_INTACK 0xC -#define GICV_EOI 0x10 -#define GICV_RUNNINGPRI 0x14 -#define GICV_HIGHESTPEND 0x18 -#define GICV_DEACTIVATE 0x1000 +#define GICV_CTL U(0x0) +#define GICV_PRIMASK U(0x4) +#define GICV_BP U(0x8) +#define GICV_INTACK U(0xC) +#define GICV_EOI U(0x10) +#define GICV_RUNNINGPRI U(0x14) +#define GICV_HIGHESTPEND U(0x18) +#define GICV_DEACTIVATE U(0x1000) /* GICD_CTLR bit definitions */ #define CTLR_ENABLE_G1_SHIFT 1 -#define CTLR_ENABLE_G1_MASK 0x1 -#define CTLR_ENABLE_G1_BIT (1 << CTLR_ENABLE_G1_SHIFT) +#define CTLR_ENABLE_G1_MASK U(0x1) +#define CTLR_ENABLE_G1_BIT BIT_32(CTLR_ENABLE_G1_SHIFT) /* Interrupt ID mask for HPPIR, AHPPIR, IAR and AIAR CPU Interface registers */ -#define INT_ID_MASK 0x3ff +#define INT_ID_MASK U(0x3ff) #ifndef __ASSEMBLY__ diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h index c13a5c9e..c9e28bae 100644 --- a/include/drivers/arm/gicv3.h +++ b/include/drivers/arm/gicv3.h @@ -11,35 +11,35 @@ * GICv3 miscellaneous definitions ******************************************************************************/ /* Interrupt group definitions */ -#define INTR_GROUP1S 0 -#define INTR_GROUP0 1 -#define INTR_GROUP1NS 2 +#define INTR_GROUP1S U(0) +#define INTR_GROUP0 U(1) +#define INTR_GROUP1NS U(2) /* Interrupt IDs reported by the HPPIR and IAR registers */ -#define PENDING_G1S_INTID 1020 -#define PENDING_G1NS_INTID 1021 +#define PENDING_G1S_INTID U(1020) +#define PENDING_G1NS_INTID U(1021) /* Constant to categorize LPI interrupt */ -#define MIN_LPI_ID 8192 +#define MIN_LPI_ID U(8192) /* GICv3 can only target up to 16 PEs with SGI */ -#define GICV3_MAX_SGI_TARGETS 16 +#define GICV3_MAX_SGI_TARGETS U(16) /******************************************************************************* * GICv3 specific Distributor interface register offsets and constants. ******************************************************************************/ -#define GICD_STATUSR 0x10 -#define GICD_SETSPI_NSR 0x40 -#define GICD_CLRSPI_NSR 0x48 -#define GICD_SETSPI_SR 0x50 -#define GICD_CLRSPI_SR 0x50 -#define GICD_IGRPMODR 0xd00 +#define GICD_STATUSR U(0x10) +#define GICD_SETSPI_NSR U(0x40) +#define GICD_CLRSPI_NSR U(0x48) +#define GICD_SETSPI_SR U(0x50) +#define GICD_CLRSPI_SR U(0x50) +#define GICD_IGRPMODR U(0xd00) /* * GICD_IROUTER<n> register is at 0x6000 + 8n, where n is the interrupt id and * n >= 32, making the effective offset as 0x6100. */ -#define GICD_IROUTER 0x6000 -#define GICD_PIDR2_GICV3 0xffe8 +#define GICD_IROUTER U(0x6000) +#define GICD_PIDR2_GICV3 U(0xffe8) #define IGRPMODR_SHIFT 5 @@ -52,29 +52,29 @@ #define CTLR_E1NWF_SHIFT 7 #define GICD_CTLR_RWP_SHIFT 31 -#define CTLR_ENABLE_G1NS_MASK 0x1 -#define CTLR_ENABLE_G1S_MASK 0x1 -#define CTLR_ARE_S_MASK 0x1 -#define CTLR_ARE_NS_MASK 0x1 -#define CTLR_DS_MASK 0x1 -#define CTLR_E1NWF_MASK 0x1 -#define GICD_CTLR_RWP_MASK 0x1 - -#define CTLR_ENABLE_G1NS_BIT (1 << CTLR_ENABLE_G1NS_SHIFT) -#define CTLR_ENABLE_G1S_BIT (1 << CTLR_ENABLE_G1S_SHIFT) -#define CTLR_ARE_S_BIT (1 << CTLR_ARE_S_SHIFT) -#define CTLR_ARE_NS_BIT (1 << CTLR_ARE_NS_SHIFT) -#define CTLR_DS_BIT (1 << CTLR_DS_SHIFT) -#define CTLR_E1NWF_BIT (1 << CTLR_E1NWF_SHIFT) -#define GICD_CTLR_RWP_BIT (1 << GICD_CTLR_RWP_SHIFT) +#define CTLR_ENABLE_G1NS_MASK U(0x1) +#define CTLR_ENABLE_G1S_MASK U(0x1) +#define CTLR_ARE_S_MASK U(0x1) +#define CTLR_ARE_NS_MASK U(0x1) +#define CTLR_DS_MASK U(0x1) +#define CTLR_E1NWF_MASK U(0x1) +#define GICD_CTLR_RWP_MASK U(0x1) + +#define CTLR_ENABLE_G1NS_BIT BIT_32(CTLR_ENABLE_G1NS_SHIFT) +#define CTLR_ENABLE_G1S_BIT BIT_32(CTLR_ENABLE_G1S_SHIFT) +#define CTLR_ARE_S_BIT BIT_32(CTLR_ARE_S_SHIFT) +#define CTLR_ARE_NS_BIT BIT_32(CTLR_ARE_NS_SHIFT) +#define CTLR_DS_BIT BIT_32(CTLR_DS_SHIFT) +#define CTLR_E1NWF_BIT BIT_32(CTLR_E1NWF_SHIFT) +#define GICD_CTLR_RWP_BIT BIT_32(GICD_CTLR_RWP_SHIFT) /* GICD_IROUTER shifts and masks */ #define IROUTER_SHIFT 0 #define IROUTER_IRM_SHIFT 31 -#define IROUTER_IRM_MASK 0x1 +#define IROUTER_IRM_MASK U(0x1) -#define GICV3_IRM_PE 0 -#define GICV3_IRM_ANY 1 +#define GICV3_IRM_PE U(0) +#define GICV3_IRM_ANY U(1) #define NUM_OF_DIST_REGS 30 @@ -82,54 +82,54 @@ * GICv3 Re-distributor interface registers & constants ******************************************************************************/ #define GICR_PCPUBASE_SHIFT 0x11 -#define GICR_SGIBASE_OFFSET (1 << 0x10) /* 64 KB */ -#define GICR_CTLR 0x0 -#define GICR_TYPER 0x08 -#define GICR_WAKER 0x14 -#define GICR_PROPBASER 0x70 -#define GICR_PENDBASER 0x78 -#define GICR_IGROUPR0 (GICR_SGIBASE_OFFSET + 0x80) -#define GICR_ISENABLER0 (GICR_SGIBASE_OFFSET + 0x100) -#define GICR_ICENABLER0 (GICR_SGIBASE_OFFSET + 0x180) -#define GICR_ISPENDR0 (GICR_SGIBASE_OFFSET + 0x200) -#define GICR_ICPENDR0 (GICR_SGIBASE_OFFSET + 0x280) -#define GICR_ISACTIVER0 (GICR_SGIBASE_OFFSET + 0x300) -#define GICR_ICACTIVER0 (GICR_SGIBASE_OFFSET + 0x380) -#define GICR_IPRIORITYR (GICR_SGIBASE_OFFSET + 0x400) -#define GICR_ICFGR0 (GICR_SGIBASE_OFFSET + 0xc00) -#define GICR_ICFGR1 (GICR_SGIBASE_OFFSET + 0xc04) -#define GICR_IGRPMODR0 (GICR_SGIBASE_OFFSET + 0xd00) -#define GICR_NSACR (GICR_SGIBASE_OFFSET + 0xe00) +#define GICR_SGIBASE_OFFSET U(65536) /* 64 KB */ +#define GICR_CTLR U(0x0) +#define GICR_TYPER U(0x08) +#define GICR_WAKER U(0x14) +#define GICR_PROPBASER U(0x70) +#define GICR_PENDBASER U(0x78) +#define GICR_IGROUPR0 (GICR_SGIBASE_OFFSET + U(0x80)) +#define GICR_ISENABLER0 (GICR_SGIBASE_OFFSET + U(0x100)) +#define GICR_ICENABLER0 (GICR_SGIBASE_OFFSET + U(0x180)) +#define GICR_ISPENDR0 (GICR_SGIBASE_OFFSET + U(0x200)) +#define GICR_ICPENDR0 (GICR_SGIBASE_OFFSET + U(0x280)) +#define GICR_ISACTIVER0 (GICR_SGIBASE_OFFSET + U(0x300)) +#define GICR_ICACTIVER0 (GICR_SGIBASE_OFFSET + U(0x380)) +#define GICR_IPRIORITYR (GICR_SGIBASE_OFFSET + U(0x400)) +#define GICR_ICFGR0 (GICR_SGIBASE_OFFSET + U(0xc00)) +#define GICR_ICFGR1 (GICR_SGIBASE_OFFSET + U(0xc04)) +#define GICR_IGRPMODR0 (GICR_SGIBASE_OFFSET + U(0xd00)) +#define GICR_NSACR (GICR_SGIBASE_OFFSET + U(0xe00)) /* GICR_CTLR bit definitions */ #define GICR_CTLR_UWP_SHIFT 31 -#define GICR_CTLR_UWP_MASK 0x1 -#define GICR_CTLR_UWP_BIT (1U << GICR_CTLR_UWP_SHIFT) +#define GICR_CTLR_UWP_MASK U(0x1) +#define GICR_CTLR_UWP_BIT BIT_32(GICR_CTLR_UWP_SHIFT) #define GICR_CTLR_RWP_SHIFT 3 -#define GICR_CTLR_RWP_MASK 0x1 -#define GICR_CTLR_RWP_BIT (1U << GICR_CTLR_RWP_SHIFT) -#define GICR_CTLR_EN_LPIS_BIT (1U << 0) +#define GICR_CTLR_RWP_MASK U(0x1) +#define GICR_CTLR_RWP_BIT BIT_32(GICR_CTLR_RWP_SHIFT) +#define GICR_CTLR_EN_LPIS_BIT BIT_32(0) /* GICR_WAKER bit definitions */ #define WAKER_CA_SHIFT 2 #define WAKER_PS_SHIFT 1 -#define WAKER_CA_MASK 0x1 -#define WAKER_PS_MASK 0x1 +#define WAKER_CA_MASK U(0x1) +#define WAKER_PS_MASK U(0x1) -#define WAKER_CA_BIT (1 << WAKER_CA_SHIFT) -#define WAKER_PS_BIT (1 << WAKER_PS_SHIFT) +#define WAKER_CA_BIT BIT_32(WAKER_CA_SHIFT) +#define WAKER_PS_BIT BIT_32(WAKER_PS_SHIFT) /* GICR_TYPER bit definitions */ #define TYPER_AFF_VAL_SHIFT 32 #define TYPER_PROC_NUM_SHIFT 8 #define TYPER_LAST_SHIFT 4 -#define TYPER_AFF_VAL_MASK 0xffffffff -#define TYPER_PROC_NUM_MASK 0xffff -#define TYPER_LAST_MASK 0x1 +#define TYPER_AFF_VAL_MASK U(0xffffffff) +#define TYPER_PROC_NUM_MASK U(0xffff) +#define TYPER_LAST_MASK U(0x1) -#define TYPER_LAST_BIT (1 << TYPER_LAST_SHIFT) +#define TYPER_LAST_BIT BIT_32(TYPER_LAST_SHIFT) #define NUM_OF_REDIST_REGS 30 @@ -137,102 +137,120 @@ * GICv3 CPU interface registers & constants ******************************************************************************/ /* ICC_SRE bit definitions*/ -#define ICC_SRE_EN_BIT (1 << 3) -#define ICC_SRE_DIB_BIT (1 << 2) -#define ICC_SRE_DFB_BIT (1 << 1) -#define ICC_SRE_SRE_BIT (1 << 0) +#define ICC_SRE_EN_BIT BIT_32(3) +#define ICC_SRE_DIB_BIT BIT_32(2) +#define ICC_SRE_DFB_BIT BIT_32(1) +#define ICC_SRE_SRE_BIT BIT_32(0) /* ICC_IGRPEN1_EL3 bit definitions */ #define IGRPEN1_EL3_ENABLE_G1NS_SHIFT 0 #define IGRPEN1_EL3_ENABLE_G1S_SHIFT 1 -#define IGRPEN1_EL3_ENABLE_G1NS_BIT (1 << IGRPEN1_EL3_ENABLE_G1NS_SHIFT) -#define IGRPEN1_EL3_ENABLE_G1S_BIT (1 << IGRPEN1_EL3_ENABLE_G1S_SHIFT) +#define IGRPEN1_EL3_ENABLE_G1NS_BIT BIT_32(IGRPEN1_EL3_ENABLE_G1NS_SHIFT) +#define IGRPEN1_EL3_ENABLE_G1S_BIT BIT_32(IGRPEN1_EL3_ENABLE_G1S_SHIFT) /* ICC_IGRPEN0_EL1 bit definitions */ #define IGRPEN1_EL1_ENABLE_G0_SHIFT 0 -#define IGRPEN1_EL1_ENABLE_G0_BIT (1 << IGRPEN1_EL1_ENABLE_G0_SHIFT) +#define IGRPEN1_EL1_ENABLE_G0_BIT BIT_32(IGRPEN1_EL1_ENABLE_G0_SHIFT) /* ICC_HPPIR0_EL1 bit definitions */ #define HPPIR0_EL1_INTID_SHIFT 0 -#define HPPIR0_EL1_INTID_MASK 0xffffff +#define HPPIR0_EL1_INTID_MASK U(0xffffff) /* ICC_HPPIR1_EL1 bit definitions */ #define HPPIR1_EL1_INTID_SHIFT 0 -#define HPPIR1_EL1_INTID_MASK 0xffffff +#define HPPIR1_EL1_INTID_MASK U(0xffffff) /* ICC_IAR0_EL1 bit definitions */ #define IAR0_EL1_INTID_SHIFT 0 -#define IAR0_EL1_INTID_MASK 0xffffff +#define IAR0_EL1_INTID_MASK U(0xffffff) /* ICC_IAR1_EL1 bit definitions */ #define IAR1_EL1_INTID_SHIFT 0 -#define IAR1_EL1_INTID_MASK 0xffffff +#define IAR1_EL1_INTID_MASK U(0xffffff) /* ICC SGI macros */ -#define SGIR_TGT_MASK 0xffff +#define SGIR_TGT_MASK ULL(0xffff) #define SGIR_AFF1_SHIFT 16 #define SGIR_INTID_SHIFT 24 -#define SGIR_INTID_MASK 0xf +#define SGIR_INTID_MASK ULL(0xf) #define SGIR_AFF2_SHIFT 32 #define SGIR_IRM_SHIFT 40 -#define SGIR_IRM_MASK 0x1 +#define SGIR_IRM_MASK ULL(0x1) #define SGIR_AFF3_SHIFT 48 -#define SGIR_AFF_MASK 0xf +#define SGIR_AFF_MASK ULL(0xf) -#define SGIR_IRM_TO_AFF 0 +#define SGIR_IRM_TO_AFF U(0) -#define GICV3_SGIR_VALUE(aff3, aff2, aff1, intid, irm, tgt) \ - ((((uint64_t) (aff3) & SGIR_AFF_MASK) << SGIR_AFF3_SHIFT) | \ - (((uint64_t) (irm) & SGIR_IRM_MASK) << SGIR_IRM_SHIFT) | \ - (((uint64_t) (aff2) & SGIR_AFF_MASK) << SGIR_AFF2_SHIFT) | \ - (((intid) & SGIR_INTID_MASK) << SGIR_INTID_SHIFT) | \ - (((aff1) & SGIR_AFF_MASK) << SGIR_AFF1_SHIFT) | \ - ((tgt) & SGIR_TGT_MASK)) +#define GICV3_SGIR_VALUE(_aff3, _aff2, _aff1, _intid, _irm, _tgt) \ + ((((uint64_t) (_aff3) & SGIR_AFF_MASK) << SGIR_AFF3_SHIFT) | \ + (((uint64_t) (_irm) & SGIR_IRM_MASK) << SGIR_IRM_SHIFT) | \ + (((uint64_t) (_aff2) & SGIR_AFF_MASK) << SGIR_AFF2_SHIFT) | \ + (((_intid) & SGIR_INTID_MASK) << SGIR_INTID_SHIFT) | \ + (((_aff1) & SGIR_AFF_MASK) << SGIR_AFF1_SHIFT) | \ + ((_tgt) & SGIR_TGT_MASK)) /***************************************************************************** * GICv3 ITS registers and constants *****************************************************************************/ -#define GITS_CTLR 0x0 -#define GITS_IIDR 0x4 -#define GITS_TYPER 0x8 -#define GITS_CBASER 0x80 -#define GITS_CWRITER 0x88 -#define GITS_CREADR 0x90 -#define GITS_BASER 0x100 +#define GITS_CTLR U(0x0) +#define GITS_IIDR U(0x4) +#define GITS_TYPER U(0x8) +#define GITS_CBASER U(0x80) +#define GITS_CWRITER U(0x88) +#define GITS_CREADR U(0x90) +#define GITS_BASER U(0x100) /* GITS_CTLR bit definitions */ -#define GITS_CTLR_ENABLED_BIT 1 +#define GITS_CTLR_ENABLED_BIT BIT_32(0) #define GITS_CTLR_QUIESCENT_SHIFT 31 -#define GITS_CTLR_QUIESCENT_BIT (1U << GITS_CTLR_QUIESCENT_SHIFT) +#define GITS_CTLR_QUIESCENT_BIT BIT_32(GITS_CTLR_QUIESCENT_SHIFT) #ifndef __ASSEMBLY__ +#include <arch_helpers.h> #include <gic_common.h> #include <interrupt_props.h> +#include <stdbool.h> #include <stdint.h> #include <utils_def.h> -#define gicv3_is_intr_id_special_identifier(id) \ - (((id) >= PENDING_G1S_INTID) && ((id) <= GIC_SPURIOUS_INTERRUPT)) +static inline bool gicv3_is_intr_id_special_identifier(unsigned int id) +{ + return (id >= PENDING_G1S_INTID) && (id <= GIC_SPURIOUS_INTERRUPT); +} /******************************************************************************* * Helper GICv3 macros for SEL1 ******************************************************************************/ -#define gicv3_acknowledge_interrupt_sel1() read_icc_iar1_el1() &\ - IAR1_EL1_INTID_MASK -#define gicv3_get_pending_interrupt_id_sel1() read_icc_hppir1_el1() &\ - HPPIR1_EL1_INTID_MASK -#define gicv3_end_of_interrupt_sel1(id) write_icc_eoir1_el1(id) +static inline uint32_t gicv3_acknowledge_interrupt_sel1(void) +{ + return (uint32_t)read_icc_iar1_el1() & IAR1_EL1_INTID_MASK; +} +static inline uint32_t gicv3_get_pending_interrupt_id_sel1(void) +{ + return (uint32_t)read_icc_hppir1_el1() & HPPIR1_EL1_INTID_MASK; +} + +static inline void gicv3_end_of_interrupt_sel1(unsigned int id) +{ + write_icc_eoir1_el1(id); +} /******************************************************************************* * Helper GICv3 macros for EL3 ******************************************************************************/ -#define gicv3_acknowledge_interrupt() read_icc_iar0_el1() &\ - IAR0_EL1_INTID_MASK -#define gicv3_end_of_interrupt(id) write_icc_eoir0_el1(id) +static inline uint32_t gicv3_acknowledge_interrupt(void) +{ + return (uint32_t)read_icc_iar0_el1() & IAR0_EL1_INTID_MASK; +} + +static inline void gicv3_end_of_interrupt(unsigned int id) +{ + return write_icc_eoir0_el1(id); +} /* * This macro returns the total number of GICD registers corresponding to @@ -245,7 +263,7 @@ DIV_ROUND_UP_2EVAL(TOTAL_PCPU_INTR_NUM, (1 << reg_name ## _SHIFT)) /* Interrupt ID mask for HPPIR, AHPPIR, IAR and AIAR CPU Interface registers */ -#define INT_ID_MASK 0xffffff +#define INT_ID_MASK U(0xffffff) /******************************************************************************* * This structure describes some of the implementation defined attributes of the @@ -402,7 +420,7 @@ void gicv3_set_interrupt_priority(unsigned int id, unsigned int proc_num, unsigned int priority); void gicv3_set_interrupt_type(unsigned int id, unsigned int proc_num, unsigned int type); -void gicv3_raise_secure_g0_sgi(int sgi_num, u_register_t target); +void gicv3_raise_secure_g0_sgi(unsigned int sgi_num, u_register_t target); void gicv3_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr); void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num); diff --git a/include/drivers/arm/smmu_v3.h b/include/drivers/arm/smmu_v3.h index b7efde46..e3912e31 100644 --- a/include/drivers/arm/smmu_v3.h +++ b/include/drivers/arm/smmu_v3.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,18 +7,19 @@ #ifndef __SMMU_V3_H__ #define __SMMU_V3_H__ +#include <utils_def.h> #include <stdint.h> /* SMMUv3 register offsets from device base */ -#define SMMU_S_IDR1 0x8004 -#define SMMU_S_INIT 0x803c +#define SMMU_S_IDR1 U(0x8004) +#define SMMU_S_INIT U(0x803c) /* SMMU_S_IDR1 register fields */ #define SMMU_S_IDR1_SECURE_IMPL_SHIFT 31 -#define SMMU_S_IDR1_SECURE_IMPL_MASK 0x1 +#define SMMU_S_IDR1_SECURE_IMPL_MASK U(0x1) /* SMMU_S_INIT register fields */ -#define SMMU_S_INIT_INV_ALL_MASK 0x1 +#define SMMU_S_INIT_INV_ALL_MASK U(0x1) int smmuv3_init(uintptr_t smmu_base); diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h index 6f0949bb..f9ed56e2 100644 --- a/include/lib/aarch32/arch.h +++ b/include/lib/aarch32/arch.h @@ -473,6 +473,8 @@ #define CCSIDR p15, 1, c0, c0, 0 #define HTCR p15, 4, c2, c0, 2 #define HMAIR0 p15, 4, c10, c2, 0 +#define ATS1CPR p15, 0, c7, c8, 0 +#define ATS1HR p15, 4, c7, c8, 0 #define DBGOSDLR p14, 0, c1, c3, 4 /* Debug register defines. The format is: coproc, opt1, CRn, CRm, opt2 */ @@ -513,6 +515,7 @@ #define VTTBR_64 p15, 6, c2 #define CNTPCT_64 p15, 0, c14 #define HTTBR_64 p15, 4, c2 +#define PAR_64 p15, 0, c7 /* 64 bit GICv3 CPU Interface system register defines. The format is: coproc, opt1, CRm */ #define ICC_SGI1R_EL1_64 p15, 0, c12 @@ -569,6 +572,12 @@ #define MAKE_MAIR_NORMAL_MEMORY(inner, outer) \ ((inner) | ((outer) << MAIR_NORM_OUTER_SHIFT)) +/* PAR fields */ +#define PAR_F_SHIFT U(0) +#define PAR_F_MASK ULL(0x1) +#define PAR_ADDR_SHIFT U(12) +#define PAR_ADDR_MASK (BIT(40) - ULL(1)) /* 40-bits-wide page address */ + /******************************************************************************* * Definitions for system register interface to AMU for ARMv8.4 onwards ******************************************************************************/ diff --git a/include/lib/aarch32/arch_helpers.h b/include/lib/aarch32/arch_helpers.h index 8eda5cbd..6369a5d7 100644 --- a/include/lib/aarch32/arch_helpers.h +++ b/include/lib/aarch32/arch_helpers.h @@ -276,6 +276,10 @@ DEFINE_COPROCR_RW_FUNCS(hdcr, HDCR) DEFINE_COPROCR_RW_FUNCS(cnthp_ctl, CNTHP_CTL) DEFINE_COPROCR_READ_FUNC(pmcr, PMCR) +DEFINE_COPROCR_RW_FUNCS(ats1cpr, ATS1CPR) +DEFINE_COPROCR_RW_FUNCS(ats1hr, ATS1HR) +DEFINE_COPROCR_RW_FUNCS_64(par, PAR_64) + DEFINE_COPROCR_RW_FUNCS(nsacr, NSACR) /* AArch32 coproc registers for 32bit MMU descriptor support */ @@ -333,6 +337,17 @@ DEFINE_DCOP_PARAM_FUNC(cvac, DCCMVAC) ((GET_M32(read_cpsr()) == MODE32_mon) || \ (IS_IN_SECURE() && (GET_M32(read_cpsr()) != MODE32_usr))) +static inline unsigned int get_current_el(void) +{ + if (IS_IN_EL3()) { + return 3U; + } else if (IS_IN_EL2()) { + return 2U; + } else { + return 1U; + } +} + /* Macros for compatibility with AArch64 system registers */ #define read_mpidr_el1() read_mpidr() diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h index 067c374a..d90061f2 100644 --- a/include/lib/aarch64/arch_helpers.h +++ b/include/lib/aarch64/arch_helpers.h @@ -155,7 +155,9 @@ DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e1r) DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e1w) DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e0r) DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e0w) +DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e1r) DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e2r) +DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e3r) void flush_dcache_range(uintptr_t addr, size_t size); void clean_dcache_range(uintptr_t addr, size_t size); @@ -353,6 +355,12 @@ DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc1_el1, ERXMISC1_EL1) #define IS_IN_EL1() IS_IN_EL(1) #define IS_IN_EL3() IS_IN_EL(3) +#define IS_IN_EL3() IS_IN_EL(3) + +static inline unsigned int get_current_el(void) +{ + return GET_EL(read_CurrentEl()); +} /* * Check if an EL is implemented from AA64PFR0 register fields. 'el' argument diff --git a/include/plat/arm/common/arm_config.h b/include/plat/arm/common/arm_config.h index 02e04fd3..44610bd9 100644 --- a/include/plat/arm/common/arm_config.h +++ b/include/plat/arm/common/arm_config.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,19 +9,21 @@ #include <stdint.h> #include <utils_def.h> -enum arm_config_flags { - /* Whether Base memory map is in use */ - ARM_CONFIG_BASE_MMAP = BIT(1), - /* Whether TZC should be configured */ - ARM_CONFIG_HAS_TZC = BIT(2), - /* FVP model has shifted affinity */ - ARM_CONFIG_FVP_SHIFTED_AFF = BIT(3), - /* FVP model has SMMUv3 affinity */ - ARM_CONFIG_FVP_HAS_SMMUV3 = BIT(4), - /* FVP model has CCI (400 or 500/550) devices */ - ARM_CONFIG_FVP_HAS_CCI400 = BIT(5), - ARM_CONFIG_FVP_HAS_CCI5XX = BIT(6), -}; +/* Whether Base memory map is in use */ +#define ARM_CONFIG_BASE_MMAP BIT(1) + +/* Whether TZC should be configured */ +#define ARM_CONFIG_HAS_TZC BIT(2) + +/* FVP model has shifted affinity */ +#define ARM_CONFIG_FVP_SHIFTED_AFF BIT(3) + +/* FVP model has SMMUv3 affinity */ +#define ARM_CONFIG_FVP_HAS_SMMUV3 BIT(4) + +/* FVP model has CCI (400 or 500/550) devices */ +#define ARM_CONFIG_FVP_HAS_CCI400 BIT(5) +#define ARM_CONFIG_FVP_HAS_CCI5XX BIT(6) typedef struct arm_config { unsigned long flags; diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 5da8cdb4..ea9d811c 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -186,25 +186,25 @@ * as Group 0 interrupts. */ #define ARM_G1S_IRQ_PROPS(grp) \ - INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \ + INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, (grp), \ GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, (grp), \ GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, (grp), \ GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, (grp), \ GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, (grp), \ GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, (grp), \ GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, (grp), \ GIC_INTR_CFG_EDGE) #define ARM_G0_IRQ_PROPS(grp) \ - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, PLAT_SDEI_NORMAL_PRI, grp, \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, PLAT_SDEI_NORMAL_PRI, (grp), \ GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, (grp), \ GIC_INTR_CFG_EDGE) #define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \ diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 2812bdaa..ee5fe4f9 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -105,7 +105,7 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep) if (EP_GET_ST(ep->h.attr)) scr_el3 |= SCR_ST_BIT; -#ifndef HANDLE_EA_EL3_FIRST +#if !HANDLE_EA_EL3_FIRST /* * SCR_EL3.EA: Do not route External Abort and SError Interrupt External * to EL3 when executing at a lower EL. When executing at EL3, External diff --git a/lib/libc/assert.c b/lib/libc/assert.c index fa12cb6b..8fa8f721 100644 --- a/lib/libc/assert.c +++ b/lib/libc/assert.c @@ -20,19 +20,23 @@ void __assert(const char *file, unsigned int line, const char *assertion) { printf("ASSERT: %s:%d:%s\n", file, line, assertion); - console_flush(); + backtrace("assert"); + (void)console_flush(); plat_panic_handler(); } #elif PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO void __assert(const char *file, unsigned int line) { printf("ASSERT: %s:%d\n", file, line); - console_flush(); + backtrace("assert"); + (void)console_flush(); plat_panic_handler(); } #else void __assert(void) { + backtrace("assert"); + (void)console_flush(); plat_panic_handler(); } #endif diff --git a/lib/libc/exit.c b/lib/libc/exit.c index b2fde9ca..f4ffe27c 100644 --- a/lib/libc/exit.c +++ b/lib/libc/exit.c @@ -10,7 +10,7 @@ static void (*exitfun)(void); void exit(int status) { - if (exitfun) + if (exitfun != NULL) (*exitfun)(); for (;;) ; @@ -18,7 +18,7 @@ void exit(int status) int atexit(void (*fun)(void)) { - if (exitfun) + if (exitfun != NULL) return -1; exitfun = fun; diff --git a/lib/libc/printf.c b/lib/libc/printf.c index 4f4a722f..4480e94d 100644 --- a/lib/libc/printf.c +++ b/lib/libc/printf.c @@ -6,28 +6,27 @@ #include <assert.h> #include <debug.h> #include <stdarg.h> +#include <stdbool.h> #include <stdint.h> -/*********************************************************** - * The printf implementation for all BL stages - ***********************************************************/ +#define get_num_va_args(_args, _lcount) \ + (((_lcount) > 1) ? va_arg(_args, long long int) : \ + (((_lcount) == 1) ? va_arg(_args, long int) : \ + va_arg(_args, int))) -#define get_num_va_args(_args, _lcount) \ - (((_lcount) > 1) ? va_arg(_args, long long int) : \ - ((_lcount) ? va_arg(_args, long int) : va_arg(_args, int))) - -#define get_unum_va_args(_args, _lcount) \ - (((_lcount) > 1) ? va_arg(_args, unsigned long long int) : \ - ((_lcount) ? va_arg(_args, unsigned long int) : va_arg(_args, unsigned int))) +#define get_unum_va_args(_args, _lcount) \ + (((_lcount) > 1) ? va_arg(_args, unsigned long long int) : \ + (((_lcount) == 1) ? va_arg(_args, unsigned long int) : \ + va_arg(_args, unsigned int))) static int string_print(const char *str) { int count = 0; - assert(str); + assert(str != NULL); - while (*str) { - putchar(*str++); + for ( ; *str != '\0'; str++) { + (void)putchar(*str); count++; } @@ -38,26 +37,30 @@ static int unsigned_num_print(unsigned long long int unum, unsigned int radix, char padc, int padn) { /* Just need enough space to store 64 bit decimal integer */ - unsigned char num_buf[20]; - int i = 0, rem, count = 0; + char num_buf[20]; + int i = 0, count = 0; + unsigned int rem; do { rem = unum % radix; if (rem < 0xa) - num_buf[i++] = '0' + rem; + num_buf[i] = '0' + rem; else - num_buf[i++] = 'a' + (rem - 0xa); - } while (unum /= radix); + num_buf[i] = 'a' + (rem - 0xa); + i++; + unum /= radix; + } while (unum > 0U); if (padn > 0) { - while (i < padn--) { - putchar(padc); + while (i < padn) { + (void)putchar(padc); count++; + padn--; } } while (--i >= 0) { - putchar(num_buf[i]); + (void)putchar(num_buf[i]); count++; } @@ -90,11 +93,11 @@ int vprintf(const char *fmt, va_list args) long long int num; unsigned long long int unum; char *str; - char padc = 0; /* Padding character */ + char padc = '\0'; /* Padding character */ int padn; /* Number of characters to pad */ int count = 0; /* Number of printed characters */ - while (*fmt) { + while (*fmt != '\0') { l_count = 0; padn = 0; @@ -107,7 +110,7 @@ loop: case 'd': num = get_num_va_args(args, l_count); if (num < 0) { - putchar('-'); + (void)putchar('-'); unum = (unsigned long long int)-num; padn--; } else @@ -122,7 +125,7 @@ loop: break; case 'p': unum = (uintptr_t)va_arg(args, void *); - if (unum) { + if (unum > 0U) { count += string_print("0x"); padn -= 2; } @@ -136,7 +139,7 @@ loop: padc, padn); break; case 'z': - if (sizeof(size_t) == 8) + if (sizeof(size_t) == 8U) l_count = 2; fmt++; @@ -155,9 +158,9 @@ loop: padn = 0; fmt++; - while (1) { + for (;;) { char ch = *fmt; - if (ch < '0' || ch > '9') { + if ((ch < '0') || (ch > '9')) { goto loop; } padn = (padn * 10) + (ch - '0'); @@ -170,7 +173,8 @@ loop: fmt++; continue; } - putchar(*fmt++); + (void)putchar(*fmt); + fmt++; count++; } diff --git a/lib/libc/puts.c b/lib/libc/puts.c index 717b5228..2a0ca11c 100644 --- a/lib/libc/puts.c +++ b/lib/libc/puts.c @@ -10,9 +10,10 @@ int puts(const char *s) { int count = 0; - while (*s) { - if (putchar(*s++) == EOF) + while (*s != '\0') { + if (putchar(*s) == EOF) return EOF; + s++; count++; } diff --git a/lib/libc/snprintf.c b/lib/libc/snprintf.c index 0738a869..9bc07b2c 100644 --- a/lib/libc/snprintf.c +++ b/lib/libc/snprintf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,9 +11,12 @@ static void string_print(char **s, size_t n, size_t *chars_printed, const char *str) { - while (*str) { - if (*chars_printed < n) - *(*s)++ = *str; + while (*str != '\0') { + if (*chars_printed < n) { + *(*s) = *str; + (*s)++; + } + (*chars_printed)++; str++; } @@ -23,17 +26,22 @@ static void unsigned_dec_print(char **s, size_t n, size_t *chars_printed, unsigned int unum) { /* Enough for a 32-bit unsigned decimal integer (4294967295). */ - unsigned char num_buf[10]; - int i = 0, rem; + char num_buf[10]; + int i = 0; + unsigned int rem; do { - rem = unum % 10; + rem = unum % 10U; num_buf[i++] = '0' + rem; - } while (unum /= 10); + unum /= 10U; + } while (unum > 0U); while (--i >= 0) { - if (*chars_printed < n) - *(*s)++ = num_buf[i]; + if (*chars_printed < n) { + *(*s) = num_buf[i]; + (*s)++; + } + (*chars_printed)++; } } @@ -58,19 +66,21 @@ int snprintf(char *s, size_t n, const char *fmt, ...) int num; unsigned int unum; char *str; - size_t chars_printed = 0; + size_t chars_printed = 0U; - if (n == 1) { + if (n == 0U) { + /* There isn't space for anything. */ + } else if (n == 1U) { /* Buffer is too small to actually write anything else. */ *s = '\0'; - n = 0; - } else if (n >= 2) { + n = 0U; + } else { /* Reserve space for the terminator character. */ n--; } va_start(args, fmt); - while (*fmt) { + while (*fmt != '\0') { if (*fmt == '%') { fmt++; @@ -81,8 +91,10 @@ int snprintf(char *s, size_t n, const char *fmt, ...) num = va_arg(args, int); if (num < 0) { - if (chars_printed < n) - *s++ = '-'; + if (chars_printed < n) { + *s = '-'; + s++; + } chars_printed++; unum = (unsigned int)-num; @@ -110,16 +122,19 @@ int snprintf(char *s, size_t n, const char *fmt, ...) continue; } - if (chars_printed < n) - *s++ = *fmt; + if (chars_printed < n) { + *s = *fmt; + s++; + } + fmt++; chars_printed++; } va_end(args); - if (n > 0) + if (n > 0U) *s = '\0'; - return chars_printed; + return (int)chars_printed; } diff --git a/maintainers.rst b/maintainers.rst index 73a6527b..ee6682e3 100644 --- a/maintainers.rst +++ b/maintainers.rst @@ -30,6 +30,15 @@ Armv7-A architecture port :M: Etienne Carriere <etienne.carriere@linaro.org> :G: `etienne-lms`_ +Arm System Guidance for Infrastructure / Mobile FVP platforms +------------------------------------------------------------- +:M: Nariman Poushin <nariman.poushin@linaro.org> +:G: `nariman`_ +:F: plat/arm/css/sgi/ +:F: plat/arm/css/sgm/ +:F: plat/arm/board/sgi575/ +:F: plat/arm/board/sgm775/ + eMMC/UFS drivers ---------------- :M: Haojian Zhuang <haojian.zhuang@linaro.org> @@ -186,6 +195,7 @@ Xilinx platform port .. _kostapr: https://github.com/kostapr .. _masahir0y: https://github.com/masahir0y .. _mtk09422: https://github.com/mtk09422 +.. _nariman: https://github.com/npoushin .. _qoriq-open-source: https://github.com/qoriq-open-source .. _rockchip-linux: https://github.com/rockchip-linux .. _shawnguo2: https://github.com/shawnguo2 diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 49f403d2..908da221 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -10,6 +10,9 @@ # poised to handle dependencies, as all build variables would have a default # value by then. +# Use T32 by default +AARCH32_INSTRUCTION_SET := T32 + # The AArch32 Secure Payload to be built as BL32 image AARCH32_SP := none diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c index bcba60a3..ea117085 100644 --- a/plat/arm/board/fvp/fvp_bl31_setup.c +++ b/plat/arm/board/fvp/fvp_bl31_setup.c @@ -34,6 +34,6 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, fvp_interconnect_enable(); /* On FVP RevC, intialize SMMUv3 */ - if (arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) + if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U) smmuv3_init(PLAT_FVP_SMMUV3_BASE); } diff --git a/plat/arm/board/juno/juno_bl2_setup.c b/plat/arm/board/juno/juno_bl2_setup.c index cedef66c..1f483d63 100644 --- a/plat/arm/board/juno/juno_bl2_setup.c +++ b/plat/arm/board/juno/juno_bl2_setup.c @@ -16,7 +16,7 @@ * boot flow as the core comes up in aarch64 and to enter the BL32 image a warm * reset in aarch32 state is required. ******************************************************************************/ -int bl2_plat_handle_post_image_load(unsigned int image_id) +int arm_bl2_plat_handle_post_image_load(unsigned int image_id) { int err = arm_bl2_handle_post_image_load(image_id); diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index 01ae8f34..a8ea075d 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -42,7 +42,7 @@ CASSERT(BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl2_base_overflows); #if LOAD_IMAGE_V2 -#pragma weak bl2_plat_handle_post_image_load +#pragma weak arm_bl2_plat_handle_post_image_load #else /* LOAD_IMAGE_V2 */ @@ -328,11 +328,16 @@ int arm_bl2_handle_post_image_load(unsigned int image_id) * This function can be used by the platforms to update/use image * information for given `image_id`. ******************************************************************************/ -int bl2_plat_handle_post_image_load(unsigned int image_id) +int arm_bl2_plat_handle_post_image_load(unsigned int image_id) { return arm_bl2_handle_post_image_load(image_id); } +int bl2_plat_handle_post_image_load(unsigned int image_id) +{ + return arm_bl2_plat_handle_post_image_load(image_id); +} + #else /* LOAD_IMAGE_V2 */ /******************************************************************************* diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index c7c45b0d..4e16e3b5 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -16,8 +16,6 @@ #include <platform.h> #include <ras.h> -#define BL31_END (uintptr_t)(&__BL31_END__) - /* * Placeholder variables for copying the arguments that have been passed to * BL31 from BL2. @@ -152,7 +150,7 @@ void arm_bl31_early_platform_setup(bl31_params_t *from_bl2, uintptr_t soc_fw_con * Copy BL33 and BL32 (if present), entry point information. * They are stored in Secure RAM, in BL2's address space. */ - while (bl_params) { + while (bl_params != NULL) { if (bl_params->image_id == BL32_IMAGE_ID) bl32_image_ep_info = *bl_params->ep_info; @@ -162,7 +160,7 @@ void arm_bl31_early_platform_setup(bl31_params_t *from_bl2, uintptr_t soc_fw_con bl_params = bl_params->next_params_info; } - if (bl33_image_ep_info.pc == 0) + if (bl33_image_ep_info.pc == 0U) panic(); # else /* LOAD_IMAGE_V2 */ @@ -175,8 +173,8 @@ void arm_bl31_early_platform_setup(bl31_params_t *from_bl2, uintptr_t soc_fw_con assert(from_bl2->h.version >= VERSION_1); /* Dynamic Config is not supported for LOAD_IMAGE_V1 */ - assert(soc_fw_config == 0); - assert(hw_config == 0); + assert(soc_fw_config == 0U); + assert(hw_config == 0U); /* * Copy BL32 (if populated by BL2) and BL33 entry point information. @@ -236,7 +234,7 @@ void arm_bl31_platform_setup(void) /* Enable and initialize the System level generic timer */ mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF, - CNTCR_FCREQ(0) | CNTCR_EN); + CNTCR_FCREQ(0U) | CNTCR_EN); /* Allow access to the System counter timer module */ arm_configure_sys_timer(); 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 5191d69b..10c19142 100644 --- a/plat/arm/common/sp_min/arm_sp_min_setup.c +++ b/plat/arm/common/sp_min/arm_sp_min_setup.c @@ -5,6 +5,7 @@ */ #include <assert.h> +#include <bl_common.h> #include <console.h> #include <debug.h> #include <mmio.h> @@ -13,8 +14,6 @@ #include <platform_def.h> #include <platform_sp_min.h> -#define BL32_END (uintptr_t)(&__BL32_END__) - static entry_point_info_t bl33_image_ep_info; /* Weak definitions may be overridden in specific ARM standard platform */ @@ -181,7 +180,7 @@ void sp_min_platform_setup(void) /* Enable and initialize the System level generic timer */ mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF, - CNTCR_FCREQ(0) | CNTCR_EN); + CNTCR_FCREQ(0U) | CNTCR_EN); /* Allow access to the System counter timer module */ arm_configure_sys_timer(); diff --git a/plat/common/plat_gicv2.c b/plat/common/plat_gicv2.c index 026ea713..2b61834b 100644 --- a/plat/common/plat_gicv2.c +++ b/plat/common/plat_gicv2.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,6 +8,7 @@ #include <gicv2.h> #include <interrupt_mgmt.h> #include <platform.h> +#include <stdbool.h> /* * The following platform GIC functions are weakly defined. They @@ -101,7 +102,7 @@ uint32_t plat_ic_get_interrupt_type(uint32_t id) type = gicv2_get_interrupt_group(id); /* Assume that all secure interrupts are S-EL1 interrupts */ - return type == GICV2_INTR_GROUP1 ? INTR_TYPE_NS : + return (type == GICV2_INTR_GROUP1) ? INTR_TYPE_NS : #if GICV2_G0_FOR_EL3 INTR_TYPE_EL3; #else @@ -130,9 +131,8 @@ void plat_ic_end_of_interrupt(uint32_t id) uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state) { - assert(type == INTR_TYPE_S_EL1 || - type == INTR_TYPE_EL3 || - type == INTR_TYPE_NS); + assert((type == INTR_TYPE_S_EL1) || (type == INTR_TYPE_EL3) || + (type == INTR_TYPE_NS)); assert(sec_state_is_valid(security_state)); @@ -144,8 +144,8 @@ uint32_t plat_interrupt_type_to_line(uint32_t type, * Secure interrupts are signaled using the IRQ line if the FIQ is * not enabled else they are signaled using the FIQ line. */ - return ((gicv2_is_fiq_enabled()) ? __builtin_ctz(SCR_FIQ_BIT) : - __builtin_ctz(SCR_IRQ_BIT)); + return ((gicv2_is_fiq_enabled() != 0U) ? __builtin_ctz(SCR_FIQ_BIT) : + __builtin_ctz(SCR_IRQ_BIT)); } unsigned int plat_ic_get_running_priority(void) @@ -211,7 +211,7 @@ int plat_ic_has_interrupt_type(unsigned int type) void plat_ic_set_interrupt_type(unsigned int id, unsigned int type) { - int gicv2_type = 0; + unsigned int gicv2_type = 0U; /* Map canonical interrupt type to GICv2 type */ switch (type) { @@ -226,7 +226,7 @@ void plat_ic_set_interrupt_type(unsigned int id, unsigned int type) gicv2_type = GICV2_INTR_GROUP1; break; default: - assert(0); + assert(false); break; } @@ -247,7 +247,7 @@ void plat_ic_raise_el3_sgi(int sgi_num, u_register_t target) gicv2_raise_sgi(sgi_num, id); #else - assert(0); + assert(false); #endif } @@ -266,7 +266,7 @@ void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode, proc_num = -1; break; default: - assert(0); + assert(false); break; } diff --git a/plat/common/plat_gicv3.c b/plat/common/plat_gicv3.c index 26a4973f..e43a3550 100644 --- a/plat/common/plat_gicv3.c +++ b/plat/common/plat_gicv3.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,6 +11,7 @@ #include <gicv3.h> #include <interrupt_mgmt.h> #include <platform.h> +#include <stdbool.h> #ifdef IMAGE_BL31 @@ -54,7 +55,7 @@ uint32_t plat_ic_get_pending_interrupt_id(void) assert(IS_IN_EL3()); irqnr = gicv3_get_pending_interrupt_id(); - return (gicv3_is_intr_id_special_identifier(irqnr)) ? + return gicv3_is_intr_id_special_identifier(irqnr) ? INTR_ID_UNAVAILABLE : irqnr; } @@ -73,20 +74,27 @@ uint32_t plat_ic_get_pending_interrupt_id(void) uint32_t plat_ic_get_pending_interrupt_type(void) { unsigned int irqnr; + uint32_t type; assert(IS_IN_EL3()); irqnr = gicv3_get_pending_interrupt_type(); switch (irqnr) { case PENDING_G1S_INTID: - return INTR_TYPE_S_EL1; + type = INTR_TYPE_S_EL1; + break; case PENDING_G1NS_INTID: - return INTR_TYPE_NS; + type = INTR_TYPE_NS; + break; case GIC_SPURIOUS_INTERRUPT: - return INTR_TYPE_INVAL; + type = INTR_TYPE_INVAL; + break; default: - return INTR_TYPE_EL3; + type = INTR_TYPE_EL3; + break; } + + return type; } /* @@ -132,9 +140,9 @@ void plat_ic_end_of_interrupt(uint32_t id) uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state) { - assert(type == INTR_TYPE_S_EL1 || - type == INTR_TYPE_EL3 || - type == INTR_TYPE_NS); + assert((type == INTR_TYPE_S_EL1) || + (type == INTR_TYPE_EL3) || + (type == INTR_TYPE_NS)); assert(sec_state_is_valid(security_state)); assert(IS_IN_EL3()); @@ -227,9 +235,10 @@ void plat_ic_raise_el3_sgi(int sgi_num, u_register_t target) assert(plat_core_pos_by_mpidr(target) >= 0); /* Verify that this is a secure EL3 SGI */ - assert(plat_ic_get_interrupt_type(sgi_num) == INTR_TYPE_EL3); + assert(plat_ic_get_interrupt_type((unsigned int)sgi_num) == + INTR_TYPE_EL3); - gicv3_raise_secure_g0_sgi(sgi_num, target); + gicv3_raise_secure_g0_sgi((unsigned int)sgi_num, target); } void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode, @@ -246,7 +255,7 @@ void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode, irm = GICV3_IRM_ANY; break; default: - assert(0); + assert(false); break; } @@ -274,10 +283,10 @@ unsigned int plat_ic_set_priority_mask(unsigned int mask) unsigned int plat_ic_get_interrupt_id(unsigned int raw) { - unsigned int id = (raw & INT_ID_MASK); + unsigned int id = raw & INT_ID_MASK; - return (gicv3_is_intr_id_special_identifier(id) ? - INTR_ID_UNAVAILABLE : id); + return gicv3_is_intr_id_special_identifier(id) ? + INTR_ID_UNAVAILABLE : id; } #endif #ifdef IMAGE_BL32 diff --git a/plat/common/plat_log_common.c b/plat/common/plat_log_common.c index 30dcb121..49e1c152 100644 --- a/plat/common/plat_log_common.c +++ b/plat/common/plat_log_common.c @@ -1,25 +1,28 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#include <assert.h> #include <debug.h> -#include <platform.h> /* Allow platforms to override the log prefix string */ #pragma weak plat_log_get_prefix -static const char *prefix_str[] = { +static const char *plat_prefix_str[] = { "ERROR: ", "NOTICE: ", "WARNING: ", "INFO: ", "VERBOSE: "}; const char *plat_log_get_prefix(unsigned int log_level) { - if (log_level < LOG_LEVEL_ERROR) - log_level = LOG_LEVEL_ERROR; - else if (log_level > LOG_LEVEL_VERBOSE) - log_level = LOG_LEVEL_VERBOSE; + unsigned int level; - return prefix_str[(log_level/10) - 1]; + if (log_level < LOG_LEVEL_ERROR) { + level = LOG_LEVEL_ERROR; + } else if (log_level > LOG_LEVEL_VERBOSE) { + level = LOG_LEVEL_VERBOSE; + } else { + level = log_level; + } + + return plat_prefix_str[(level / 10U) - 1U]; } diff --git a/plat/layerscape/common/ls_bl31_setup.c b/plat/layerscape/common/ls_bl31_setup.c index 3016f58e..25fe407c 100644 --- a/plat/layerscape/common/ls_bl31_setup.c +++ b/plat/layerscape/common/ls_bl31_setup.c @@ -5,6 +5,7 @@ */ #include <assert.h> +#include <bl_common.h> #include <console.h> #include <mmio.h> #include <gicv2.h> @@ -12,8 +13,6 @@ #include "plat_ls.h" #include "soc.h" -#define BL31_END (uintptr_t)(&__BL31_END__) - /* * Placeholder variables for copying the arguments that have been passed to * BL31 from BL2. @@ -168,7 +167,7 @@ void ls_bl31_platform_setup(void) /* Enable and initialize the System level generic timer */ mmio_write_32(LS1043_SYS_CNTCTL_BASE + CNTCR_OFF, - CNTCR_FCREQ(0) | CNTCR_EN); + CNTCR_FCREQ(0U) | CNTCR_EN); VERBOSE("Leave arm_bl31_platform_setup\n"); } diff --git a/plat/socionext/synquacer/sq_bl31_setup.c b/plat/socionext/synquacer/sq_bl31_setup.c index 30d06e9e..26b8ff1b 100644 --- a/plat/socionext/synquacer/sq_bl31_setup.c +++ b/plat/socionext/synquacer/sq_bl31_setup.c @@ -137,7 +137,7 @@ void bl31_platform_setup(void) /* Enable and initialize the System level generic timer */ mmio_write_32(SQ_SYS_CNTCTL_BASE + CNTCR_OFF, - CNTCR_FCREQ(0) | CNTCR_EN); + CNTCR_FCREQ(0U) | CNTCR_EN); /* Allow access to the System counter timer module */ sq_configure_sys_timer(); diff --git a/plat/socionext/uniphier/uniphier_bl31_setup.c b/plat/socionext/uniphier/uniphier_bl31_setup.c index d9c87bd9..9e28eecd 100644 --- a/plat/socionext/uniphier/uniphier_bl31_setup.c +++ b/plat/socionext/uniphier/uniphier_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,7 +17,6 @@ #include "uniphier.h" -#define BL31_END (unsigned long)(&__BL31_END__) #define BL31_SIZE ((BL31_END) - (BL31_BASE)) static entry_point_info_t bl32_image_ep_info; @@ -70,7 +69,7 @@ void bl31_platform_setup(void) /* Enable and initialize the System level generic timer */ mmio_write_32(UNIPHIER_SYS_CNTCTL_BASE + CNTCR_OFF, - CNTCR_FCREQ(0) | CNTCR_EN); + CNTCR_FCREQ(0U) | CNTCR_EN); } void bl31_plat_arch_setup(void) diff --git a/plat/ti/k3/board/generic/include/board_def.h b/plat/ti/k3/board/generic/include/board_def.h index fe0a062a..1bf58eda 100644 --- a/plat/ti/k3/board/generic/include/board_def.h +++ b/plat/ti/k3/board/generic/include/board_def.h @@ -32,4 +32,7 @@ #define PLAT_MAX_OFF_STATE U(2) #define PLAT_MAX_RET_STATE U(1) +#define PLAT_PROC_START_ID 32 +#define PLAT_PROC_DEVICE_START_ID 202 + #endif /* BOARD_DEF_H */ diff --git a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c new file mode 100644 index 00000000..92414b90 --- /dev/null +++ b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c @@ -0,0 +1,289 @@ +/* + * Texas Instruments K3 Secure Proxy Driver + * Based on Linux and U-Boot implementation + * + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch_helpers.h> +#include <debug.h> +#include <errno.h> +#include <mmio.h> +#include <platform_def.h> +#include <stdlib.h> +#include <utils.h> +#include <utils_def.h> + +#include "sec_proxy.h" + +/* SEC PROXY RT THREAD STATUS */ +#define RT_THREAD_STATUS (0x0) +#define RT_THREAD_STATUS_ERROR_SHIFT (31) +#define RT_THREAD_STATUS_ERROR_MASK BIT(31) +#define RT_THREAD_STATUS_CUR_CNT_SHIFT (0) +#define RT_THREAD_STATUS_CUR_CNT_MASK GENMASK(7, 0) + +/* SEC PROXY SCFG THREAD CTRL */ +#define SCFG_THREAD_CTRL (0x1000) +#define SCFG_THREAD_CTRL_DIR_SHIFT (31) +#define SCFG_THREAD_CTRL_DIR_MASK BIT(31) + +#define SEC_PROXY_THREAD(base, x) ((base) + (0x1000 * (x))) +#define THREAD_IS_RX (1) +#define THREAD_IS_TX (0) + +/** + * struct k3_sec_proxy_desc - Description of secure proxy integration + * @timeout_us: Timeout for communication (in Microseconds) + * @max_msg_size: Message size in bytes + * @data_start_offset: Offset of the First data register of the thread + * @data_end_offset: Offset of the Last data register of the thread + */ +struct k3_sec_proxy_desc { + uint32_t timeout_us; + uint16_t max_msg_size; + uint16_t data_start_offset; + uint16_t data_end_offset; +}; + +/** + * struct k3_sec_proxy_thread - Description of a secure proxy Thread + * @id: Thread ID + * @data: Thread Data path region for target + * @scfg: Secure Config Region for Thread + * @rt: RealTime Region for Thread + */ +struct k3_sec_proxy_thread { + uint32_t id; + uintptr_t data; + uintptr_t scfg; + uintptr_t rt; +}; + +/** + * struct k3_sec_proxy_mbox - Description of a Secure Proxy Instance + * @desc: Description of the SoC integration + * @chans: Array for valid thread instances + */ +struct k3_sec_proxy_mbox { + const struct k3_sec_proxy_desc desc; + struct k3_sec_proxy_thread threads[]; +}; + +/* + * Thread ID #0: DMSC notify + * Thread ID #1: DMSC request response + * Thread ID #2: DMSC request high priority + * Thread ID #3: DMSC request low priority + * Thread ID #4: DMSC notify response + */ +#define SP_THREAD(_x) \ + [_x] = { \ + .id = _x, \ + .data = SEC_PROXY_THREAD(SEC_PROXY_DATA_BASE, _x), \ + .scfg = SEC_PROXY_THREAD(SEC_PROXY_SCFG_BASE, _x), \ + .rt = SEC_PROXY_THREAD(SEC_PROXY_RT_BASE, _x), \ + } + +static struct k3_sec_proxy_mbox spm = { + .desc = { + .timeout_us = SEC_PROXY_TIMEOUT_US, + .max_msg_size = SEC_PROXY_MAX_MESSAGE_SIZE, + .data_start_offset = 0x4, + .data_end_offset = 0x3C, + }, + .threads = { + SP_THREAD(SP_NOTIFY), + SP_THREAD(SP_RESPONSE), + SP_THREAD(SP_HIGH_PRIORITY), + SP_THREAD(SP_LOW_PRIORITY), + SP_THREAD(SP_NOTIFY_RESP), + }, +}; + +/** + * struct sec_msg_hdr - Message header for secure messages and responses + * @checksum: CRC of message for integrity checking + */ +union sec_msg_hdr { + struct { + uint16_t checksum; + uint16_t reserved; + } __packed; + uint32_t data; +}; + +/** + * k3_sec_proxy_verify_thread() - Verify thread status before + * sending/receiving data + * @spt: Pointer to Secure Proxy thread description + * @dir: Direction of the thread + * + * Return: 0 if all goes well, else appropriate error message + */ +static inline int k3_sec_proxy_verify_thread(struct k3_sec_proxy_thread *spt, + uint32_t dir) +{ + /* Check for any errors already available */ + if (mmio_read_32(spt->rt + RT_THREAD_STATUS) & + RT_THREAD_STATUS_ERROR_MASK) { + ERROR("Thread %d is corrupted, cannot send data\n", spt->id); + return -EINVAL; + } + + /* Make sure thread is configured for right direction */ + if ((mmio_read_32(spt->scfg + SCFG_THREAD_CTRL) & SCFG_THREAD_CTRL_DIR_MASK) + != (dir << SCFG_THREAD_CTRL_DIR_SHIFT)) { + if (dir) + ERROR("Trying to receive data on tx Thread %d\n", + spt->id); + else + ERROR("Trying to send data on rx Thread %d\n", + spt->id); + return -EINVAL; + } + + /* Check the message queue before sending/receiving data */ + uint32_t tick_start = (uint32_t)read_cntpct_el0(); + uint32_t ticks_per_us = SYS_COUNTER_FREQ_IN_TICKS / 1000000; + while (!(mmio_read_32(spt->rt + RT_THREAD_STATUS) & RT_THREAD_STATUS_CUR_CNT_MASK)) { + VERBOSE("Waiting for thread %d to clear\n", spt->id); + if (((uint32_t)read_cntpct_el0() - tick_start) > + (spm.desc.timeout_us * ticks_per_us)) { + ERROR("Timeout waiting for thread %d to clear\n", spt->id); + return -ETIMEDOUT; + } + } + + return 0; +} + +/** + * k3_sec_proxy_send() - Send data over a Secure Proxy thread + * @id: Channel Identifier + * @msg: Pointer to k3_sec_proxy_msg + * + * Return: 0 if all goes well, else appropriate error message + */ +int k3_sec_proxy_send(enum k3_sec_proxy_chan_id id, const struct k3_sec_proxy_msg *msg) +{ + struct k3_sec_proxy_thread *spt = &spm.threads[id]; + union sec_msg_hdr secure_header; + int num_words, trail_bytes, i, ret; + uintptr_t data_reg; + + ret = k3_sec_proxy_verify_thread(spt, THREAD_IS_TX); + if (ret) { + ERROR("Thread %d verification failed (%d)\n", spt->id, ret); + return ret; + } + + /* Check the message size */ + if (msg->len + sizeof(secure_header) > spm.desc.max_msg_size) { + ERROR("Thread %d message length %lu > max msg size\n", + spt->id, msg->len); + return -EINVAL; + } + + /* TODO: Calculate checksum */ + secure_header.checksum = 0; + + /* Send the secure header */ + data_reg = spm.desc.data_start_offset; + mmio_write_32(spt->data + data_reg, secure_header.data); + data_reg += sizeof(uint32_t); + + /* Send whole words */ + num_words = msg->len / sizeof(uint32_t); + for (i = 0; i < num_words; i++) { + mmio_write_32(spt->data + data_reg, ((uint32_t *)msg->buf)[i]); + data_reg += sizeof(uint32_t); + } + + /* Send remaining bytes */ + trail_bytes = msg->len % sizeof(uint32_t); + if (trail_bytes) { + uint32_t data_trail = 0; + + i = msg->len - trail_bytes; + while (trail_bytes--) { + data_trail <<= 8; + data_trail |= msg->buf[i++]; + } + + mmio_write_32(spt->data + data_reg, data_trail); + data_reg += sizeof(uint32_t); + } + /* + * 'data_reg' indicates next register to write. If we did not already + * write on tx complete reg(last reg), we must do so for transmit + */ + if (data_reg <= spm.desc.data_end_offset) + mmio_write_32(spt->data + spm.desc.data_end_offset, 0); + + VERBOSE("Message successfully sent on thread %ud\n", id); + + return 0; +} + +/** + * k3_sec_proxy_recv() - Receive data from a Secure Proxy thread + * @id: Channel Identifier + * @msg: Pointer to k3_sec_proxy_msg + * + * Return: 0 if all goes well, else appropriate error message + */ +int k3_sec_proxy_recv(uint32_t id, struct k3_sec_proxy_msg *msg) +{ + struct k3_sec_proxy_thread *spt = &spm.threads[id]; + union sec_msg_hdr secure_header; + uintptr_t data_reg; + int num_words, trail_bytes, i, ret; + + ret = k3_sec_proxy_verify_thread(spt, THREAD_IS_RX); + if (ret) { + ERROR("Thread %d verification failed (%d)\n", spt->id, ret); + return ret; + } + + /* Read secure header */ + data_reg = spm.desc.data_start_offset; + secure_header.data = mmio_read_32(spt->data + data_reg); + data_reg += sizeof(uint32_t); + + /* Read whole words */ + num_words = msg->len / sizeof(uint32_t); + for (i = 0; i < num_words; i++) { + ((uint32_t *)msg->buf)[i] = mmio_read_32(spt->data + data_reg); + data_reg += sizeof(uint32_t); + } + + /* Read remaining bytes */ + trail_bytes = msg->len % sizeof(uint32_t); + if (trail_bytes) { + uint32_t data_trail = mmio_read_32(spt->data + data_reg); + data_reg += sizeof(uint32_t); + + i = msg->len - trail_bytes; + while (trail_bytes--) { + msg->buf[i] = data_trail & 0xff; + data_trail >>= 8; + } + } + + /* + * 'data_reg' indicates next register to read. If we did not already + * read on rx complete reg(last reg), we must do so for receive + */ + if (data_reg <= spm.desc.data_end_offset) + mmio_read_32(spt->data + spm.desc.data_end_offset); + + /* TODO: Verify checksum */ + (void)secure_header.checksum; + + VERBOSE("Message successfully received from thread %ud\n", id); + + return 0; +} diff --git a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h new file mode 100644 index 00000000..facfd198 --- /dev/null +++ b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h @@ -0,0 +1,58 @@ +/* + * Texas Instruments K3 Secure Proxy Driver + * Based on Linux and U-Boot implementation + * + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef K3_SEC_PROXY_H +#define K3_SEC_PROXY_H + +#include <stdint.h> + +/** + * enum k3_sec_proxy_chan_id - Secure Proxy thread IDs + * + * These the available IDs used in k3_sec_proxy_{send,recv}() + */ +enum k3_sec_proxy_chan_id { + SP_NOTIFY = 0, + SP_RESPONSE, + SP_HIGH_PRIORITY, + SP_LOW_PRIORITY, + SP_NOTIFY_RESP, +}; + +/** + * struct k3_sec_proxy_msg - Secure proxy message structure + * @len: Length of data in the Buffer + * @buf: Buffer pointer + * + * This is the structure for data used in k3_sec_proxy_{send,recv}() + */ +struct k3_sec_proxy_msg { + size_t len; + uint8_t *buf; +}; + +/** + * k3_sec_proxy_send() - Send data over a Secure Proxy thread + * @id: Channel Identifier + * @msg: Pointer to k3_sec_proxy_msg + * + * Return: 0 if all goes well, else appropriate error message + */ +int k3_sec_proxy_send(enum k3_sec_proxy_chan_id id, const struct k3_sec_proxy_msg *msg); + +/** + * k3_sec_proxy_recv() - Receive data from a Secure Proxy thread + * @id: Channel Identifier + * @msg: Pointer to k3_sec_proxy_msg + * + * Return: 0 if all goes well, else appropriate error message + */ +int k3_sec_proxy_recv(enum k3_sec_proxy_chan_id id, struct k3_sec_proxy_msg *msg); + +#endif /* K3_SEC_PROXY_H */ diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c new file mode 100644 index 00000000..7ba0267d --- /dev/null +++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c @@ -0,0 +1,1482 @@ +/* + * Texas Instruments System Control Interface Driver + * Based on Linux and U-Boot implementation + * + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <debug.h> +#include <errno.h> +#include <platform_def.h> +#include <stdbool.h> +#include <stddef.h> +#include <string.h> + +#include <sec_proxy.h> + +#include "ti_sci_protocol.h" +#include "ti_sci.h" + +/** + * struct ti_sci_desc - Description of SoC integration + * @host_id: Host identifier representing the compute entity + * @max_msg_size: Maximum size of data per message that can be handled + */ +struct ti_sci_desc { + uint8_t host_id; + int max_msg_size; +}; + +/** + * struct ti_sci_info - Structure representing a TI SCI instance + * @desc: SoC description for this instance + * @seq: Seq id used for verification for tx and rx message + */ +struct ti_sci_info { + const struct ti_sci_desc desc; + uint8_t seq; +}; + +static struct ti_sci_info info = { + .desc = { + .host_id = TI_SCI_HOST_ID, + .max_msg_size = TI_SCI_MAX_MESSAGE_SIZE, + }, + .seq = 0x0a, +}; + +/** + * struct ti_sci_xfer - Structure representing a message flow + * @tx_message: Transmit message + * @rx_message: Receive message + */ +struct ti_sci_xfer { + struct k3_sec_proxy_msg tx_message; + struct k3_sec_proxy_msg rx_message; +}; + +/** + * ti_sci_setup_one_xfer() - Setup one message type + * + * @msg_type: Message type + * @msg_flags: Flag to set for the message + * @tx_buf: Buffer to be sent to mailbox channel + * @tx_message_size: transmit message size + * @rx_buf: Buffer to be received from mailbox channel + * @rx_message_size: receive message size + * + * Helper function which is used by various command functions that are + * exposed to clients of this driver for allocating a message traffic event. + * + * Return: 0 if all goes well, else appropriate error message + */ +static int ti_sci_setup_one_xfer(uint16_t msg_type, uint32_t msg_flags, + void *tx_buf, + size_t tx_message_size, + void *rx_buf, + size_t rx_message_size, + struct ti_sci_xfer *xfer) +{ + struct ti_sci_msg_hdr *hdr; + + /* Ensure we have sane transfer sizes */ + if (rx_message_size > info.desc.max_msg_size || + tx_message_size > info.desc.max_msg_size || + rx_message_size < sizeof(*hdr) || + tx_message_size < sizeof(*hdr)) + return -ERANGE; + + info.seq++; + + hdr = (struct ti_sci_msg_hdr *)tx_buf; + hdr->seq = info.seq; + hdr->type = msg_type; + hdr->host = info.desc.host_id; + hdr->flags = msg_flags; + + xfer->tx_message.buf = tx_buf; + xfer->tx_message.len = tx_message_size; + + xfer->rx_message.buf = rx_buf; + xfer->rx_message.len = rx_message_size; + + return 0; +} + +/** + * ti_sci_get_response() - Receive response from mailbox channel + * + * @xfer: Transfer to initiate and wait for response + * @chan: Channel to receive the response + * + * Return: 0 if all goes well, else appropriate error message + */ +static inline int ti_sci_get_response(struct ti_sci_xfer *xfer, + enum k3_sec_proxy_chan_id chan) +{ + struct k3_sec_proxy_msg *msg = &xfer->rx_message; + struct ti_sci_msg_hdr *hdr; + int ret; + + /* Receive the response */ + ret = k3_sec_proxy_recv(chan, msg); + if (ret) { + ERROR("Message receive failed (%d)\n", ret); + return ret; + } + + /* msg is updated by Secure Proxy driver */ + hdr = (struct ti_sci_msg_hdr *)msg->buf; + + /* Sanity check for message response */ + if (hdr->seq != info.seq) { + ERROR("Message for %d is not expected\n", hdr->seq); + return -EINVAL; + } + + if (msg->len > info.desc.max_msg_size) { + ERROR("Unable to handle %lu xfer (max %d)\n", + msg->len, info.desc.max_msg_size); + return -EINVAL; + } + + return 0; +} + +/** + * ti_sci_do_xfer() - Do one transfer + * + * @xfer: Transfer to initiate and wait for response + * + * Return: 0 if all goes well, else appropriate error message + */ +static inline int ti_sci_do_xfer(struct ti_sci_xfer *xfer) +{ + struct k3_sec_proxy_msg *msg = &xfer->tx_message; + int ret; + + /* Send the message */ + ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, msg); + if (ret) { + ERROR("Message sending failed (%d)\n", ret); + return ret; + } + + ret = ti_sci_get_response(xfer, SP_RESPONSE); + if (ret) { + ERROR("Failed to get response (%d)\n", ret); + return ret; + } + + return 0; +} + +/** + * ti_sci_get_revision() - Get the revision of the SCI entity + * + * Updates the SCI information in the internal data structure. + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_get_revision(struct ti_sci_msg_resp_version *rev_info) +{ + struct ti_sci_msg_hdr hdr; + struct ti_sci_xfer xfer; + int ret; + + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_VERSION, 0x0, + &hdr, sizeof(hdr), + rev_info, sizeof(*rev_info), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + return 0; +} + +/** + * ti_sci_is_response_ack() - Generic ACK/NACK message check + * + * @r: pointer to response buffer + * + * Return: true if the response was an ACK, else returns false + */ +static inline bool ti_sci_is_response_ack(void *r) +{ + struct ti_sci_msg_hdr *hdr = r; + + return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false; +} + +/** + * ti_sci_device_set_state() - Set device state + * + * @id: Device identifier + * @flags: flags to setup for the device + * @state: State to move the device to + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_device_set_state(uint32_t id, uint32_t flags, uint8_t state) +{ + struct ti_sci_msg_req_set_device_state req; + struct ti_sci_msg_hdr resp; + + struct ti_sci_xfer xfer; + int ret; + + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_DEVICE_STATE, + flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.id = id; + req.state = state; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + return 0; +} + +/** + * ti_sci_device_get_state() - Get device state + * + * @id: Device Identifier + * @clcnt: Pointer to Context Loss Count + * @resets: pointer to resets + * @p_state: pointer to p_state + * @c_state: pointer to c_state + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_device_get_state(uint32_t id, uint32_t *clcnt, uint32_t *resets, + uint8_t *p_state, uint8_t *c_state) +{ + struct ti_sci_msg_req_get_device_state req; + struct ti_sci_msg_resp_get_device_state resp; + + struct ti_sci_xfer xfer; + int ret; + + if (!clcnt && !resets && !p_state && !c_state) + return -EINVAL; + + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_DEVICE_STATE, 0, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.id = id; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + if (clcnt) + *clcnt = resp.context_loss_count; + if (resets) + *resets = resp.resets; + if (p_state) + *p_state = resp.programmed_state; + if (c_state) + *c_state = resp.current_state; + + return 0; +} + +/** + * ti_sci_device_get() - Request for device managed by TISCI + * + * @id: Device Identifier + * + * Request for the device - NOTE: the client MUST maintain integrity of + * usage count by balancing get_device with put_device. No refcounting is + * managed by driver for that purpose. + * + * NOTE: The request is for exclusive access for the processor. + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_device_get(uint32_t id) +{ + return ti_sci_device_set_state(id, + MSG_FLAG_DEVICE_EXCLUSIVE, + MSG_DEVICE_SW_STATE_ON); +} + +/** + * ti_sci_device_idle() - Idle a device managed by TISCI + * + * @id: Device Identifier + * + * Request for the device - NOTE: the client MUST maintain integrity of + * usage count by balancing get_device with put_device. No refcounting is + * managed by driver for that purpose. + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_device_idle(uint32_t id) +{ + return ti_sci_device_set_state(id, + MSG_FLAG_DEVICE_EXCLUSIVE, + MSG_DEVICE_SW_STATE_RETENTION); +} + +/** + * ti_sci_device_put() - Release a device managed by TISCI + * + * @id: Device Identifier + * + * Request for the device - NOTE: the client MUST maintain integrity of + * usage count by balancing get_device with put_device. No refcounting is + * managed by driver for that purpose. + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_device_put(uint32_t id) +{ + return ti_sci_device_set_state(id, 0, MSG_DEVICE_SW_STATE_AUTO_OFF); +} + +/** + * ti_sci_device_is_valid() - Is the device valid + * + * @id: Device Identifier + * + * Return: 0 if all goes well and the device ID is valid, else return + * appropriate error + */ +int ti_sci_device_is_valid(uint32_t id) +{ + uint8_t unused; + + /* check the device state which will also tell us if the ID is valid */ + return ti_sci_device_get_state(id, NULL, NULL, NULL, &unused); +} + +/** + * ti_sci_device_get_clcnt() - Get context loss counter + * + * @id: Device Identifier + * @count: Pointer to Context Loss counter to populate + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_device_get_clcnt(uint32_t id, uint32_t *count) +{ + return ti_sci_device_get_state(id, count, NULL, NULL, NULL); +} + +/** + * ti_sci_device_is_idle() - Check if the device is requested to be idle + * + * @id: Device Identifier + * @r_state: true if requested to be idle + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_device_is_idle(uint32_t id, bool *r_state) +{ + int ret; + uint8_t state; + + if (!r_state) + return -EINVAL; + + ret = ti_sci_device_get_state(id, NULL, NULL, &state, NULL); + if (ret) + return ret; + + *r_state = (state == MSG_DEVICE_SW_STATE_RETENTION); + + return 0; +} + +/** + * ti_sci_device_is_stop() - Check if the device is requested to be stopped + * + * @id: Device Identifier + * @r_state: true if requested to be stopped + * @curr_state: true if currently stopped + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_device_is_stop(uint32_t id, bool *r_state, bool *curr_state) +{ + int ret; + uint8_t p_state, c_state; + + if (!r_state && !curr_state) + return -EINVAL; + + ret = ti_sci_device_get_state(id, NULL, NULL, &p_state, &c_state); + if (ret) + return ret; + + if (r_state) + *r_state = (p_state == MSG_DEVICE_SW_STATE_AUTO_OFF); + if (curr_state) + *curr_state = (c_state == MSG_DEVICE_HW_STATE_OFF); + + return 0; +} + +/** + * ti_sci_device_is_on() - Check if the device is requested to be ON + * + * @id: Device Identifier + * @r_state: true if requested to be ON + * @curr_state: true if currently ON and active + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_device_is_on(uint32_t id, bool *r_state, bool *curr_state) +{ + int ret; + uint8_t p_state, c_state; + + if (!r_state && !curr_state) + return -EINVAL; + + ret = + ti_sci_device_get_state(id, NULL, NULL, &p_state, &c_state); + if (ret) + return ret; + + if (r_state) + *r_state = (p_state == MSG_DEVICE_SW_STATE_ON); + if (curr_state) + *curr_state = (c_state == MSG_DEVICE_HW_STATE_ON); + + return 0; +} + +/** + * ti_sci_device_is_trans() - Check if the device is currently transitioning + * + * @id: Device Identifier + * @curr_state: true if currently transitioning + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_device_is_trans(uint32_t id, bool *curr_state) +{ + int ret; + uint8_t state; + + if (!curr_state) + return -EINVAL; + + ret = ti_sci_device_get_state(id, NULL, NULL, NULL, &state); + if (ret) + return ret; + + *curr_state = (state == MSG_DEVICE_HW_STATE_TRANS); + + return 0; +} + +/** + * ti_sci_device_set_resets() - Set resets for device managed by TISCI + * + * @id: Device Identifier + * @reset_state: Device specific reset bit field + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_device_set_resets(uint32_t id, uint32_t reset_state) +{ + struct ti_sci_msg_req_set_device_resets req; + struct ti_sci_msg_hdr resp; + + struct ti_sci_xfer xfer; + int ret; + + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_DEVICE_RESETS, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.id = id; + req.resets = reset_state; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + return 0; +} + +/** + * ti_sci_device_get_resets() - Get reset state for device managed by TISCI + * + * @id: Device Identifier + * @reset_state: Pointer to reset state to populate + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_device_get_resets(uint32_t id, uint32_t *reset_state) +{ + return ti_sci_device_get_state(id, NULL, reset_state, NULL, NULL); +} + +/** + * ti_sci_clock_set_state() - Set clock state helper + * + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request, + * Each device has its own set of clock inputs, This indexes + * which clock input to modify + * @flags: Header flags as needed + * @state: State to request for the clock + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_clock_set_state(uint32_t dev_id, uint8_t clk_id, + uint32_t flags, uint8_t state) +{ + struct ti_sci_msg_req_set_clock_state req; + struct ti_sci_msg_hdr resp; + + struct ti_sci_xfer xfer; + int ret; + + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_CLOCK_STATE, + flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.dev_id = dev_id; + req.clk_id = clk_id; + req.request_state = state; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + return 0; +} + +/** + * ti_sci_clock_get_state() - Get clock state helper + * + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has its own set of clock inputs. This indexes + * which clock input to modify. + * @programmed_state: State requested for clock to move to + * @current_state: State that the clock is currently in + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_clock_get_state(uint32_t dev_id, uint8_t clk_id, + uint8_t *programmed_state, + uint8_t *current_state) +{ + struct ti_sci_msg_req_get_clock_state req; + struct ti_sci_msg_resp_get_clock_state resp; + + struct ti_sci_xfer xfer; + int ret; + + if (!programmed_state && !current_state) + return -EINVAL; + + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_CLOCK_STATE, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.dev_id = dev_id; + req.clk_id = clk_id; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + if (programmed_state) + *programmed_state = resp.programmed_state; + if (current_state) + *current_state = resp.current_state; + + return 0; +} + +/** + * ti_sci_clock_get() - Get control of a clock from TI SCI + + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has its own set of clock inputs. This indexes + * which clock input to modify. + * @needs_ssc: 'true' iff Spread Spectrum clock is desired + * @can_change_freq: 'true' iff frequency change is desired + * @enable_input_term: 'true' iff input termination is desired + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_clock_get(uint32_t dev_id, uint8_t clk_id, + bool needs_ssc, bool can_change_freq, + bool enable_input_term) +{ + uint32_t flags = 0; + + flags |= needs_ssc ? MSG_FLAG_CLOCK_ALLOW_SSC : 0; + flags |= can_change_freq ? MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE : 0; + flags |= enable_input_term ? MSG_FLAG_CLOCK_INPUT_TERM : 0; + + return ti_sci_clock_set_state(dev_id, clk_id, flags, + MSG_CLOCK_SW_STATE_REQ); +} + +/** + * ti_sci_clock_idle() - Idle a clock which is in our control + + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has its own set of clock inputs. This indexes + * which clock input to modify. + * + * NOTE: This clock must have been requested by get_clock previously. + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_clock_idle(uint32_t dev_id, uint8_t clk_id) +{ + return ti_sci_clock_set_state(dev_id, clk_id, 0, + MSG_CLOCK_SW_STATE_UNREQ); +} + +/** + * ti_sci_clock_put() - Release a clock from our control + * + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has its own set of clock inputs. This indexes + * which clock input to modify. + * + * NOTE: This clock must have been requested by get_clock previously. + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_clock_put(uint32_t dev_id, uint8_t clk_id) +{ + return ti_sci_clock_set_state(dev_id, clk_id, 0, + MSG_CLOCK_SW_STATE_AUTO); +} + +/** + * ti_sci_clock_is_auto() - Is the clock being auto managed + * + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has its own set of clock inputs. This indexes + * which clock input to modify. + * @req_state: state indicating if the clock is auto managed + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_clock_is_auto(uint32_t dev_id, uint8_t clk_id, bool *req_state) +{ + uint8_t state = 0; + int ret; + + if (!req_state) + return -EINVAL; + + ret = ti_sci_clock_get_state(dev_id, clk_id, &state, NULL); + if (ret) + return ret; + + *req_state = (state == MSG_CLOCK_SW_STATE_AUTO); + + return 0; +} + +/** + * ti_sci_clock_is_on() - Is the clock ON + * + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has its own set of clock inputs. This indexes + * which clock input to modify. + * @req_state: state indicating if the clock is managed by us and enabled + * @curr_state: state indicating if the clock is ready for operation + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_clock_is_on(uint32_t dev_id, uint8_t clk_id, + bool *req_state, bool *curr_state) +{ + uint8_t c_state = 0, r_state = 0; + int ret; + + if (!req_state && !curr_state) + return -EINVAL; + + ret = ti_sci_clock_get_state(dev_id, clk_id, &r_state, &c_state); + if (ret) + return ret; + + if (req_state) + *req_state = (r_state == MSG_CLOCK_SW_STATE_REQ); + if (curr_state) + *curr_state = (c_state == MSG_CLOCK_HW_STATE_READY); + + return 0; +} + +/** + * ti_sci_clock_is_off() - Is the clock OFF + * + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has its own set of clock inputs. This indexes + * which clock input to modify. + * @req_state: state indicating if the clock is managed by us and disabled + * @curr_state: state indicating if the clock is NOT ready for operation + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_clock_is_off(uint32_t dev_id, uint8_t clk_id, + bool *req_state, bool *curr_state) +{ + uint8_t c_state = 0, r_state = 0; + int ret; + + if (!req_state && !curr_state) + return -EINVAL; + + ret = ti_sci_clock_get_state(dev_id, clk_id, &r_state, &c_state); + if (ret) + return ret; + + if (req_state) + *req_state = (r_state == MSG_CLOCK_SW_STATE_UNREQ); + if (curr_state) + *curr_state = (c_state == MSG_CLOCK_HW_STATE_NOT_READY); + + return 0; +} + +/** + * ti_sci_clock_set_parent() - Set the clock source of a specific device clock + * + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has its own set of clock inputs. This indexes + * which clock input to modify. + * @parent_id: Parent clock identifier to set + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_clock_set_parent(uint32_t dev_id, uint8_t clk_id, uint8_t parent_id) +{ + struct ti_sci_msg_req_set_clock_parent req; + struct ti_sci_msg_hdr resp; + + struct ti_sci_xfer xfer; + int ret; + + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_CLOCK_PARENT, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.dev_id = dev_id; + req.clk_id = clk_id; + req.parent_id = parent_id; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + return 0; +} + +/** + * ti_sci_clock_get_parent() - Get current parent clock source + * + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has its own set of clock inputs. This indexes + * which clock input to modify. + * @parent_id: Current clock parent + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_clock_get_parent(uint32_t dev_id, uint8_t clk_id, uint8_t *parent_id) +{ + struct ti_sci_msg_req_get_clock_parent req; + struct ti_sci_msg_resp_get_clock_parent resp; + + struct ti_sci_xfer xfer; + int ret; + + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_CLOCK_PARENT, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.dev_id = dev_id; + req.clk_id = clk_id; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + *parent_id = resp.parent_id; + + return 0; +} + +/** + * ti_sci_clock_get_num_parents() - Get num parents of the current clk source + * + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has its own set of clock inputs. This indexes + * which clock input to modify. + * @num_parents: Returns he number of parents to the current clock. + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_clock_get_num_parents(uint32_t dev_id, uint8_t clk_id, + uint8_t *num_parents) +{ + struct ti_sci_msg_req_get_clock_num_parents req; + struct ti_sci_msg_resp_get_clock_num_parents resp; + + struct ti_sci_xfer xfer; + int ret; + + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_NUM_CLOCK_PARENTS, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.dev_id = dev_id; + req.clk_id = clk_id; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + *num_parents = resp.num_parents; + + return 0; +} + +/** + * ti_sci_clock_get_match_freq() - Find a good match for frequency + * + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has its own set of clock inputs. This indexes + * which clock input to modify. + * @min_freq: The minimum allowable frequency in Hz. This is the minimum + * allowable programmed frequency and does not account for clock + * tolerances and jitter. + * @target_freq: The target clock frequency in Hz. A frequency will be + * processed as close to this target frequency as possible. + * @max_freq: The maximum allowable frequency in Hz. This is the maximum + * allowable programmed frequency and does not account for clock + * tolerances and jitter. + * @match_freq: Frequency match in Hz response. + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_clock_get_match_freq(uint32_t dev_id, uint8_t clk_id, + uint64_t min_freq, uint64_t target_freq, + uint64_t max_freq, uint64_t *match_freq) +{ + struct ti_sci_msg_req_query_clock_freq req; + struct ti_sci_msg_resp_query_clock_freq resp; + + struct ti_sci_xfer xfer; + int ret; + + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_QUERY_CLOCK_FREQ, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.dev_id = dev_id; + req.clk_id = clk_id; + req.min_freq_hz = min_freq; + req.target_freq_hz = target_freq; + req.max_freq_hz = max_freq; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + *match_freq = resp.freq_hz; + + return 0; +} + +/** + * ti_sci_clock_set_freq() - Set a frequency for clock + * + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has its own set of clock inputs. This indexes + * which clock input to modify. + * @min_freq: The minimum allowable frequency in Hz. This is the minimum + * allowable programmed frequency and does not account for clock + * tolerances and jitter. + * @target_freq: The target clock frequency in Hz. A frequency will be + * processed as close to this target frequency as possible. + * @max_freq: The maximum allowable frequency in Hz. This is the maximum + * allowable programmed frequency and does not account for clock + * tolerances and jitter. + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_clock_set_freq(uint32_t dev_id, uint8_t clk_id, uint64_t min_freq, + uint64_t target_freq, uint64_t max_freq) +{ + struct ti_sci_msg_req_set_clock_freq req; + struct ti_sci_msg_hdr resp; + + struct ti_sci_xfer xfer; + int ret; + + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_CLOCK_FREQ, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + req.dev_id = dev_id; + req.clk_id = clk_id; + req.min_freq_hz = min_freq; + req.target_freq_hz = target_freq; + req.max_freq_hz = max_freq; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + return 0; +} + +/** + * ti_sci_clock_get_freq() - Get current frequency + * + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has its own set of clock inputs. This indexes + * which clock input to modify. + * @freq: Currently frequency in Hz + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_clock_get_freq(uint32_t dev_id, uint8_t clk_id, uint64_t *freq) +{ + struct ti_sci_msg_req_get_clock_freq req; + struct ti_sci_msg_resp_get_clock_freq resp; + + struct ti_sci_xfer xfer; + int ret; + + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_CLOCK_FREQ, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.dev_id = dev_id; + req.clk_id = clk_id; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + *freq = resp.freq_hz; + + return 0; +} + +/** + * ti_sci_core_reboot() - Command to request system reset + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_core_reboot(void) +{ + struct ti_sci_msg_req_reboot req; + struct ti_sci_msg_hdr resp; + + struct ti_sci_xfer xfer; + int ret; + + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SYS_RESET, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + return 0; +} + +/** + * ti_sci_proc_request() - Request a physical processor control + * + * @proc_id: Processor ID this request is for + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_proc_request(uint8_t proc_id) +{ + struct ti_sci_msg_req_proc_request req; + struct ti_sci_msg_hdr resp; + + struct ti_sci_xfer xfer; + int ret; + + ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_REQUEST, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.processor_id = proc_id; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + return 0; +} + +/** + * ti_sci_proc_release() - Release a physical processor control + * + * @proc_id: Processor ID this request is for + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_proc_release(uint8_t proc_id) +{ + struct ti_sci_msg_req_proc_release req; + struct ti_sci_msg_hdr resp; + + struct ti_sci_xfer xfer; + int ret; + + ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_RELEASE, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.processor_id = proc_id; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + return 0; +} + +/** + * ti_sci_proc_handover() - Handover a physical processor control to a host in + * the processor's access control list. + * + * @proc_id: Processor ID this request is for + * @host_id: Host ID to get the control of the processor + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_proc_handover(uint8_t proc_id, uint8_t host_id) +{ + struct ti_sci_msg_req_proc_handover req; + struct ti_sci_msg_hdr resp; + + struct ti_sci_xfer xfer; + int ret; + + ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_HANDOVER, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.processor_id = proc_id; + req.host_id = host_id; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + return 0; +} + +/** + * ti_sci_proc_set_boot_cfg() - Set the processor boot configuration flags + * + * @proc_id: Processor ID this request is for + * @config_flags_set: Configuration flags to be set + * @config_flags_clear: Configuration flags to be cleared + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_proc_set_boot_cfg(uint8_t proc_id, uint64_t bootvector, + uint32_t config_flags_set, + uint32_t config_flags_clear) +{ + struct ti_sci_msg_req_set_proc_boot_config req; + struct ti_sci_msg_hdr resp; + + struct ti_sci_xfer xfer; + int ret; + + ret = ti_sci_setup_one_xfer(TISCI_MSG_SET_PROC_BOOT_CONFIG, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.processor_id = proc_id; + req.bootvector_low = bootvector & TISCI_ADDR_LOW_MASK; + req.bootvector_high = (bootvector & TISCI_ADDR_HIGH_MASK) >> + TISCI_ADDR_HIGH_SHIFT; + req.config_flags_set = config_flags_set; + req.config_flags_clear = config_flags_clear; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + return 0; +} + +/** + * ti_sci_proc_set_boot_ctrl() - Set the processor boot control flags + * + * @proc_id: Processor ID this request is for + * @control_flags_set: Control flags to be set + * @control_flags_clear: Control flags to be cleared + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_proc_set_boot_ctrl(uint8_t proc_id, uint32_t control_flags_set, + uint32_t control_flags_clear) +{ + struct ti_sci_msg_req_set_proc_boot_ctrl req; + struct ti_sci_msg_hdr resp; + + struct ti_sci_xfer xfer; + int ret; + + ret = ti_sci_setup_one_xfer(TISCI_MSG_SET_PROC_BOOT_CTRL, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.processor_id = proc_id; + req.control_flags_set = control_flags_set; + req.control_flags_clear = control_flags_clear; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + return 0; +} + +/** + * ti_sci_proc_auth_boot_image() - Authenticate and load image and then set the + * processor configuration flags + * + * @proc_id: Processor ID this request is for + * @cert_addr: Memory address at which payload image certificate is located + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_proc_auth_boot_image(uint8_t proc_id, uint64_t cert_addr) +{ + struct ti_sci_msg_req_proc_auth_boot_image req; + struct ti_sci_msg_hdr resp; + + struct ti_sci_xfer xfer; + int ret; + + ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_AUTH_BOOT_IMIAGE, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.processor_id = proc_id; + req.cert_addr_low = cert_addr & TISCI_ADDR_LOW_MASK; + req.cert_addr_high = (cert_addr & TISCI_ADDR_HIGH_MASK) >> + TISCI_ADDR_HIGH_SHIFT; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + return 0; +} + +/** + * ti_sci_proc_get_boot_status() - Get the processor boot status + * + * @proc_id: Processor ID this request is for + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_proc_get_boot_status(uint8_t proc_id, uint64_t *bv, + uint32_t *cfg_flags, + uint32_t *ctrl_flags, + uint32_t *sts_flags) +{ + struct ti_sci_msg_req_get_proc_boot_status req; + struct ti_sci_msg_resp_get_proc_boot_status resp; + + struct ti_sci_xfer xfer; + int ret; + + ret = ti_sci_setup_one_xfer(TISCI_MSG_GET_PROC_BOOT_STATUS, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.processor_id = proc_id; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + *bv = (resp.bootvector_low & TISCI_ADDR_LOW_MASK) | + (((uint64_t)resp.bootvector_high << TISCI_ADDR_HIGH_SHIFT) & + TISCI_ADDR_HIGH_MASK); + *cfg_flags = resp.config_flags; + *ctrl_flags = resp.control_flags; + *sts_flags = resp.status_flags; + + return 0; +} + +/** + * ti_sci_init() - Basic initialization + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_init(void) +{ + struct ti_sci_msg_resp_version rev_info; + int ret; + + ret = ti_sci_get_revision(&rev_info); + if (ret) { + ERROR("Unable to communicate with control firmware (%d)\n", ret); + return ret; + } + + INFO("SYSFW ABI: %d.%d (firmware rev 0x%04x '%s')\n", + rev_info.abi_major, rev_info.abi_minor, + rev_info.firmware_revision, + rev_info.firmware_description); + + return 0; +} diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h new file mode 100644 index 00000000..e40ad6bc --- /dev/null +++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h @@ -0,0 +1,208 @@ +/* + * Texas Instruments System Control Interface API + * Based on Linux and U-Boot implementation + * + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __TI_SCI_H +#define __TI_SCI_H + +#include <stdint.h> +#include <stdbool.h> + +/** + * Device control operations + * + * - ti_sci_device_set_state - Set device state helper + * @flags: flags to setup for the device + * @state: State to move the device to + * - ti_sci_device_get_state - Get device state helper + * @clcnt: Pointer to Context Loss Count + * @resets: pointer to resets + * @p_state: pointer to p_state + * @c_state: pointer to c_state + * - ti_sci_device_get - command to request for device managed by TISCI + * - ti_sci_device_idle - Command to idle a device managed by TISCI + * - ti_sci_device_put - command to release a device managed by TISCI + * - ti_sci_device_is_valid - Is the device valid + * - ti_sci_device_get_clcnt - Get context loss counter + * @count: Pointer to Context Loss counter to populate + * - ti_sci_device_is_idle - Check if the device is requested to be idle + * @r_state: true if requested to be idle + * - ti_sci_device_is_stop - Check if the device is requested to be stopped + * @r_state: true if requested to be stopped + * @curr_state: true if currently stopped. + * - ti_sci_device_is_on - Check if the device is requested to be ON + * @r_state: true if requested to be ON + * @curr_state: true if currently ON and active + * - ti_sci_device_is_trans - Check if the device is currently transitioning + * @curr_state: true if currently transitioning. + * - ti_sci_device_set_resets - Command to set resets for + * device managed by TISCI + * @reset_state: Device specific reset bit field + * - ti_sci_device_get_resets - Get reset state for device managed by TISCI + * @reset_state: Pointer to reset state to populate + * + * NOTE: for all these functions, the following are generic in nature: + * @id: Device Identifier + * Returns 0 for successful request, else returns corresponding error message. + * + * Request for the device - NOTE: the client MUST maintain integrity of + * usage count by balancing get_device with put_device. No refcounting is + * managed by driver for that purpose. + */ +int ti_sci_device_set_state(uint32_t id, uint32_t flags, uint8_t state); +int ti_sci_device_get_state(uint32_t id, uint32_t *clcnt, uint32_t *resets, + uint8_t *p_state, uint8_t *c_state); +int ti_sci_device_get(uint32_t id); +int ti_sci_device_idle(uint32_t id); +int ti_sci_device_put(uint32_t id); +int ti_sci_device_is_valid(uint32_t id); +int ti_sci_device_get_clcnt(uint32_t id, uint32_t *count); +int ti_sci_device_is_idle(uint32_t id, bool *r_state); +int ti_sci_device_is_stop(uint32_t id, bool *r_state, bool *curr_state); +int ti_sci_device_is_on(uint32_t id, bool *r_state, bool *curr_state); +int ti_sci_device_is_trans(uint32_t id, bool *curr_state); +int ti_sci_device_set_resets(uint32_t id, uint32_t reset_state); +int ti_sci_device_get_resets(uint32_t id, uint32_t *reset_state); + +/** + * Clock control operations + * + * - ti_sci_clock_set_state - Set clock state helper + * @flags: Header flags as needed + * @state: State to request for the clock. + * - ti_sci_clock_get_state - Get clock state helper + * @programmed_state: State requested for clock to move to + * @current_state: State that the clock is currently in + * - ti_sci_clock_get - Get control of a clock from TI SCI + * @needs_ssc: 'true' iff Spread Spectrum clock is desired + * @can_change_freq: 'true' iff frequency change is desired + * @enable_input_term: 'true' iff input termination is desired + * - ti_sci_clock_idle - Idle a clock which is in our control + * - ti_sci_clock_put - Release a clock from our control + * - ti_sci_clock_is_auto - Is the clock being auto managed + * @req_state: state indicating if the clock is auto managed + * - ti_sci_clock_is_on - Is the clock ON + * @req_state: state indicating if the clock is managed by us and enabled + * @curr_state: state indicating if the clock is ready for operation + * - ti_sci_clock_is_off - Is the clock OFF + * @req_state: state indicating if the clock is managed by us and disabled + * @curr_state: state indicating if the clock is NOT ready for operation + * - ti_sci_clock_set_parent - Set the clock source of a specific device clock + * @parent_id: Parent clock identifier to set + * - ti_sci_clock_get_parent - Get current parent clock source + * @parent_id: Current clock parent + * - ti_sci_clock_get_num_parents - Get num parents of the current clk source + * @num_parents: Returns he number of parents to the current clock. + * - ti_sci_clock_get_match_freq - Find a good match for frequency + * @match_freq: Frequency match in Hz response. + * - ti_sci_clock_set_freq - Set a frequency for clock + * - ti_sci_clock_get_freq - Get current frequency + * @freq: Currently frequency in Hz + * + * NOTE: for all these functions, the following are generic in nature: + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has its own set of clock inputs. This indexes + * which clock input to modify. + * @min_freq: The minimum allowable frequency in Hz. This is the minimum + * allowable programmed frequency and does not account for clock + * tolerances and jitter. + * @target_freq: The target clock frequency in Hz. A frequency will be + * processed as close to this target frequency as possible. + * @max_freq: The maximum allowable frequency in Hz. This is the maximum + * allowable programmed frequency and does not account for clock + * tolerances and jitter. + * Returns 0 for successful request, else returns corresponding error message. + * + * Request for the clock - NOTE: the client MUST maintain integrity of + * usage count by balancing get_clock with put_clock. No refcounting is + * managed by driver for that purpose. + */ +int ti_sci_clock_set_state(uint32_t dev_id, uint8_t clk_id, + uint32_t flags, uint8_t state); +int ti_sci_clock_get_state(uint32_t dev_id, uint8_t clk_id, + uint8_t *programmed_state, uint8_t *current_state); +int ti_sci_clock_get(uint32_t dev_id, uint8_t clk_id, + bool needs_ssc, bool can_change_freq, + bool enable_input_term); +int ti_sci_clock_idle(uint32_t dev_id, uint8_t clk_id); +int ti_sci_clock_put(uint32_t dev_id, uint8_t clk_id); +int ti_sci_clock_is_auto(uint32_t dev_id, uint8_t clk_id, + bool *req_state); +int ti_sci_clock_is_on(uint32_t dev_id, uint8_t clk_id, + bool *req_state, bool *curr_state); +int ti_sci_clock_is_off(uint32_t dev_id, uint8_t clk_id, + bool *req_state, bool *curr_state); +int ti_sci_clock_set_parent(uint32_t dev_id, uint8_t clk_id, + uint8_t parent_id); +int ti_sci_clock_get_parent(uint32_t dev_id, uint8_t clk_id, + uint8_t *parent_id); +int ti_sci_clock_get_num_parents(uint32_t dev_id, uint8_t clk_id, + uint8_t *num_parents); +int ti_sci_clock_get_match_freq(uint32_t dev_id, uint8_t clk_id, + uint64_t min_freq, uint64_t target_freq, + uint64_t max_freq, uint64_t *match_freq); +int ti_sci_clock_set_freq(uint32_t dev_id, uint8_t clk_id, + uint64_t min_freq, uint64_t target_freq, + uint64_t max_freq); +int ti_sci_clock_get_freq(uint32_t dev_id, uint8_t clk_id, uint64_t *freq); + +/** + * Core control operations + * + * - ti_sci_core_reboot() - Command to request system reset + * + * Return: 0 if all went well, else returns appropriate error value. + */ +int ti_sci_core_reboot(void); + +/** + * Processor control operations + * + * - ti_sci_proc_request - Command to request a physical processor control + * - ti_sci_proc_release - Command to release a physical processor control + * - ti_sci_proc_handover - Command to handover a physical processor control to + * a host in the processor's access control list. + * @host_id: Host ID to get the control of the processor + * - ti_sci_proc_set_boot_cfg - Command to set the processor boot configuration flags + * @config_flags_set: Configuration flags to be set + * @config_flags_clear: Configuration flags to be cleared. + * - ti_sci_proc_set_boot_ctrl - Command to set the processor boot control flags + * @control_flags_set: Control flags to be set + * @control_flags_clear: Control flags to be cleared + * - ti_sci_proc_auth_boot_image - Command to authenticate and load the image + * and then set the processor configuration flags. + * @cert_addr: Memory address at which payload image certificate is located. + * - ti_sci_proc_get_boot_status - Command to get the processor boot status + * + * NOTE: for all these functions, the following are generic in nature: + * @proc_id: Processor ID + * Returns 0 for successful request, else returns corresponding error message. + */ +int ti_sci_proc_request(uint8_t proc_id); +int ti_sci_proc_release(uint8_t proc_id); +int ti_sci_proc_handover(uint8_t proc_id, uint8_t host_id); +int ti_sci_proc_set_boot_cfg(uint8_t proc_id, uint64_t bootvector, + uint32_t config_flags_set, + uint32_t config_flags_clear); +int ti_sci_proc_set_boot_ctrl(uint8_t proc_id, uint32_t control_flags_set, + uint32_t control_flags_clear); +int ti_sci_proc_auth_boot_image(uint8_t proc_id, uint64_t cert_addr); +int ti_sci_proc_get_boot_status(uint8_t proc_id, uint64_t *bv, + uint32_t *cfg_flags, + uint32_t *ctrl_flags, + uint32_t *sts_flags); + +/** + * ti_sci_init() - Basic initialization + * + * Return: 0 if all goes good, else appropriate error message. + */ +int ti_sci_init(void); + +#endif /* __TI_SCI_H */ diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h new file mode 100644 index 00000000..2c4b23fc --- /dev/null +++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h @@ -0,0 +1,650 @@ +/* + * Texas Instruments System Control Interface (TISCI) Protocol + * + * Communication protocol with TI SCI hardware + * The system works in a message response protocol + * See: http://processors.wiki.ti.com/index.php/TISCI for details + * + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __TI_SCI_PROTOCOL_H +#define __TI_SCI_PROTOCOL_H + +#include <stdint.h> + +/* Generic Messages */ +#define TI_SCI_MSG_ENABLE_WDT 0x0000 +#define TI_SCI_MSG_WAKE_RESET 0x0001 +#define TI_SCI_MSG_VERSION 0x0002 +#define TI_SCI_MSG_WAKE_REASON 0x0003 +#define TI_SCI_MSG_GOODBYE 0x0004 +#define TI_SCI_MSG_SYS_RESET 0x0005 + +/* Device requests */ +#define TI_SCI_MSG_SET_DEVICE_STATE 0x0200 +#define TI_SCI_MSG_GET_DEVICE_STATE 0x0201 +#define TI_SCI_MSG_SET_DEVICE_RESETS 0x0202 + +/* Clock requests */ +#define TI_SCI_MSG_SET_CLOCK_STATE 0x0100 +#define TI_SCI_MSG_GET_CLOCK_STATE 0x0101 +#define TI_SCI_MSG_SET_CLOCK_PARENT 0x0102 +#define TI_SCI_MSG_GET_CLOCK_PARENT 0x0103 +#define TI_SCI_MSG_GET_NUM_CLOCK_PARENTS 0x0104 +#define TI_SCI_MSG_SET_CLOCK_FREQ 0x010c +#define TI_SCI_MSG_QUERY_CLOCK_FREQ 0x010d +#define TI_SCI_MSG_GET_CLOCK_FREQ 0x010e + +/* Processor Control Messages */ +#define TISCI_MSG_PROC_REQUEST 0xc000 +#define TISCI_MSG_PROC_RELEASE 0xc001 +#define TISCI_MSG_PROC_HANDOVER 0xc005 +#define TISCI_MSG_SET_PROC_BOOT_CONFIG 0xc100 +#define TISCI_MSG_SET_PROC_BOOT_CTRL 0xc101 +#define TISCI_MSG_PROC_AUTH_BOOT_IMIAGE 0xc120 +#define TISCI_MSG_GET_PROC_BOOT_STATUS 0xc400 + +/** + * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses + * @type: Type of messages: One of TI_SCI_MSG* values + * @host: Host of the message + * @seq: Message identifier indicating a transfer sequence + * @flags: Flag for the message + */ +struct ti_sci_msg_hdr { + uint16_t type; + uint8_t host; + uint8_t seq; +#define TI_SCI_MSG_FLAG(val) (1 << (val)) +#define TI_SCI_FLAG_REQ_GENERIC_NORESPONSE 0x0 +#define TI_SCI_FLAG_REQ_ACK_ON_RECEIVED TI_SCI_MSG_FLAG(0) +#define TI_SCI_FLAG_REQ_ACK_ON_PROCESSED TI_SCI_MSG_FLAG(1) +#define TI_SCI_FLAG_RESP_GENERIC_NACK 0x0 +#define TI_SCI_FLAG_RESP_GENERIC_ACK TI_SCI_MSG_FLAG(1) + /* Additional Flags */ + uint32_t flags; +} __packed; + +/** + * struct ti_sci_msg_resp_version - Response for a message + * @hdr: Generic header + * @firmware_description: String describing the firmware + * @firmware_revision: Firmware revision + * @abi_major: Major version of the ABI that firmware supports + * @abi_minor: Minor version of the ABI that firmware supports + * + * In general, ABI version changes follow the rule that minor version increments + * are backward compatible. Major revision changes in ABI may not be + * backward compatible. + * + * Response to a generic message with message type TI_SCI_MSG_VERSION + */ +struct ti_sci_msg_resp_version { + struct ti_sci_msg_hdr hdr; +#define FIRMWARE_DESCRIPTION_LENGTH 32 + char firmware_description[FIRMWARE_DESCRIPTION_LENGTH]; + uint16_t firmware_revision; + uint8_t abi_major; + uint8_t abi_minor; +} __packed; + +/** + * struct ti_sci_msg_req_reboot - Reboot the SoC + * @hdr: Generic Header + * + * Request type is TI_SCI_MSG_SYS_RESET, responded with a generic + * ACK/NACK message. + */ +struct ti_sci_msg_req_reboot { + struct ti_sci_msg_hdr hdr; +} __packed; + +/** + * struct ti_sci_msg_req_set_device_state - Set the desired state of the device + * @hdr: Generic header + * @id: Indicates which device to modify + * @reserved: Reserved space in message, must be 0 for backward compatibility + * @state: The desired state of the device. + * + * Certain flags can also be set to alter the device state: + * + MSG_FLAG_DEVICE_WAKE_ENABLED - Configure the device to be a wake source. + * The meaning of this flag will vary slightly from device to device and from + * SoC to SoC but it generally allows the device to wake the SoC out of deep + * suspend states. + * + MSG_FLAG_DEVICE_RESET_ISO - Enable reset isolation for this device. + * + MSG_FLAG_DEVICE_EXCLUSIVE - Claim this device exclusively. When passed + * with STATE_RETENTION or STATE_ON, it will claim the device exclusively. + * If another host already has this device set to STATE_RETENTION or STATE_ON, + * the message will fail. Once successful, other hosts attempting to set + * STATE_RETENTION or STATE_ON will fail. + * + * Request type is TI_SCI_MSG_SET_DEVICE_STATE, responded with a generic + * ACK/NACK message. + */ +struct ti_sci_msg_req_set_device_state { + /* Additional hdr->flags options */ +#define MSG_FLAG_DEVICE_WAKE_ENABLED TI_SCI_MSG_FLAG(8) +#define MSG_FLAG_DEVICE_RESET_ISO TI_SCI_MSG_FLAG(9) +#define MSG_FLAG_DEVICE_EXCLUSIVE TI_SCI_MSG_FLAG(10) + struct ti_sci_msg_hdr hdr; + uint32_t id; + uint32_t reserved; + +#define MSG_DEVICE_SW_STATE_AUTO_OFF 0 +#define MSG_DEVICE_SW_STATE_RETENTION 1 +#define MSG_DEVICE_SW_STATE_ON 2 + uint8_t state; +} __packed; + +/** + * struct ti_sci_msg_req_get_device_state - Request to get device. + * @hdr: Generic header + * @id: Device Identifier + * + * Request type is TI_SCI_MSG_GET_DEVICE_STATE, responded device state + * information + */ +struct ti_sci_msg_req_get_device_state { + struct ti_sci_msg_hdr hdr; + uint32_t id; +} __packed; + +/** + * struct ti_sci_msg_resp_get_device_state - Response to get device request. + * @hdr: Generic header + * @context_loss_count: Indicates how many times the device has lost context. A + * driver can use this monotonic counter to determine if the device has + * lost context since the last time this message was exchanged. + * @resets: Programmed state of the reset lines. + * @programmed_state: The state as programmed by set_device. + * - Uses the MSG_DEVICE_SW_* macros + * @current_state: The actual state of the hardware. + * + * Response to request TI_SCI_MSG_GET_DEVICE_STATE. + */ +struct ti_sci_msg_resp_get_device_state { + struct ti_sci_msg_hdr hdr; + uint32_t context_loss_count; + uint32_t resets; + uint8_t programmed_state; +#define MSG_DEVICE_HW_STATE_OFF 0 +#define MSG_DEVICE_HW_STATE_ON 1 +#define MSG_DEVICE_HW_STATE_TRANS 2 + uint8_t current_state; +} __packed; + +/** + * struct ti_sci_msg_req_set_device_resets - Set the desired resets + * configuration of the device + * @hdr: Generic header + * @id: Indicates which device to modify + * @resets: A bit field of resets for the device. The meaning, behavior, + * and usage of the reset flags are device specific. 0 for a bit + * indicates releasing the reset represented by that bit while 1 + * indicates keeping it held. + * + * Request type is TI_SCI_MSG_SET_DEVICE_RESETS, responded with a generic + * ACK/NACK message. + */ +struct ti_sci_msg_req_set_device_resets { + struct ti_sci_msg_hdr hdr; + uint32_t id; + uint32_t resets; +} __packed; + +/** + * struct ti_sci_msg_req_set_clock_state - Request to setup a Clock state + * @hdr: Generic Header, Certain flags can be set specific to the clocks: + * MSG_FLAG_CLOCK_ALLOW_SSC: Allow this clock to be modified + * via spread spectrum clocking. + * MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE: Allow this clock's + * frequency to be changed while it is running so long as it + * is within the min/max limits. + * MSG_FLAG_CLOCK_INPUT_TERM: Enable input termination, this + * is only applicable to clock inputs on the SoC pseudo-device. + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to modify. + * @request_state: Request the state for the clock to be set to. + * MSG_CLOCK_SW_STATE_UNREQ: The IP does not require this clock, + * it can be disabled, regardless of the state of the device + * MSG_CLOCK_SW_STATE_AUTO: Allow the System Controller to + * automatically manage the state of this clock. If the device + * is enabled, then the clock is enabled. If the device is set + * to off or retention, then the clock is internally set as not + * being required by the device.(default) + * MSG_CLOCK_SW_STATE_REQ: Configure the clock to be enabled, + * regardless of the state of the device. + * + * Normally, all required clocks are managed by TISCI entity, this is used + * only for specific control *IF* required. Auto managed state is + * MSG_CLOCK_SW_STATE_AUTO, in other states, TISCI entity assume remote + * will explicitly control. + * + * Request type is TI_SCI_MSG_SET_CLOCK_STATE, response is a generic + * ACK or NACK message. + */ +struct ti_sci_msg_req_set_clock_state { + /* Additional hdr->flags options */ +#define MSG_FLAG_CLOCK_ALLOW_SSC TI_SCI_MSG_FLAG(8) +#define MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE TI_SCI_MSG_FLAG(9) +#define MSG_FLAG_CLOCK_INPUT_TERM TI_SCI_MSG_FLAG(10) + struct ti_sci_msg_hdr hdr; + uint32_t dev_id; + uint8_t clk_id; +#define MSG_CLOCK_SW_STATE_UNREQ 0 +#define MSG_CLOCK_SW_STATE_AUTO 1 +#define MSG_CLOCK_SW_STATE_REQ 2 + uint8_t request_state; +} __packed; + +/** + * struct ti_sci_msg_req_get_clock_state - Request for clock state + * @hdr: Generic Header + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to get state of. + * + * Request type is TI_SCI_MSG_GET_CLOCK_STATE, response is state + * of the clock + */ +struct ti_sci_msg_req_get_clock_state { + struct ti_sci_msg_hdr hdr; + uint32_t dev_id; + uint8_t clk_id; +} __packed; + +/** + * struct ti_sci_msg_resp_get_clock_state - Response to get clock state + * @hdr: Generic Header + * @programmed_state: Any programmed state of the clock. This is one of + * MSG_CLOCK_SW_STATE* values. + * @current_state: Current state of the clock. This is one of: + * MSG_CLOCK_HW_STATE_NOT_READY: Clock is not ready + * MSG_CLOCK_HW_STATE_READY: Clock is ready + * + * Response to TI_SCI_MSG_GET_CLOCK_STATE. + */ +struct ti_sci_msg_resp_get_clock_state { + struct ti_sci_msg_hdr hdr; + uint8_t programmed_state; +#define MSG_CLOCK_HW_STATE_NOT_READY 0 +#define MSG_CLOCK_HW_STATE_READY 1 + uint8_t current_state; +} __packed; + +/** + * struct ti_sci_msg_req_set_clock_parent - Set the clock parent + * @hdr: Generic Header + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to modify. + * @parent_id: The new clock parent is selectable by an index via this + * parameter. + * + * Request type is TI_SCI_MSG_SET_CLOCK_PARENT, response is generic + * ACK / NACK message. + */ +struct ti_sci_msg_req_set_clock_parent { + struct ti_sci_msg_hdr hdr; + uint32_t dev_id; + uint8_t clk_id; + uint8_t parent_id; +} __packed; + +/** + * struct ti_sci_msg_req_get_clock_parent - Get the clock parent + * @hdr: Generic Header + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * Each device has it's own set of clock inputs. This indexes + * which clock input to get the parent for. + * + * Request type is TI_SCI_MSG_GET_CLOCK_PARENT, response is parent information + */ +struct ti_sci_msg_req_get_clock_parent { + struct ti_sci_msg_hdr hdr; + uint32_t dev_id; + uint8_t clk_id; +} __packed; + +/** + * struct ti_sci_msg_resp_get_clock_parent - Response with clock parent + * @hdr: Generic Header + * @parent_id: The current clock parent + * + * Response to TI_SCI_MSG_GET_CLOCK_PARENT. + */ +struct ti_sci_msg_resp_get_clock_parent { + struct ti_sci_msg_hdr hdr; + uint8_t parent_id; +} __packed; + +/** + * struct ti_sci_msg_req_get_clock_num_parents - Request to get clock parents + * @hdr: Generic header + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * + * This request provides information about how many clock parent options + * are available for a given clock to a device. This is typically used + * for input clocks. + * + * Request type is TI_SCI_MSG_GET_NUM_CLOCK_PARENTS, response is appropriate + * message, or NACK in case of inability to satisfy request. + */ +struct ti_sci_msg_req_get_clock_num_parents { + struct ti_sci_msg_hdr hdr; + uint32_t dev_id; + uint8_t clk_id; +} __packed; + +/** + * struct ti_sci_msg_resp_get_clock_num_parents - Response for get clk parents + * @hdr: Generic header + * @num_parents: Number of clock parents + * + * Response to TI_SCI_MSG_GET_NUM_CLOCK_PARENTS + */ +struct ti_sci_msg_resp_get_clock_num_parents { + struct ti_sci_msg_hdr hdr; + uint8_t num_parents; +} __packed; + +/** + * struct ti_sci_msg_req_query_clock_freq - Request to query a frequency + * @hdr: Generic Header + * @dev_id: Device identifier this request is for + * @min_freq_hz: The minimum allowable frequency in Hz. This is the minimum + * allowable programmed frequency and does not account for clock + * tolerances and jitter. + * @target_freq_hz: The target clock frequency. A frequency will be found + * as close to this target frequency as possible. + * @max_freq_hz: The maximum allowable frequency in Hz. This is the maximum + * allowable programmed frequency and does not account for clock + * tolerances and jitter. + * @clk_id: Clock identifier for the device for this request. + * + * NOTE: Normally clock frequency management is automatically done by TISCI + * entity. In case of specific requests, TISCI evaluates capability to achieve + * requested frequency within provided range and responds with + * result message. + * + * Request type is TI_SCI_MSG_QUERY_CLOCK_FREQ, response is appropriate message, + * or NACK in case of inability to satisfy request. + */ +struct ti_sci_msg_req_query_clock_freq { + struct ti_sci_msg_hdr hdr; + uint32_t dev_id; + uint64_t min_freq_hz; + uint64_t target_freq_hz; + uint64_t max_freq_hz; + uint8_t clk_id; +} __packed; + +/** + * struct ti_sci_msg_resp_query_clock_freq - Response to a clock frequency query + * @hdr: Generic Header + * @freq_hz: Frequency that is the best match in Hz. + * + * Response to request type TI_SCI_MSG_QUERY_CLOCK_FREQ. NOTE: if the request + * cannot be satisfied, the message will be of type NACK. + */ +struct ti_sci_msg_resp_query_clock_freq { + struct ti_sci_msg_hdr hdr; + uint64_t freq_hz; +} __packed; + +/** + * struct ti_sci_msg_req_set_clock_freq - Request to setup a clock frequency + * @hdr: Generic Header + * @dev_id: Device identifier this request is for + * @min_freq_hz: The minimum allowable frequency in Hz. This is the minimum + * allowable programmed frequency and does not account for clock + * tolerances and jitter. + * @target_freq_hz: The target clock frequency. The clock will be programmed + * at a rate as close to this target frequency as possible. + * @max_freq_hz: The maximum allowable frequency in Hz. This is the maximum + * allowable programmed frequency and does not account for clock + * tolerances and jitter. + * @clk_id: Clock identifier for the device for this request. + * + * NOTE: Normally clock frequency management is automatically done by TISCI + * entity. In case of specific requests, TISCI evaluates capability to achieve + * requested range and responds with success/failure message. + * + * This sets the desired frequency for a clock within an allowable + * range. This message will fail on an enabled clock unless + * MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE is set for the clock. Additionally, + * if other clocks have their frequency modified due to this message, + * they also must have the MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE or be disabled. + * + * Calling set frequency on a clock input to the SoC pseudo-device will + * inform the PMMC of that clock's frequency. Setting a frequency of + * zero will indicate the clock is disabled. + * + * Calling set frequency on clock outputs from the SoC pseudo-device will + * function similarly to setting the clock frequency on a device. + * + * Request type is TI_SCI_MSG_SET_CLOCK_FREQ, response is a generic ACK/NACK + * message. + */ +struct ti_sci_msg_req_set_clock_freq { + struct ti_sci_msg_hdr hdr; + uint32_t dev_id; + uint64_t min_freq_hz; + uint64_t target_freq_hz; + uint64_t max_freq_hz; + uint8_t clk_id; +} __packed; + +/** + * struct ti_sci_msg_req_get_clock_freq - Request to get the clock frequency + * @hdr: Generic Header + * @dev_id: Device identifier this request is for + * @clk_id: Clock identifier for the device for this request. + * + * NOTE: Normally clock frequency management is automatically done by TISCI + * entity. In some cases, clock frequencies are configured by host. + * + * Request type is TI_SCI_MSG_GET_CLOCK_FREQ, responded with clock frequency + * that the clock is currently at. + */ +struct ti_sci_msg_req_get_clock_freq { + struct ti_sci_msg_hdr hdr; + uint32_t dev_id; + uint8_t clk_id; +} __packed; + +/** + * struct ti_sci_msg_resp_get_clock_freq - Response of clock frequency request + * @hdr: Generic Header + * @freq_hz: Frequency that the clock is currently on, in Hz. + * + * Response to request type TI_SCI_MSG_GET_CLOCK_FREQ. + */ +struct ti_sci_msg_resp_get_clock_freq { + struct ti_sci_msg_hdr hdr; + uint64_t freq_hz; +} __packed; + +#define TISCI_ADDR_LOW_MASK 0x00000000ffffffff +#define TISCI_ADDR_HIGH_MASK 0xffffffff00000000 +#define TISCI_ADDR_HIGH_SHIFT 32 + +/** + * struct ti_sci_msg_req_proc_request - Request a processor + * + * @hdr: Generic Header + * @processor_id: ID of processor + * + * Request type is TISCI_MSG_PROC_REQUEST, response is a generic ACK/NACK + * message. + */ +struct ti_sci_msg_req_proc_request { + struct ti_sci_msg_hdr hdr; + uint8_t processor_id; +} __packed; + +/** + * struct ti_sci_msg_req_proc_release - Release a processor + * + * @hdr: Generic Header + * @processor_id: ID of processor + * + * Request type is TISCI_MSG_PROC_RELEASE, response is a generic ACK/NACK + * message. + */ +struct ti_sci_msg_req_proc_release { + struct ti_sci_msg_hdr hdr; + uint8_t processor_id; +} __packed; + +/** + * struct ti_sci_msg_req_proc_handover - Handover a processor to a host + * + * @hdr: Generic Header + * @processor_id: ID of processor + * @host_id: New Host we want to give control to + * + * Request type is TISCI_MSG_PROC_HANDOVER, response is a generic ACK/NACK + * message. + */ +struct ti_sci_msg_req_proc_handover { + struct ti_sci_msg_hdr hdr; + uint8_t processor_id; + uint8_t host_id; +} __packed; + +/* A53 Config Flags */ +#define PROC_BOOT_CFG_FLAG_ARMV8_DBG_EN 0x00000001 +#define PROC_BOOT_CFG_FLAG_ARMV8_DBG_NIDEN 0x00000002 +#define PROC_BOOT_CFG_FLAG_ARMV8_DBG_SPIDEN 0x00000004 +#define PROC_BOOT_CFG_FLAG_ARMV8_DBG_SPNIDEN 0x00000008 +#define PROC_BOOT_CFG_FLAG_ARMV8_AARCH32 0x00000100 + +/* R5 Config Flags */ +#define PROC_BOOT_CFG_FLAG_R5_DBG_EN 0x00000001 +#define PROC_BOOT_CFG_FLAG_R5_DBG_NIDEN 0x00000002 +#define PROC_BOOT_CFG_FLAG_R5_LOCKSTEP 0x00000100 +#define PROC_BOOT_CFG_FLAG_R5_TEINIT 0x00000200 +#define PROC_BOOT_CFG_FLAG_R5_NMFI_EN 0x00000400 +#define PROC_BOOT_CFG_FLAG_R5_TCM_RSTBASE 0x00000800 +#define PROC_BOOT_CFG_FLAG_R5_BTCM_EN 0x00001000 +#define PROC_BOOT_CFG_FLAG_R5_ATCM_EN 0x00002000 + +/** + * struct ti_sci_msg_req_set_proc_boot_config - Set Processor boot configuration + * @hdr: Generic Header + * @processor_id: ID of processor + * @bootvector_low: Lower 32bit (Little Endian) of boot vector + * @bootvector_high: Higher 32bit (Little Endian) of boot vector + * @config_flags_set: Optional Processor specific Config Flags to set. + * Setting a bit here implies required bit sets to 1. + * @config_flags_clear: Optional Processor specific Config Flags to clear. + * Setting a bit here implies required bit gets cleared. + * + * Request type is TISCI_MSG_SET_PROC_BOOT_CONFIG, response is a generic + * ACK/NACK message. + */ +struct ti_sci_msg_req_set_proc_boot_config { + struct ti_sci_msg_hdr hdr; + uint8_t processor_id; + uint32_t bootvector_low; + uint32_t bootvector_high; + uint32_t config_flags_set; + uint32_t config_flags_clear; +} __packed; + +/* R5 Control Flags */ +#define PROC_BOOT_CTRL_FLAG_R5_CORE_HALT 0x00000001 + +/** + * struct ti_sci_msg_req_set_proc_boot_ctrl - Set Processor boot control flags + * @hdr: Generic Header + * @processor_id: ID of processor + * @config_flags_set: Optional Processor specific Config Flags to set. + * Setting a bit here implies required bit sets to 1. + * @config_flags_clear: Optional Processor specific Config Flags to clear. + * Setting a bit here implies required bit gets cleared. + * + * Request type is TISCI_MSG_SET_PROC_BOOT_CTRL, response is a generic ACK/NACK + * message. + */ +struct ti_sci_msg_req_set_proc_boot_ctrl { + struct ti_sci_msg_hdr hdr; + uint8_t processor_id; + uint32_t control_flags_set; + uint32_t control_flags_clear; +} __packed; + +/** + * struct ti_sci_msg_req_proc_auth_start_image - Authenticate and start image + * @hdr: Generic Header + * @processor_id: ID of processor + * @cert_addr_low: Lower 32bit (Little Endian) of certificate + * @cert_addr_high: Higher 32bit (Little Endian) of certificate + * + * Request type is TISCI_MSG_PROC_AUTH_BOOT_IMAGE, response is a generic + * ACK/NACK message. + */ +struct ti_sci_msg_req_proc_auth_boot_image { + struct ti_sci_msg_hdr hdr; + uint8_t processor_id; + uint32_t cert_addr_low; + uint32_t cert_addr_high; +} __packed; + +/** + * struct ti_sci_msg_req_get_proc_boot_status - Get processor boot status + * @hdr: Generic Header + * @processor_id: ID of processor + * + * Request type is TISCI_MSG_GET_PROC_BOOT_STATUS, response is appropriate + * message, or NACK in case of inability to satisfy request. + */ +struct ti_sci_msg_req_get_proc_boot_status { + struct ti_sci_msg_hdr hdr; + uint8_t processor_id; +} __packed; + +/* ARMv8 Status Flags */ +#define PROC_BOOT_STATUS_FLAG_ARMV8_WFE 0x00000001 +#define PROC_BOOT_STATUS_FLAG_ARMV8_WFI 0x00000002 + +/* R5 Status Flags */ +#define PROC_BOOT_STATUS_FLAG_R5_WFE 0x00000001 +#define PROC_BOOT_STATUS_FLAG_R5_WFI 0x00000002 +#define PROC_BOOT_STATUS_FLAG_R5_CLK_GATED 0x00000004 +#define PROC_BOOT_STATUS_FLAG_R5_LOCKSTEP_PERMITTED 0x00000100 + +/** + * \brief Processor Status Response + * struct ti_sci_msg_resp_get_proc_boot_status - Processor boot status response + * @hdr: Generic Header + * @processor_id: ID of processor + * @bootvector_low: Lower 32bit (Little Endian) of boot vector + * @bootvector_high: Higher 32bit (Little Endian) of boot vector + * @config_flags: Optional Processor specific Config Flags set. + * @control_flags: Optional Processor specific Control Flags. + * @status_flags: Optional Processor specific Status Flags set. + * + * Response to TISCI_MSG_GET_PROC_BOOT_STATUS. + */ +struct ti_sci_msg_resp_get_proc_boot_status { + struct ti_sci_msg_hdr hdr; + uint8_t processor_id; + uint32_t bootvector_low; + uint32_t bootvector_high; + uint32_t config_flags; + uint32_t control_flags; + uint32_t status_flags; +} __packed; + +#endif /* __TI_SCI_PROTOCOL_H */ diff --git a/plat/ti/k3/common/k3_bl31_setup.c b/plat/ti/k3/common/k3_bl31_setup.c index 3de57a7c..2d4d1c27 100644 --- a/plat/ti/k3/common/k3_bl31_setup.c +++ b/plat/ti/k3/common/k3_bl31_setup.c @@ -14,6 +14,7 @@ #include <platform_def.h> #include <k3_gicv3.h> #include <string.h> +#include <ti_sci.h> /* Table of regions to map using the MMU */ const mmap_region_t plat_arm_mmap[] = { @@ -21,6 +22,9 @@ const mmap_region_t plat_arm_mmap[] = { MAP_REGION_FLAT(K3_USART_BASE_ADDRESS, K3_USART_SIZE, MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(K3_GICD_BASE, K3_GICD_SIZE, MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(K3_GICR_BASE, K3_GICR_SIZE, MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(SEC_PROXY_RT_BASE, SEC_PROXY_RT_SIZE, MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(SEC_PROXY_SCFG_BASE, SEC_PROXY_SCFG_SIZE, MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(SEC_PROXY_DATA_BASE, SEC_PROXY_DATA_SIZE, MT_DEVICE | MT_RW | MT_SECURE), { /* sentinel */ } }; @@ -118,6 +122,8 @@ void bl31_platform_setup(void) { k3_gic_driver_init(K3_GICD_BASE, K3_GICR_BASE); k3_gic_init(); + + ti_sci_init(); } void platform_mem_init(void) diff --git a/plat/ti/k3/common/k3_psci.c b/plat/ti/k3/common/k3_psci.c index 4d6428b5..4c501f57 100644 --- a/plat/ti/k3/common/k3_psci.c +++ b/plat/ti/k3/common/k3_psci.c @@ -9,8 +9,11 @@ #include <debug.h> #include <k3_gicv3.h> #include <psci.h> +#include <platform.h> #include <stdbool.h> +#include <ti_sci.h> + #define STUB() ERROR("stub %s called\n", __func__) uintptr_t k3_sec_entrypoint; @@ -33,9 +36,40 @@ static void k3_cpu_standby(plat_local_state_t cpu_state) static int k3_pwr_domain_on(u_register_t mpidr) { - sev(); - - /* TODO: Indicate to System firmware about powering up */ + int core_id, proc, device, ret; + + core_id = plat_core_pos_by_mpidr(mpidr); + if (core_id < 0) { + ERROR("Could not get target core id: %d\n", core_id); + return PSCI_E_INTERN_FAIL; + } + + proc = PLAT_PROC_START_ID + core_id; + device = PLAT_PROC_DEVICE_START_ID + core_id; + + ret = ti_sci_proc_request(proc); + if (ret) { + ERROR("Request for processor failed: %d\n", ret); + return PSCI_E_INTERN_FAIL; + } + + ret = ti_sci_proc_set_boot_cfg(proc, k3_sec_entrypoint, 0, 0); + if (ret) { + ERROR("Request to set core boot address failed: %d\n", ret); + return PSCI_E_INTERN_FAIL; + } + + ret = ti_sci_device_get(device); + if (ret) { + ERROR("Request to start core failed: %d\n", ret); + return PSCI_E_INTERN_FAIL; + } + + ret = ti_sci_proc_release(proc); + if (ret) { + /* this is not fatal */ + WARN("Could not release processor control: %d\n", ret); + } return PSCI_E_SUCCESS; } @@ -58,8 +92,8 @@ void k3_pwr_domain_on_finish(const psci_power_state_t *target_state) static void __dead2 k3_system_reset(void) { - /* TODO: Indicate to System firmware about system reset */ - STUB(); + /* Send the system reset request to system firmware */ + ti_sci_core_reboot(); while (true) wfi(); diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk index 7cb6eb78..446d8afb 100644 --- a/plat/ti/k3/common/plat_common.mk +++ b/plat/ti/k3/common/plat_common.mk @@ -36,6 +36,8 @@ PLAT_INCLUDES += \ -I${PLAT_PATH}/include \ -Iinclude/plat/arm/common/ \ -Iinclude/plat/arm/common/aarch64/ \ + -I${PLAT_PATH}/common/drivers/sec_proxy \ + -I${PLAT_PATH}/common/drivers/ti_sci \ K3_CONSOLE_SOURCES += \ drivers/console/aarch64/console.S \ @@ -53,6 +55,12 @@ K3_PSCI_SOURCES += \ plat/common/plat_psci_common.c \ ${PLAT_PATH}/common/k3_psci.c \ +K3_SEC_PROXY_SOURCES += \ + ${PLAT_PATH}/common/drivers/sec_proxy/sec_proxy.c \ + +K3_TI_SCI_SOURCES += \ + ${PLAT_PATH}/common/drivers/ti_sci/ti_sci.c \ + PLAT_BL_COMMON_SOURCES += \ plat/arm/common/arm_common.c \ lib/cpus/aarch64/cortex_a53.S \ @@ -65,3 +73,5 @@ BL31_SOURCES += \ ${PLAT_PATH}/common/k3_topology.c \ ${K3_GIC_SOURCES} \ ${K3_PSCI_SOURCES} \ + ${K3_SEC_PROXY_SOURCES} \ + ${K3_TI_SCI_SOURCES} \ diff --git a/plat/ti/k3/include/platform_def.h b/plat/ti/k3/include/platform_def.h index ebc9c477..ab0739e9 100644 --- a/plat/ti/k3/include/platform_def.h +++ b/plat/ti/k3/include/platform_def.h @@ -106,7 +106,7 @@ * runtime memory used, choose the smallest value needed to register the * required regions for each BL stage. */ -#define MAX_MMAP_REGIONS 8 +#define MAX_MMAP_REGIONS 11 /* * Defines the total size of the address space in bytes. For example, for a 32 @@ -193,4 +193,17 @@ #define K3_GICR_BASE 0x01880000 #define K3_GICR_SIZE 0x100000 +#define SEC_PROXY_DATA_BASE 0x32C00000 +#define SEC_PROXY_DATA_SIZE 0x80000 +#define SEC_PROXY_SCFG_BASE 0x32800000 +#define SEC_PROXY_SCFG_SIZE 0x80000 +#define SEC_PROXY_RT_BASE 0x32400000 +#define SEC_PROXY_RT_SIZE 0x80000 + +#define SEC_PROXY_TIMEOUT_US 1000000 +#define SEC_PROXY_MAX_MESSAGE_SIZE 56 + +#define TI_SCI_HOST_ID 10 +#define TI_SCI_MAX_MESSAGE_SIZE 52 + #endif /* __PLATFORM_DEF_H__ */ |